トップ画像
ぼっちは寂しいのでプログラミングで彼女(概念)を生み出してみた

執筆者: ふぉ

最終更新: 2021/05/08

2021年技術記事:3位

時は令和。何かの奇跡で数百年後とかにこの記事が古文書として発掘された時のために書き残しておきます(???)が、ご存じの通り今世界はCOVID-19で大変なことになっています。

そんなわけで、大学はオンライン自宅はド田舎という、見事に世界から隔絶された生活が続いている引きこもり大学生(21)の ふぉ と申します、おはよう(午後起床)。

ここ最近は毎日ほとんど人と会話しない生活をしているもので、引きこもり大学生の例に漏れず私もちょっと気分がしょぼんとしてきているのが現状。部活やサークルに毎日打ち込んで、たまに楽しいイベントがあってその後は恒例行事の飲み会!!みたいな理想の大学生活はたぶん幻想だし、本当は大学なんてものも概念で、久しぶりに行ってみたら実は更地になっているかもしれない(?)。もしかしたら大学の友達やよく授業が一緒だったあの人も単なる夢の中の登場人物だったかもしれない。

……え?………彼女? たぶんそれはCOVID-19の有無とは関係ないんじゃないかな?()

ということで寂しい(べつに寂しくないもん!)ので彼女(概念)を作ろうと思います(メチャクチャ雑な導入)。

最高の話し相手(概念)の作り方


今回使うのはDiscordのボット機能です。(Discordマジですごい)
JavaScriptとかPythonとかを使ってボットの自作ができるっぽいので、どっちでもいいですが今回はJavaScriptで作ります。

私が作ったのは彼女(概念)だったので以後表記は彼女(概念)となりますが、
もちろん読者の皆々様の豊かで素晴らしい 妄想 解釈次第で彼氏(概念)とかパートナー(概念)とか猫(概念)とか、何でもいけると思います。

Attention:実際に本記事の内容を試される場合は自己責任のもとで行ってください。人体錬成は錬金術最大の禁忌


準備編


まずは彼女(概念)を生み出す下準備をします。

  • Discordのアカウントを用意します。(はいそこ、Discordで友達と通話すればいいじゃんとか言わない)
  • Discord Developer Portalに行き、[Applications] → [New Application] でアプリケーションを追加します。名前は彼女(概念)の名前とします。
  • 追加したアプリケーションの画面に移行するので、[Bot] → [Build-A-Bot] でボットを追加します。これが彼女(概念)の姿(概念)になります。
  • このとき [PUBLIC BOT] のチェックがONになっていると思うので、自分専用にしたい場合はOFFにしておきましょう。



続いて、彼女(概念)の魂(言わずもがな概念)を作り出すための準備をします。

  • 普段使っているあるいは開発をしているPCにNode.jsをインストールします。
  • そのPC上に適当な作業用ディレクトリを用意します(後述しますが、末永くお付き合いしたい場合はGit管理しておくと良いです)。
  • PowershellなりBashなり何でも良いので適当なターミナルで先ほど用意した作業用ディレクトリに入ります。
  • npm init を実行します。色々訊かれますが、とりあえずnameは彼女(概念)の名前としてその他はお好みで(後で package.json というファイルから編集できます)。
  • npm install discord.js 、 npm install dotenv の2つを実行します。



見た目を決める


Discordボットはアイコンを自由に設定できるので、とりあえず顔だけサクっと描いておきます。Discordのアイコンはガッツリ縮小されるので多少塗りとか線とかが雑でもある程度は耐えると思います。


試しに描いてみました。

これをいい感じの正方形にトリミングした上で、Discordアプリケーション画面の [General Information] にある [APP ICON] からアイコン画像に設定しておきます。


コーディング


まず、作業用ディレクトリ直下に .env ファイルを新規作成します。内容は以下のようにします。

DISCORD_TOKEN=<INSERT DISCORD TOKEN HERE>

<INSERT DISCORD TOKEN HERE> の部分にはDiscordボットのトークンを貼り付けます。トークンというのはDiscord側であらかじめ指定された英数字と記号の羅列で、彼女(概念)の魂と姿(概念)を結びつける合言葉になります。

