はじめに
当記事は筆者の忘備録であり、完全なチュートリアルではないことをご理解ください。
スレッド周りのみを見たい方はこちらを
開発環境
Node.js - 16.11.0
discord.js - 13.2.0
環境構築
Node.js 公式サイト
discord.js 公式Guide
まずは適当な場所に新規フォルダを作成し、そのフォルダ内で
npm init -y
を実行、完了したら同フォルダ内で
npm install discord.js
上記二つが完了すればひとまず開発環境は構築できました。
botの招待
discord developer portal
その1
ログイン後New Application buttonをクリックし、Appを作成してください
作成が完了したらページ左側にあるBot項目をクリックし、Add Botをクリックします。
ここでTOKENという項目と青色のボタンが現れると思うので左側のCopyをクリックしトークンを控えておいてください。
今控えたトークンは必ず他人に教えないでください。またGithub等にトークンが記載されたファイルを
上げることも控えてください。当警告を無視した結果起こりえる被害について筆者は責任を負いかねます。
その2
ページ左側のOAuth2をクリック
ここが重要で
SCOPEの中にあるbotとapplications.commandsに必ずチェックを入れてください。
後々追加することも可能ですが思わぬエラーと無駄な時間を過ごすことになります。
チェックを入れると下側にBOT PERMISSIONSという項目が出てくるので
皆様の用途に合った設定をしてください。
全てにチェックを終えたら、先ほどのSCOPEにURLが表示されていると思うのでコピーし踏んでください。
これで導入は完了!
ファイル作成
discord.js Guide(Initial files)
トークン管理ですが、ここではひとまずローカル環境での動作を目的としているので
最初に作成したフォルダのルートディレクトリにconfig.jsonファイルを作成してください。
以下中身
config.json
{
"token": "先ほど控えたトークンを張り付けてください。"
}
gitignoreも作成します。
node_modules
.env
config.json
ようやくメインファイルであるindex.jsを作成します。
以下中身
index.js
const { Client, Intents } = require('discord.js');
const { token } = require('./config.json');
const client = new Client({ intents: [Intents.FLAGS.GUILDS] });
client.once('ready', () => {
console.log('Ready!');
});
client.login(token);
作成が完了したらターミナル(コマンドプロンプト)で
node index.js
を実行してみてください。ターミナル上にReady!と表示されたらひとまず作業は完了です。
終了はCtrl + cです。
コマンド作成
ここではv13から追加されたスラッシュコマンドを作成します。
まずは以下画像を見てください。
このように/を入力するとコマンド一覧が現れますよね?botがいないサーバーで入力してもビルドインコマンドが表示されます。
これらを今から作成します。
ちなみにですが、ここでapplications.commandsにチェックを入れていない場合次の作業を行った時に
必ずエラーが発生します。だからチェックをいれる必要があったんですね!
本題ですが、まずはプロジェクトフォルダ内で
npm install @discordjs/builders @discordjs/rest discord-api-types
を行ってください。これらはスラッシュコマンドを作成するときに必須な物です。
インストールが完了したら、先ほど作成したconfig.jsonを以下のように修正します
config.json
{
"clientId": "123456789012345678",
"guildId": "876543210987654321",
"token": "your-token-goes-here"
}
clientIdとguildIdはそれぞれ
- clientId ⇒ https://discord.com/developers/applications のOAuth2タブにCLIENT IDが記載されていますのでそれを張り付けてください。
- guildId ⇒ botを参加させたサーバーのIDです。サーバーを開いて名前を右クリックするとIDをコピーと出てきますのでコピペ。
次に核となるdeploy-commands.jsを作成します。
以下中身
deploy-commands.js
const { SlashCommandBuilder } = require('@discordjs/builders');
const { REST } = require('@discordjs/rest');
const { Routes } = require('discord-api-types/v9');
const { clientId, guildId, token } = require('./config.json');
const commands = [
new SlashCommandBuilder().setName('ping').setDescription('Replies with pong!'),
new SlashCommandBuilder().setName('server').setDescription('Replies with server info!'),
new SlashCommandBuilder().setName('user').setDescription('Replies with user info!'),
]
.map(command => command.toJSON());
const rest = new REST({ version: '9' }).setToken(token);
rest.put(Routes.applicationGuildCommands(clientId, guildId), { body: commands })
.then(() => console.log('Successfully registered application commands.'))
.catch(console.error);
少しだけ解説をば
- setName ⇒ コマンド名。setName('ping')であれば/pingと入力することができるようになります。
- setDescription ⇒ コマンドの説明文です。先ほどの画像でコマンド名の下に出てきてたやつです。
オプションは他にも沢山あります。詳細はこちら
後ほど記述するスレッド周りのコマンドも他オプションを利用します。
作成出来たら
ファイルがあるディレクトリで
node deploy-commands.js
を実行してください。完了したら自身のサーバーで/を入力してみてください。コマンド一覧が出てきます。
ただ、現状はコマンドを登録できただけで機能は実装していないので次項からいよいよ実装に入ります。
コマンドに対しての機能実装
公式ガイド
ここではコマンドに対して起こる機能を実装します。index.jsを開いて以下のように編集してください。
index.js
client.once('ready', () => {
console.log('Ready!');
});
//以下追加
client.on('interactionCreate', async interaction => {
if (!interaction.isCommand()) return;
const { commandName } = interaction;
if (commandName === 'ping') {
await interaction.reply('Pong!');
} else if (commandName === 'server') {
await interaction.reply('Server info.');
} else if (commandName === 'user') {
await interaction.reply('User info.');
}
});
// ここまで
client.login(token);
一応解説
if (commandName === 'ping') {
await interaction.reply('Pong!');
// もしコマンド名が 'ping' だったら 'Pong!' を返します
詳しくは以下画像を見てください。
interactionってなんぞや?って人はここを参照してください。
返信内容に引っ張ってきたデータを入れたい場合はシングルクォーテーションで囲うのではなくバッククォートで囲って
await interaction.reply(`Server name: ${interaction.guild.name}\nTotal members: ${interaction.guild.memberCount}`);
このように記述すると
こんな感じで出せます。
ひとまず・・・
以上で簡単なbotは作成完了しました。お疲れさまでした。
コマンドが増えていくとコマンド事にファイルを分ける等の作業が必要になりますがそれらはここでは解説しません。
次項からは応用編としてタイトルにもあるようにスレッド周りの実装を行います。
元気な方は引き続き頑張りましょう。
スレッド周りの実装
はじめに
当項目はスレッド周りの実装をしてみようと思った矢先、日本語記事が全くなくとてもつらい思い(ドキュメント漁り)をしたので
こうして日本語記事として残そうと思った次第です。
ソース
index.js
else if (commandName === 'ct') {
const thread = await interaction.channel.threads.create({
name: `${interaction.options.getString('name')}`,
autoArchiveDuration: 60,
reason: 'Needed a separate thread for food',
});
interaction.reply({ content: `${thread.name}が立ちました。`, ephemeral: true });;
}
deploy-commands.js
new SlashCommandBuilder().setName('ct').setDescription('create thread').addStringOption(option => option.setName('name').setDescription('スレッド名を入力してください。'))
解説
まずはdeploy-commands.jsの方から
deploy-commands.js
.addStringOption(option => option.setName('name').setDescription('スレッド名を入力してください。'))
.addStringOptionでコマンドに対して以下の画像のようにオプションをつけることができます
ここではオプションの名前をnameとしています。
ここで入力されたhelloは後ほど使います。
続いてindex.js
index.js
if (commandName === 'ct') {
const thread = await interaction.channel.threads.create({
name: `${interaction.options.getString('name')}`,
autoArchiveDuration: 60,
reason: 'Needed a separate thread for food',
});
interaction.reply({ content: `${thread.name}が立ちました。`, ephemeral: true });;
}
await interaction.channel.threads.create
// コマンドが送信されたチャンネルにスレッドを作成します
以下channel.threads.createのオプション
name: `${interaction.options.getString('name')}`
// interaction.options.getString('ここに(option.setNameで付けた名前を入れます)')
// こうすることで先ほどオプションで入力させた'hello'がこれから立ち上がるスレッドの名前になります
autoArchiveDuration: 60,
// 何分で自動アーカイブするかの設定です
reason: 'Needed a separate thread for food',
// これよくわからないんですよね...()
interaction.reply({ content: `${thread.name}が立ちました。`, ephemeral: true });;
// この部分、実はなくてもスレッドは立ちますがこれを記述しないと以下画像のようにエラーを吐きます。
// ephemeralは初期値だとFalseですがtrueにすることでbotからのメッセージがコマンドを打った人間にしか見えなくなります。
まとめ
ここまで見てくださった皆様、お疲れ様でした。そしてご覧いただきありがとうございます。
雑な解説ではありましたがどなたかのお役に立てたなら幸いです。
私自身discord.pyを過去に使っていて最近discord.jsにやってきた身なのでまだまだ分からないことだらけですが頑張ってこれからも開発していけたらなぁと思っています。
また、そのうち本記事では紹介できなかった部分も記事に起こすつもりなのでまた良ければお願いします。
さいごに
当記事は公式のGuideをもとに個人的な解釈を含めて解説したものです。
なのでもちろん正しい完璧な記事とは言えないのでもし問題・質問等ありましたらお気軽にコメントしてください。
↧