3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Discord Application Commands 非公式日本語版リファレンス その1

Posted at

はじめに

はじめまして。@nahiro_tusです。

この記事は、Discordのアプリケーションコマンドのドキュメントを読むのが大変だったので、自分なりにまとめてみた記事になります。

原文は英語なので、DeepLなどを活用しながら少しずつ読み進めていきました。もし間違っている個所や表現がおかしい部分などがありましたらコメントを頂ければ修正します。
今後Discordのアプリケーションコマンドを作ってみたい方や作る予定の方、現在開発をしている方の参考になれば幸いです。
この記事は以下のページを参考にして作っています。

Application Commandsとは

Application Commandsを一言で表すなら、「ユーザーのアクションをトリガーとして処理を開始してくれる機能」です。これだけだと少々わかりにくいので、今までのDiscord botと比較してみましょう。

従来のDiscord botの構成は以下のようになっていました。

従来のbotサーバ.drawio (1).png

botが各Discordサーバーにbotユーザとしてログインし、コマンド受け付け状態になります。この状態でbotに登録されたコマンドをユーザーが手動で入力すると処理が開始されます。

Discordサーバーの呼び方について
開発者ドキュメントではDiscordサーバーのことを「ギルド」と呼んでいるので、以降はその呼び方で統一します。

この構成のデメリットとして、

  • botが常時接続状態である必要がある
  • コマンドの構文やパラメータはユーザが覚えている必要がある

が挙げられます。
また、bot用サーバ側で構文解析を行っている構成上、送信したメッセージはすべてbot用サーバに送信されます。

Application Commandsでは、これらのデメリットが解消されています。

appbotの構成.drawio.png

Application Commandsのコマンドが実行されると、Discord botにあらかじめ設定されたエンドポイントへリクエストを実行します。その後、ギルドへHTTPレスポンスを返したりバックエンドからDiscord APIへのリクエストを行ったりすることにより、メッセージを返信したりギルドの情報を更新したりできます。

従来のDiscord botと比較すると

  • bot用サーバーが不要になった
    • botがDiscordに常時接続する必要がなくなったため、bot用のサーバを立てる必要がなくなった
    • Discord botに設定したAPIエンドポイントにリクエストするので、サーバーレス構成も容易
  • コマンドを暗記が不要になった
    • スラッシュコマンドではコマンドが補完されるため、コマンドを覚える必要がなくなった
    • さらに、入力値を選択式にできるので、入力するパラメータを制限できる
  • コマンドの入力内容のみが送信されるので、セキュリティ的にも安心

などのメリットがあります。

Application Commandsの種類

Application Commandsは3種類あります。

  • Slash Commands
  • User Commands
  • Message Commands

それぞれ簡単に解説します

Slash Commands

おそらく最もオーソドックスなコマンド。別名CHAT_INPUT

メッセージ入力欄に/を入力するとSlash Commandが入力できます。

Untitled.png

すでにビルドインで何種類か用意されており、テキストを強調するコマンドやちゃぶ台返しをするコマンドが使えるようになっています。

ちなみにちゃぶ台返しをするコマンドでは以下のようなメッセージを作れます。

テスト勉強なんてやってられんわ! (╯°□°)╯︵ ┻━┻

テスト勉強はちゃんとしましょう。

User Commands

別名USER。ユーザーを右クリック(もしくはタップ)すると表示されるUIベースのコマンドです。

スクリーンショット 2023-07-11 224145 (1).png

ユーザーに関係する処理を実行するときに便利です。特定のユーザーにロールをまとめてつけたり、ユーザー情報を自分に送るときなどに使えそうです。

Message Commands

別名MESSAGE。メッセージを右クリック(もしくはタップ)すると表示されるUIベースのコマンドです。

Untitled (1).png

メッセージに関係する処理を実行するときに便利です。メッセージをブックマークしたり、メッセージを翻訳するbotなどが作れそうです。

コマンドの登録・更新・削除

コマンドはHTTPエンドポイント経由でのみ登録することができます。画面から登録することはできません。

コマンドのスコープ

コマンドのスコープにはグローバルギルドの2種類があります。

グローバルスコープ

アプリケーションを追加したすべてのギルドで使用可能です。
また、自分と相手が同じギルドに属しており、そのギルドにグローバルスコープのコマンドを持つアプリがある場合、DM(ダイレクトメッセージ)でもそのコマンドを使用することができます。

ギルドスコープ

そのコマンドを使用できるのは作成時に指定したギルドのみです。
また、DMで使用することもできません。

制約

コマンド名は、アプリケーションごと、タイプごと、各スコープごとに一意ある必要があります。以下は公式ドキュメントに書かれていた具体例です。

  • 同じ名前の2つのグローバルCHAT_INPUTコマンドを含めることはできない
アプリケーション

スコープ:グローバル
タイプ:CHAT_INPUT
コマンド1:sample

スコープ:グローバル
タイプ:CHAT_INPUT
コマンド2:sample
  • 同じギルドで同じ名前の2つのギルドCHAT_INPUTコマンドを含めることはできない
アプリケーション

スコープ:ギルドA
タイプ:CHAT_INPUT
コマンド名:sample

スコープ:ギルドA
タイプ:CHAT_INPUT
コマンド名:sample
  • 同じ名前のグローバルUSERコマンドを含めることができない
アプリケーション

スコープ:グローバル
タイプ:USER
コマンド名:sample

