Discord Slash Commandをつくる
Yuta Goto
Posted on July 21, 2021
DiscordのSlashコマンドを使ってみます。
https://discord.com/developers/docs/interactions/slash-commands
アプリの作成
https://discord.com/developers/applications
Developer PortalのApplicationsから新規作成します。
作成したら、OAuth2の設定ページに遷移して、OAuth2 URL Generatorの下にあるSCOPESから Bot
, applications.commands
を選択して、さらに Bot Permissions
の Send Meesages
にチェックを入れます。(必要に応じて追加でチェックを入れてください)
SCOPESにあるURLにアクセスしてBOTユーザをサーバーに招待します。
ここでBOTの下準備は完了です。
スラッシュコマンドの登録
https://discord.com/developers/docs/interactions/slash-commands#registering-a-command
公式のドキュメントにある通りスクリプトを組んで実行します。
import requests
url = "https://discord.com/api/v8/applications/<APPLICATION ID>/guilds/<GUILD ID>/commands"
json = {
"name": "blep",
"description": "Send a random adorable animal photo",
"options": [
{
"name": "animal",
"description": "The type of animal",
"type": 3,
"required": True,
"choices": [
{
"name": "Dog",
"value": "animal_dog"
},
{
"name": "Cat",
"value": "animal_cat"
},
{
"name": "Penguin",
"value": "animal_penguin"
}
]
},
{
"name": "only_smol",
"description": "Whether to show only baby animals",
"type": 5,
"required": False
}
]
}
headers = {
"Authorization": "Bot <BOT TOKEN>"
}
r = requests.post(url, headers=headers, json=json)
print(r.status_code)
特定のサーバーでのみ使用するのであれば <GUILD ID>
を指定します。
このスクリプトを実行して成功すれば201が表示されて終了します。
特定のサーバーでのみのコマンドであれば即時反映されるので、実際にDiscord上でも確認ができます。/
を入力すると候補に /blep
が表示されるはずです。
ただこのままコマンドを送信してもエラーとなり何も発生しないので、ひとまずコマンドを送信したらBOTがメッセージを送信する処理を実装します。
コマンド送信後の実装
今回、本番環境では Cloudflare Workers KV を使用します。GoogleCloudRunなどのサーバレスのものを利用しても問題ないですが、CloudRunはアクセスがあってから起動するまでに時間がかかってしまい、Discord側でタイムアウト判定になってしまう可能性があります。Cloudflare Workers KVは起動がCloudRunよりもかなり早いので正常にレスポンスできるはずです。
https://www.cloudflare.com/ja-jp/products/workers-kv/
Cloudflare Workers KVのセットアップは割愛します。https://developers.cloudflare.com/workers/ に環境構築からデプロイまでかかれています。
外部ライブラリを利用するのでWebpackも利用します。
Discordのリクエストを受け付ける
discord-interactions
を使って実装します。
https://www.npmjs.com/package/discord-interactions
このコードは何かしらコマンドのリクエストがあれば pong
を返却するだけのものになっています。
以下のコードでヘッダーがちゃんとDiscordから来たものかを判定します。Discordで Interactions Endpoint URL
を登録する際にあえて誤ったリクエストヘッダーがついたリクエストがくるので、それの判定を行います。
const valid = verifyKey(
await request.clone().arrayBuffer(),
request.headers.get('X-Signature-Ed25519'),
request.headers.get('X-Signature-Timestamp'),
discord_public_key
)
if (!valid) {
return new Response('', { status: 401 })
}
以降の処理は正しい形式でJSONを返却します。 https://discord.com/developers/docs/interactions/slash-commands#responding-to-an-interaction にもサンプルが書いています。
デプロイ
外部パッケージを使用しているのでwebpackした後のコードをデプロイします。webpackやその設定の説明は端折ります。
デプロイもcloudflareのチュートリアルにある通りにコマンド一発で完了します。 https://developers.cloudflare.com/workers/get-started/guide#8-publish-your-project
デプロイが完了したらCloudflareのWorkers一覧ページにアクセスして、そこに表示されているURLを確認します。
そこに表示されているURLを Discordのアプリケーション設定ページの discord-interactions
にペーストしてセーブしてチェックがパスしたら完了です。
Posted on July 21, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.