Discord.jsのBotでみまもり君を作る&絵文字を送る
動機とか
新型コロナウイルスのおかげて友人とdiscordで通話しながら作業する機会が増えたので、誰かが通話し始めたら通知が行くと嬉しいな。みたいな感じで作りはじめた。
と言ってもそんなに真面目な目的ではなく、まあdicordのapiとか触ってみたいと思っていたし〜みたいなかるーいノリ
pythonかjsが主流(C#とかもあるらしい)ぽいので、とりあえずjsで書いてみた。
あと、そのサーバでカスタム絵文字で遊ぶ文化があるので、絵文字も送ろうと思ったがちょっと一手間必要で調べてもイマイチぴんと来る資料が見つからなかったので、合わせてまとめて書いた
内輪向けのコードがほぼそのまま乗っているので、一部の人にしか通じないネタがあるが理解できなくてもbotは作れるのでご安心を。気づいたら適当にツイートでもしてくだされ。
前提環境
ssh クライアント
サーバー
環境構築
サーバの設定
npmとか色々入れる
sudo apt-get update sudo apt-get upgrade sudo apt-get install -y nodejs npm sudo npm cache clean sudo npm install n -g sudo n stable sudo ln -sf /usr/local/bin/node /usr/bin/node
serverの適当なところにフォルダを用意し、Erisを入れる
mkdir discordBot cd discordBot mkdir watchingBot sudo npm install eris
discordの設定
サーバーの作成を先にしておいてください
ここにアクセス
左上のNew Applicationを押してBotを作成
NAMEやアイコンを適当に決め、OAuthのタブに移動
BOTにチェックを入れ、下のAdministratorにチェック
Adminにしなくてもいい場合もあるが、後から直すのも面倒なのでこのままで
この状態でhttps://discordapp.com/api/oauth2/authorize?client_id=〜の形で表示されているurlをコピーし、開くとサーバに追加する画面が表示される
作成した任意のサーバを選択し、認証
Botのタブに移動し、TOKENをコピーのボタンを押してTOKENを取得
あとで使うのでタブを開けておくか、適当に貼っておくかする
このTOKENは絶対に公開してはいけません
大荒れしたこともあるらしい。なむなむ。
githubとかにこのTOKENが上がると自動でdiscordがTOKENを更新して事故(事件)を防ぐらしいけど、気をつけようね。
本編
やっていきます
Visual Studio Code(以後vscode)で新規ファイル index.jsを作成
vscodeでsshをしてコーディングをする方法があります。ググってみて
動作テスト
まずはEris公式にあるサンプルコードをコピペ
var bot = new Eris("BOT_TOKEN"); bot.on("ready", () => { console.log("Ready!"); }); bot.on("messageCreate", (msg) => { if(msg.content === "!ping") { bot.createMessage(msg.channel.id, "Pong!"); } }); bot.connect();
!pingというメッセージを送信するとPong!と返すだけのプログラム
保存したらindex.jsがあるディレクトリで
npm index.js
でBotが動きます
起動前はbotはオフライン表示になっていますが、起動するとちゃんとオンラインになってるはず
そして!pingと送るとPongと返ることも確認できます
そしたらカスタマイズして行く
abal.moe
ここの公式サイトを見れば大体のことはできる
みまもり君のコーディング
ここでは監視君(?)に必要そうな動作として
const TOKEN = "??????"; const Eris = require("eris"); //Eriisを作る var bot = new Eris(TOKEN); var guildId = '000000000000000"'; var channelId = "000000000000000"; var emojiArray={}; bot.on("ready", () => { console.log("ready"); bot.createMessage(channelId, "進捗みまもり隊が起動しました。進捗どうですか?"); emojiLoad(); }); bot.on("voiceChannelJoin", (member, newChannel) => { //入室処理 let ch = newChannel.guild.defaultChannel; var reply = member.username + "さんが チャンネル[" + newChannel.name + "] に入室しました" + emojiArray['sintyoku_dodesuka']; bot.createMessage(channelId, reply); }); bot.on("voiceChannelSwitch", (member, newChannel, oldChannel) => { //入室処理 let ch = newChannel.guild.defaultChannel; var reply = member.username + "さんが チャンネル[" + newChannel.name + "] に移動しました"; bot.createMessage(channelId, reply); }); bot.on("voiceChannelLeave", (member, oldChannel) => { // 退室処理 let ch = oldChannel.guild.defaultChannel; console.log("%s さんが チャンネル %s を退室しました。:oyasumi:", member.username, oldChannel.name); var reply = member.username + "さんが チャンネル[" + oldChannel.name + "] を退室しました。"+emojiArray['oyasumi'] bot.createMessage(channelId,reply); }); bot.on("messageCreate", (msg) => { //Botの投稿を無視する //自分自身だけでなく、他のBotも無視する if(msg.author.bot)return console.log(emojiArray['dame']); if(msg.content === emojiArray['iidesuyo']) { //iidesuyoの絵文字を受け取るとgood_poemの絵文字を返す bot.createMessage(msg.channel.id,emojiArray['good_poem']); console.log("ok"); } else if(msg.content === emojiArray['dame']) { //dameの絵文字を受け取るとdamekaの絵文字を返す bot.createMessage(msg.channel.id,emojiArray['dameka']); console.log("not ok"); } }); //Discordに接続 bot.connect(); function emojiLoad(){ //serverを特定 var guild = bot.guilds.find(guild => guild.id == guildId); console.log(guild.emojis); makeEmoji(guild,'sintyoku_dodesuka'); makeEmoji(guild,'oyasumi'); makeEmoji(guild,'iidesuyo'); makeEmoji(guild,'dame'); makeEmoji(guild,'dameka'); } //絵文字の文字列 function makeEmoji(guild,_name){ emojiArray[_name]= "<:"+_name+":"+guild.emojis.find(emoji => emoji.name == _name).id +">"; }
コードの解説
var guildId = '000000000000000"'; var channelId = "000000000000000";
もちろん000000〜はダミー
channelIdはテキストチャンネルのIdで、discordアプリ内でチャンネルを右クリックするとIDをコピーというのがある
ない場合はユーザー設定->テーマ->開発者モードをオンにすると見れる
guildIdはサーバ名を右クリックで見れる。guildとはこの場合Discordの各サーバのこと
bot.on("ready", () => { console.log("ready"); bot.createMessage(channelId, "進捗みまもり隊が起動しました。進捗どうですか?"); emojiLoad(); });
botが実行された時に一度だけ実行される
bot.createMessage(channelId, "進捗みまもり隊が起動しました。進捗どうですか?");
のように、createMessagenにチャンネルIDと発言内容を渡してやるだけで送ることができる
bot.on("voiceChannelJoin", (member, newChannel) => { //入室処理 let ch = newChannel.guild.defaultChannel; var reply = member.username + "さんが チャンネル[" + newChannel.name + "] に入室しました" + emojiArray['sintyoku_dodesuka']; bot.createMessage(channelId, reply); });
voiceChannelJoinnは誰かがvoiceチャンネルに入った時に実行されるイベントになる
voiceChannelLeaveはいなくなった時、Switchは移動した時に実行
member.usernameのから名前も取れるのでメンションも簡単につけられる
bot.on("messageCreate", (msg) => { //Botの投稿を無視する //自分自身だけでなく、他のBotも無視する if(msg.author.bot)return console.log(emojiArray['dame']); if(msg.content === emojiArray['iidesuyo']) { //iidesuyoの絵文字を受け取るとgood_poemの絵文字を返す bot.createMessage(msg.channel.id,emojiArray['good_poem']); console.log("ok"); } else if(msg.content === emojiArray['dame']) { //dameの絵文字を受け取るとdamekaの絵文字を返す bot.createMessage(msg.channel.id,emojiArray['dameka']); console.log("not ok"); } });
messageCreateは誰かがmessageを送った時に実行される
bot自身の送信を拾わないようにしている(無限ループは起こる可能性がある)
あとはそのまま。簡単だね
//Discordに接続 bot.connect();
繋ごう。
function emojiLoad(){ //serverを特定 var guild = bot.guilds.find(guild => guild.id == guildId); console.log(guild.emojis); makeEmoji(guild,'sintyoku_dodesuka'); makeEmoji(guild,'oyasumi'); makeEmoji(guild,'iidesuyo'); makeEmoji(guild,'dame'); makeEmoji(guild,'dameka'); }
bot.guilds.findでサーバ名を確かめる
makeEmojiでemojiArrayに絵文字の文字列を追加
botで絵文字を送るときは :thinking_face: のように送ってもただの文字列になってしまうので、
//絵文字の文字列 function makeEmoji(guild,_name){ emojiArray[_name]= "<:"+_name+":"+guild.emojis.find(emoji => emoji.name == _name).id +">"; }
これで <:thinking_face:123456789>
みたいにしてやる
これでサーバに追加したカスタム絵文字が使える。
nitro課金をしていないのでgifでもできるかは不明。できそうだけど
終わり
こんな感じでdiscordとjavascriptで簡単にbotが作れる
今回はサーバマシンを別に用意したが、macとかでも常駐させればいいし、glitch みたいなサービスを使ってもいい
…個人的にGASに拡張してみたい
それでは。