スコープ:グローバル
タイプ:USER
コマンド名:sample
  • 同じ名前のグローバルCHAT_INPUTコマンドとギルドCHAT_INPUTコマンドを含めることができる
アプリケーション

スコープ:グローバル
コマンド名:sample

スコープ:ギルドA
コマンド名sample
  • 同じ名前のグローバルCHAT_INPUTコマンドとグローバルUSERコマンドを含めることができる
アプリケーション

スコープ:グローバル
タイプ:CHAT_INPUT
コマンド名:sample

スコープ:グローバル
タイプ:USER
コマンド名:sample
  • 複数のアプリに同じ名前のコマンドを含めることができる
アプリケーションA
コマンド名:sample

アプリケーションB
コマンド名:sample

つまり、アプリケーション名・スコープ・タイプ・コマンド名の4つのパラメータの組み合わせがユニークであればコマンドを登録することができます。

また、1つのアプリケーションあたりに登録できるコマンドの数はタイプごとに決まっています。

CHAT_INPUT

  • 100個の(グローバルコマンド+ギルドコマンド)

USER

  • 5個の(グローバルコマンド+ギルドコマンド)

MESSAGE

  • 5個の(グローバルコマンド+ギルドコマンド)

登録リクエスト上限
1ギルドあたり、1日に登録できるコマンド数は200件まで

コマンドの登録方法

ここからはコマンド登録の具体的な方法について書いていきます。コマンドの登録は、特定のエンドポイントに対してPOSTメソッドでリクエストすると登録することができます。
パラメータの詳細については次回解説するので、ひとまず以下の内容を覚えておけば大丈夫です。

  • nameはコマンド名
  • typeはコマンドの種類
  • descriptionはコマンドの説明
  • optionCHAT_INPUT固有のパラメータ

グローバルコマンドの作成

グローバルコマンドはapplicationを招待したすべてのサーバーで使用可能なコマンドです。グローバルコマンドは登録時に読み取り修復機能処理が走ります。グローバルコマンドを更新する前に内部で整合性判定を行い、万が一チェックに失敗した場合はそのコマンドの更新が拒否されます。

登録するためには以下のようなHTTPリクエストを送信します。

add_command.py
import requests

my_application_id = <作成したdiscord app のID>

# credentioals_token か app_tokenのどちらかを宣言
my_bot_token = <作成したdiscord app のトークン>
# my_credentials_token = <applications.commands.update の権限を付与したcredentials_token>

url = f"https://discord.com/api/v10/applications/{my_application_id}/commands"

# 以下はスラッシュコマンドを登録するときの例です
json = {
    "name": "blep",
    "type": 1,
    "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": f"Bot {my_bot_token}"
}

# credentials tokenを使用する場合はこのコメントアウトを外して、bot tokenのヘッダーをコメントアウトする
# headers = {
#     "Authorization": f"Bearer {my_credentials_token}"
# }

r = requests.post(url, headers=headers, json=json)

コードを実行すると、以下のようなスラッシュコマンドが登録されます

Untitled (2).png

ギルドコマンドの作成

ギルドコマンドは作成時に指定したギルドでのみ使用できるコマンドです。ギルドコマンドはグローバルコマンドとは違い、読み取り修復機能はありません。そのため、リクエストをすると即時に設定が反映されます。公式ドキュメントでは、開発やテストはギルドコマンドで実装し、一般公開時にグローバルコマンドへ変更することを推奨しています。

add_command.py
import requests

# ここに変更が入っている
url = "https://discord.com/api/v10/applications/<my_application_id>/guilds/<guild_id>/commands"

# This is an example USER command, with a type of 2
json = {
    "name": "High Five",
    "type": 2
}

# For authorization, you can use either your bot token
headers = {
    "Authorization": "Bot <my_bot_token>"
}

# or a client credentials token for your app with the applications.commands.update scope
headers = {
    "Authorization": "Bearer <my_credentials_token>"
}

r = requests.post(url, headers=headers, json=json)

type:2を指定するとUSERコマンドを登録することができます。

このコマンドを実行すると、ギルドUSERコマンドが登録されます。

スクリーンショット 2023-07-11 224145 (1).png

コマンドの更新方法

コマンドの更新と削除にはPATCHメソッドとDELETEメソッドを使います。

以下のエンドポントへPATCHメソッドでリクエストすると更新、DELETEメソッドでリクエストすると削除が行えます。

  • グローバルコマンドの場合

https://discord.com/api/v10/applications/<my_application_id>/commands/<command_id>

  • ギルドコマンドの場合

https://discord.com/api/v10/applications/<my_application_id>/guilds/<guild_id>/commands/<command_id>

また、コマンドはアプリケーション名、スコープ、名前、タイプで識別されているため、POSTメソッドはupsert(データが存在しなければ追加(insert)、存在すれば更新(update))として処理されます。
そのため、アプリケーション内ですでに存在するスコープ、名前、タイプの組み合わせに対してPOSTでリクエストをすると、PATCHでのリクエストと同じ処理になります。

まとめ

今回はDiscord Application Commandsの基本情報と種類、具体的な登録方法について紹介しました。Application Commands のリファレンスはボリュームが大きいので、複数回に分けて紹介するつもりです。今のところ全3回を予定しているので、続きが気になる方は「いいね」を押してもらえるとうれしいです。(「いいね」が多いと執筆スピードが上がります。)

次回はApplication Commandsの各パラメータの解説と、コマンドの種類ごとの特徴について書きたいと思っています。

お楽しみに。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?