こんにちは!
今回は discord.js、TypeScript、そして Docker を使ってDiscordのBot開発に挑戦した体験をまとめます。
以前に discord.py を使ってBot開発をしていましたが、その頃はプログラミング初心者で、比較的簡単なPythonを選んでいました。
今回はTypeScriptやDockerにも挑戦し、学びながら開発した内容を紹介します。
1. なぜ技術を変えたのか
-
discord.py → discord.js
大学時代に作ったDiscordBotでは言語自体の導入の簡単さからPythonを使用していましたが、しばらく触っていない間に度重なるアップデートがあり、勉強を兼ねて新しく作成することにしました。前々からTypeScriptを触ってみたかったのでTypeScriptに挑戦しました。 -
TypeScript
型チェックがあるくらいのメリットしか感じていませんが最低限の書き方は理解できたような気がします。 -
Docker
業務で触る機会が少ないですが、個人開発でnode系を触ることが多いため勉強を兼ねて使用しました。気軽に環境を構築したり消したりできることが良かったです。今後サーバー運用するとなったときにクラウドにデプロイしやすいこともあります。ただ、Dockerを導入したことによるエラーなどもあるので今後も勉強を続けていきたいと思います。
2. プロジェクト構成
ディレクトリ構成です。
discord.jsのデフォルト構成やTypeScirptのデフォルト構成がわからなかったのでとりあえずコードとそれ以外で分けていました。
.
|-- Dockerfile
|-- docker-compose.yml
|-- json/
|-- logs/
|-- package-lock.json
|-- package.json
|-- src/
| |-- main.ts
| |-- commands/
| |-- events/
| |-- model/
| `-- utils/
| |-- logger.ts
| |-- data/
| |-- interaction/
| `-- tts/
|-- tmp/
`-- tsconfig.json
-
src/:TypeScriptで書いたBotのコード -
src/events:イベント系→ユーザーなどの動きによって動くプログラム -
src/commands:コマンド系→ユーザーがコマンドを打った時に動くプログラム -
src/model:モデルクラス→モデルクラスの定義を行う(完全にC#の流用) -
src/utils:ツール系→それ以外の機能やそれらをサポートする機能 -
Dockerfile:Dockerイメージの設定 -
package.json:依存関係管理 -
tsconfig.json:TypeScriptの設定
3. Bot開発の流れ
1. 主なツールの導入
TypeScriptやDocker、node.js、discord.jsのインストール
2. 簡単なBotの実装
import { Client, GatewayIntentBits } from 'discord.js';
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.once('ready', () => {
console.log(`Logged in as ${client.user?.tag}!`);
});
client.on('messageCreate', message => {
if (message.content === '!ping') {
message.reply('Pong!');
}
});
client.login(process.env.DISCORD_TOKEN);
3. Dockerでの開発
Dockerを使うと、どの環境でも同じBotを動かせます。
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
CMD ["node", "dist/index.js"]
ポイント:
- 環境変数でトークンを渡す(
.envやDocker起動時に指定) - ホストとコンテナでパスやボリュームを間違えると動かないので注意
4. つまずいたところと工夫
-
Dockerのボリュームパス
コンテナ内でTypeScriptのビルド先 (dist/) とホスト側のフォルダが干渉して動かないことがありました。
実際にコンテナ内に入りLinuxコマンドなどで確認して解決しました。 -
セレクトメニューが25件以上追加できない
Discordの仕様で、セレクトメニューは25件までしか表示できませんでした。
→ コマンドに検索機能を追加し、必要な項目だけを絞り込む形に変更。 -
ログ管理
開発中にBotの挙動を追いやすくするため、winstonでログを整備しました。
前回開発したときは機能にだけ注目していてあまりメンテナンス性は意識してなかったので今回は保守性を意識したコードを書けたと思います。 -
VoiceVoxとの連携
DockerでVoiceVoxのコンテナを立ち上げ、Botから音声生成を呼び出す仕組みも構築しました。
TTS(読み上げ機能)について前回はOpenJTalkを利用していたが、今回は少し前から流行っているVoiceVoxを導入。
Dockerを利用していたこともありすんなり導入ができた。 -
Interactionの理解
discord.jsではボタンやセレクトメニューなどの Interaction が使えます。ただしInterationの中でもいろいろ種類があるそうでした。似たようなAPIなおかげでそこら辺は前回の知識が少し流用できました。
5. 学んだこと
- TypeScriptはそんなに難しくない(今のところ)
- Dockerは技術書を読んだおかげか導入が難しいけど慣れると便利な気がしてきた
- Dockerを使っていたことでVoiceVoxが一瞬で導入できたところは感動した(Dockerイメージ神)
- スラッシュコマンドやセレクトメニュー、ボタンなどの実装がめちゃくちゃ簡単でびっくりした(discord.pyでは苦戦して諦めた記憶)
まとめ
まだ勉強中ですが、TypeScriptやDockerを触る良い機会でした。discord.pyでBot開発を始めたのは5年くらい前だけどAIの躍進もあり、かなりのスピードで実装できました。
仕事柄Dockerを触る機会があまりないですが、今後の自分の技術力向上を考えてこれからも勉強したいと思います。
今後は機能の追加を必要に応じてやっていきたいと思います。