はじめに
こんにちは!今年新卒入社しました、エンジニアのタナカです。
早速ですが、ここ最近リモートワークが推奨されている中、「Discord(ディスコード)」というツールを導入した、もしくは導入してはいないけれども単語は聞いたことがあるという方が増えているのではないでしょうか。
このツールは過去に 「ゲーマー向けチャットツール」 とよく言われてましたが、2020年7月にブランディングイメージが 「あらゆるコミュニティが使えるコミュニケーションツール」 に変更され、ゲームだけに留まらないツールとなりそうです。
音声も結構クリーンな感じなのもまたいいところですよね👍
さて、この「Discord」というツールなのですが…実はこれ、チャットや会話をするだけではなく、botだって作れるんです。
私も実際にbotを作ってみましたが、とても楽しく作れます!
「プログラミング一通り学んだけど次何したら良いか分かんない…」という方にもきっとオススメできます。
なので今回は、TypeScriptでのDiscord botの作り方(コード部分)について書いていきたいと思います!
※本記事は9/18(金)に協賛枠で参加したWebナイト宮崎 Vol.10 ~てげTypeScriptを学びたい~にて Tunakan という名義で発表した内容から一部を抜粋し、ブログ用に編集したものになります。
Discord bot 作ってみよう!
準備
事前に必要なものは以下になります。
…え?これだけ?
そうです。これだけで作れちゃいます!
24時間フル稼働させるような規模のものでなければ、たったの3つで出来ます!
ちなみに今回JavaScriptではなくTypeScriptを使う理由としては、くらしのマーケットで使われている言語の1つなので使い慣れているという点があります。
そして以下が作成したサーバーにbotを追加した状態になります。
右側に 「Tunakan bot」 というのがオフラインで存在してますね。こちらが今回準備したbotになります。
…おや?何やらDiscord画面の下の方に面白い言葉が書いてありますね?
「ご挨拶しな!」と半ば強引に挨拶を求められてますね…😅
ただこの状態だと(作成してすぐなので当然ですが)何も返してくれません。シカトされちゃいます。悲しいですね…
なので、まずは簡単に挨拶出来る機能を追加しちゃいましょう!💪
botが挨拶出来るようにしよう!
最初に、discord.js
というNode.jsモジュールをインストールします。MacやLinux系ならターミナル、Windowsならコマンドプロンプト、その他お好きなコマンドラインツールがあればそちらを開き以下を実行しましょう!
npm install discord.js
次にテキストエディタを開いて以下のコードをサクッと書いて保存してください。
// ./bot.ts import { Client, Message } from "discord.js"; import { config } from "./config"; const client = new Client(); interface ReplyInterface { messageReply(message: Message): Promise<void>; } class Reply implements ReplyInterface { public async messageReply(message: Message): Promise<void> { if (message.author.bot) { return; } else if (message.content === "こんにちは") { message.reply("こんにちは!"); } } } const reply = new Reply(); client.on("message", (message) => reply.messageReply(message)); client.login(config.token);
// ./config.ts export const config = { token: "{token}", // Developer Portalからtokenをコピペする };
ファイル構成は以下のようになるはずです。
このサクッと書いたコードですが、以下の流れになります
client.login
でbotがオンライン状態になる- 何かしらのメッセージが送信されたら
reply.messageReply(message)
を実行 if (message.author.bot) { return; }
で、メッセージがbotからならreturn- bot以外で"こんにちは"というメッセージが送信されたら"こんにちは!"と発言者に対してリプライをする
bot作るなら結構複雑なコード書かなきゃいけないんじゃ…?と思われそうですが(実際私もそう思っていました)、単純なものならこの通りたった数行で作れます!👍
では実際に動かしてみましょう!以下をコマンドラインツールで実行してみてください!
tsc bot.ts node bot.js
うまく行けばこの通り、Tunakan botがオンライン状態になり、挨拶をしてくれます!
挨拶だけじゃ物足りない!もっと凝ったものを作る
さて、挨拶するだけじゃかなり物足りないですよね?
せっかく簡単に作れるんだから、何かもうちょっと凝ったものを作りたい…少し手軽にbotらしく動作させたい…うーん…
そうだ、じゃんけんゲームを作ろう!
というわけでじゃんけんのコードをサクッと書いちゃいましょう。
import { Collection } from "@discordjs/collection"; import { Client, Message } from "discord.js"; import { config } from "./config"; const client = new Client(); enum hands { "グー", "チョキ", "パー", } interface ReplyInterface { messageReply(message: Message): Promise<void>; } interface GameInterface { playRockPaperScissorsGame(message: Message): Promise<void>; } class Reply implements ReplyInterface { private game = new Game(); public async messageReply(message: Message): Promise<void> { if (message.content === "じゃんけん") { await this.game.playRockPaperScissorsGame(message); } } } class Game implements GameInterface { public async playRockPaperScissorsGame(message: Message): Promise<void> { await message.reply("最初はグー!じゃんけん…!"); const filter = (player) => { return ["グー", "チョキ", "パー"].includes(player.content); }; let player: Collection<string, Message>; try { player = await message.channel.awaitMessages(filter, { max: 1, time: 10000, errors: ["time"] }); } catch { message.reply("タイムオーバー!あなたの負けです"); return; } if (!player) { // playerがundefinedならログアウトしてエラーを出す client.destroy(); throw new Error("player is undefined"); } // botの手を決める const botHand = Math.floor(Math.random() * 3); await message.reply(hands[botHand]); // 判定を行う const judge: number = (hands[player.first().content] - botHand + 3) % 3; switch (judge) { case 0: await message.reply("あいこ"); break; case 1: await message.reply("あなたの負け"); break; case 2: await message.reply("あなたの勝ち"); break; default: await message.reply("Error!"); break; } } } const reply = new Reply(); client.on("message", (message) => reply.messageReply(message)); client.login(config.token);
処理の流れは以下の通りです。サクッと作成したものなので、あいこでも再度勝負をしない一発勝負という点にご注意ください。
- ユーザーが「じゃんけん」とメッセージを送ると
playRockPaperScissorsGame()
を実行 - 「最初はグー!じゃんけん…!」とreplyし、ユーザーからのメッセージを
awaitMessages
で待つ - filterで設定した文字列「グー」「チョキ」「パー」のメッセージが送信された時、bot側の手をランダムで決め、botの手をreplyする
- 計算してじゃんけんの判定を行い、それぞれの結果をreplyする
また、じゃんけんの判定ロジックは以下になります
- グー(0) チョキ(1) パー(2)とする
( {プレイヤーの手} - {botの手} + 3 ) % 3
をする- 計算結果が0ならあいこ、1なら負け、2なら勝ちになる
コードが書けたらbotを起動してみましょう!tsc bot.ts
でコンパイルも忘れずに!
さいごに
Discordのbotは気軽に作れて、プログラミングの勉強にもなると思います!
Discordを使っている、サーバー持ってたりしててもうちょっといい感じにしたい!楽に運用したい!って時や、TypeScriptを勉強したい…!って時に作ってみるのもいいかもしれませんね👍