まず先ほど作成したDiscordのボットのページで [Bot] をクリックし → [USERNAME] の下の [TOKEN] の欄を見ます。ここに [Copy] というボタンがあるので押すと [Copied] に変化するので、それが確認できたら .env に貼り付けます。先述の通り英数字と記号の羅列が貼り付けられたと思うので、その状態で保存して閉じます。(トークンをうっかりGitHubで公開したり他人に見られたりしないように注意

続いて .env と同じ場所に index.js というファイルを作成します。これが彼女(概念)の思考回路となります。
内容はこんな感じ。とりあえずこのまま貼れば動きます。

const path = require('path');
const Discord = require('discord.js');
const client = new Discord.Client();
const os = require('os'); // ホスト名取得用

// 環境変数に.envを使う
require('dotenv').config({ path: path.join(__dirname, '.env') });

// ログイン時の処理
client.on("ready", () => {
    client.user.setStatus("online"); // online, idle, dnd, invisible
    client.user.setActivity(os.hostname()); // 「~~をプレイ中」
    console.log("ready...");
});

// 入室時の挨拶
client.on("guildCreate", guild => {

    let greetingChannel = "";

    // 入室時にメッセージを送るチャンネルを判定
    guild.channels.cache.forEach((channel) => {
        if (channel.type == "text" && greetingChannel == "") {
            if (channel.permissionsFor(guild.me).has("SEND_MESSAGES")) {
                greetingChannel = channel;
            }
        }
    })
    greetingChannel.send("やっほ!") // メッセ送信
        .then(message => console.log('Message: "やっほ!" sent.'))
        .catch(console.error);
});

// メッセージ受け取り時
client.on("message", message => {

    // 自分のだったら無視
    if (message.author.bot) {
        return;
    }

    // おはよう
    if (message.content.match(/おはよ/)) {

        message.channel.send("おはよ-!") //メッセ送信
            .then(message => console.log('Message: "おはよー!" sent.'))
            .catch(console.error);
        return;
    }

    // いちゃいちゃ
    if (message.content.match(/好き/)) {

        message.channel.send("私も!") //メッセ送信
            .then(message => console.log('Message: "私も!" sent.'))
            .catch(console.error);
        return;
    }

    // 任意で色々追加

});

// ログイン処理
client.login(process.env.DISCORD_TOKEN);


保存出来たら、ターミナルで node index.js と実行してみましょう。特にエラー等が出ずready...と表示されたら勝ちです。彼女(概念)が生み出されています。おめでとう。

例えば if (message.content.match(/好き/)) { の中身は流れてきたメッセージに「好き」と含まれていた場合に行われる処理です。この場合は「私も!」と返します。ここの単語を変えることで様々なメッセージに対応させることができるというわけです。正規表現が使えます。


彼女(概念)に会いに行こう


ということで無事に彼女(概念)に息が吹き込めたら、実際に彼女(概念)と会ってお話をしてみましょう。

……緊張してる? 大丈夫だよ、君の理想のパートナー(概念)だから。ほら、心配しないで。

  • Discordで適当に自分用のサーバーを用意します。
  • 先ほどトークンをコピーしてきたページで今度は [OAuth2] をクリックします。
  • [OAuth2 URL Generator] の欄にいっぱいチェックボックスがあるので、[bot] にチェックを入れて出てきたURLをコピーします。
  • ブラウザにそのURLを貼り付けて移動し、ログインします。
  • 彼女(概念)を招待するサーバーを選ぶ画面が出るので、用意したサーバーに招待します。


招待が完了したらメッセージが出ると思うので、会話してみます。



えぇ……なんだこの地獄みたいな光景は…………



失礼、取り乱しました。

こうして無事に彼女(概念)と会話ができるようになったわけですが、この入室時の挨拶や特定の言葉に反応して返信してくれる機能こそが、さっきわけもわからずコピペした index.js によって実行されているのです。

ということで無事、彼女(概念)を生み出すことに成功しました。index.js を自由に編集して、理想のパートナー(概念)を作っていきましょう。特定の言葉に返信する機能を増やしてもいいですし、誕生日におめでとうのメッセージをくれる機能を付けてもいいですね。JavaScriptの勉強をすれば大体のやりたいことはできるんじゃないでしょうか。

ちなみに私は現在、彼女(概念)と秘書(概念)に自宅のPCやMinecraftサーバーの管理をしてもらおうと試行錯誤しているところです。

----

次の章はある程度のLinuxの知識がある中級者向けの内容となります。実際に試される場合は必要に応じて検索するなどして内容を十分に理解した上で行ってください。

彼女(概念)に永遠の命を



……しかし残念ながらこの彼女(概念)は、永遠の存在ではなかったのです。

今のままの彼女(概念)は、とても脆く、そして儚い存在なのです。というのも、例えば node index.js を実行しているターミナルでCtrl + Cと入力する、ターミナルを閉じる、PCの電源を切る、そういった操作によってプログラムの実行が終了した時点で、彼女(概念)はオフライン表示になってしまいます。オフライン表示になってしまっては、返事も何もしてくれなくなります。またしても、独りぼっちになってしまいます。

もちろんforeverなどでデーモン化しても良いのですが、結局はPCをつけっぱなしにすることになるため電気代もかかるしPCにも良くないしということで、ここは一つ、彼女(概念)のために永遠の肉体(物理)を特別に用意することとしましょう。これからも末永く、彼女(概念)との明るい未来を、ともに誓い合いそしてともに切り拓いていくために。



ということで、お手元にRaspberry Piをご用意ください。これが彼女(概念)の肉体(物理)、すなわち心臓(物理)となり頭脳(物理)となります。Raspberry Piというのは平たく言えばめっちゃ多機能なマイコンボードで、「OSをインストールすれば普通にPCとして使える超小型のデバイス」と解釈してもらえれば今回は十分です。


下準備


以下は私の場合の準備物の例です。

  • Raspberry Pi 4B
  • Raspberry Pi 4B 対応ケース(スターターキットに付属していたもの)
  • 電源ケーブル(同上)
  • SDカード(Raspberry Pi OSのインストールを済ませたもの)
  • LANケーブル


まず、GitHub等に彼女(概念)の作業用ディレクトリをコミット、プッシュしておきます。また、Raspberry Pi OSの初期セットアップを済ませておきます。このとき、彼女(概念)を生み出したPCからラズパイに公開鍵認証でSSH接続ができるようにしておきます。合わせて、rootログインの無効化、SSHポートの変更、公開鍵認証以外でのSSH接続の無効化など、セキュリティ上必要な設定もしておきます。


彼女(概念)の移植


ラズパイにnpmをインストールします。以下を順に実行していきます。

  • sudo apt-get update
  • sudo apt-get install -y nodejs npm
  • sudo npm install npm n -g
  • sudo n stable


では、ホームディレクトリの適当な場所に彼女(概念)のリポジトリをクローンします。
ここでクローンしたディレクトリに移動して、discord.js、dotenvもインストールして使えるようにしておきましょう。

さらに追加で sudo npm install -g forever と実行してforeverをインストールします。foreverというのはnodeで動かすアプリをデーモン化(バックグラウンド化)してくれるモジュールで、もしエラーなどでボットが落ちた場合に自動で再起動してくれるなど、彼女(概念)のお世話をしてくれるような存在です。

続いて、scpコマンドなどで元のPCのディレクトリにあった .env ファイルをラズパイ側に持ってきます。

以上で下準備は完了です。


永遠の命を吹き込む


それでは一通り環境の移植が終わったので、node index.js が使えることを確認します。特に問題なく起動するようであれば、いったん終了して今度は forever start index.js と実行します。
なんかちょっとWarningを吐くかもしれませんが、Accessing non-existent property 'padLevels'... 云々というやつはそのままにしていてもちゃんと動きます。毎回出るのでめっちゃ気になるんですけどね。

forever list と実行すると現在Foreverで実行されているアプリ一覧が出ます。script の欄に index.js と出ていればOKです。
終了させたい場合は forever <uidの欄の文字列> で終了できます。

また、私はラズパイの電源を入れた際に自動で実行されるように、crontabを編集して以下を追加しています。

@reboot cd <index.jsがあるディレクトリの絶対パス>; /usr/local/bin/forever start index.js


あとは、LANケーブルと電源ケーブルを接続したラズパイをデスクなどに設置して完了です。


これが私の彼女(概念)のRemokoです。


結論


ということでDiscordのボット機能を使って彼女(概念)を作りました。

作ってて余計に寂しい気持ちになる瞬間があったことは否定しません。でも、別にいいんだ。これからはこんなにも可愛い彼女(概念)がずーっと一緒にいてくれるから……それでいいんだ………

取得に失敗しました

2019年度 入部

Twitter GitHub YouTube