Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
11
Help us understand the problem. What is going on with this article?
@CyberRex

PythonにおいてのDiscord Slash Commandの実装方法

Discordには、最近「スラッシュコマンド」と呼ばれる新しい機能が実装されました。
公式リファレンス見てても英語ばかり、翻訳してみてもいまいち理解できないですよね。

そこで、ライブラリを使ってかんたんに実装しつつ仕組みを理解していくことにします。

※なお、Webhook型に関してはここで扱いません

スラッシュコマンドの標準的な仕様

無題3_20210105114325.png

言葉で長々と説明するのも分かりづらいと思いましたので図を用意しました。

クライアントがスラッシュコマンドを使うとゲートウェイ経由でボットに「〇〇が□□というコマンドを使った、引数はA, B, ...」などという情報とともに通知が行きます。

それに従ってボットは応答処理をします。

しかしこの方法はWebSocket経由であるため、送られてきた生の状態のデータを扱うのは難易度が高いです。

discord-py-slash-commandを使う

最も簡単でおすすめできるのは有志のモジュールを使うことです。
これを使えば、コマンドの実装だけに集中できて他にとらわれることもないと思います。

python3 -m pip install discord-py-slash-command

でパッケージをインストールします。

その前に

今のボットの設定では、スラッシュコマンドが使えません。

Discord Developer Portalでボットに新しく権限を与えてサーバーに入れ直す必要があります。
※…と言われていますが、ボットを追い出さなくても入れるときと同じように認証を進めれば権限が付与されるようです。

Developer Portalで必要な設定を行います。
設定したいボットを選んで下の図に従って行ってください。

無題4_20210106130237.png

SCOPESの下に認証用のURLができます。

無題7_20210106131134.png

これからはこのURLを経由して導入してもらうことになります。

コードを書く

import discord
from discord.ext import commands
from discord_slash import SlashCommand, SlashContext

bot = discord.Client(intents=discord.Intents.all())
# または:
# bot = commands.Bot(command_prefix='@', intents=discord.Intents.all())

slash_client = SlashCommand(bot)

@slash_client.slash(name="hello")
async def _slash_hello(ctx: SlashContext):
    await ctx.send(content="Hello!")

@bot.event
async def on_ready():
  print('bot ready.')

bot.run("discord_token")

スラッシュコマンドを使ったボットのコードはこんな感じになります。
※ボットの基本的な部分は解説しません

slash_client = SlashCommand(bot)

これは、スラッシュコマンド専用のオブジェクトです。

@slash_client.slash(name="hello")
async def _slash_hello(ctx: SlashContext):
    await ctx.send(content="Hello!")

このコードでスラッシュコマンドを作ります。
基本的に関数に渡されるコンテキストはCogの時と変わりません。

ただ、違うのはsendメソッドの引数です。
hidden=Trueという引数を追加してあげると、コマンドを実行した人にだけメッセージが表示されるようになります。

これだけです。

最後にひと工夫します。
SlashCommandオブジェクトを作るとき

slash_client = SlashCommand(bot, sync_commands=True)

と、sync_commands=Trueという引数を追加してあげると、モジュールが自動でスラッシュコマンドを登録してくれます。

どのサーバーでも使えるコマンドとそうでないもの

プログラム書いて、いざ起動してみて、テストチャンネルで「/」と入力しても自分のボットは出てこないと思います。

image.png

これは仕様で、今登録したコマンドは、どのサーバーでも使える「グローバルコマンド」です。
登録してから使えるようになるまで最大1時間かかります。

一方、あるサーバー限定でしか使えない「サーバーコマンド」は、即時反映となっています。

また、登録数にも上限があります。簡単に表にまとめました。

種類 反映にかかる時間 最大個数
Global Command 最大1時間 50
Guild Command 即時反映 50

いかがでしょうか。スラッシュコマンドには説明が最初からあって、丁寧に引数まで教えてくれます。
今後に期待しましょう。

注意点もある!応答メッセージの仕様

ボットが応答するメッセージは、Webhookに似た仕様となっています。

everyoneメンションとhereメンションは権限問わず可能

これはとても重要です。予めボット側でメンションの設定を行わないと予期せぬメンションをしてしまうかもしれません。
sendメソッドに、普通のチャンネルに送信するMessage.send()と同様allowed_mentions=Noneという引数を渡すことで未然に防止できます。

Markdownのリンク表記が使える

通常のメッセージでは[リンク](URL)という表記は使えませんが、スラッシュコマンドの応答メッセージでは使えます。

埋め込みを最大10個まで送信可能

複数の埋め込みを一度に送ることができます。

おことわり

discord-py-slash-commandは、Discord.py公式のライブラリではなく、有志によって開発されたものです。
現在開発途中のパブリックベータ版であり、破壊的な仕様変更によって突然動作しなくなったり、ボットの動作に影響を及ぼす場合があります。
以上の点を理解したうえで、モジュールを利用するようにお願いします。

参考

discord-py-slash-command - PyPI
https://pypi.org/project/discord-py-slash-command/

discord-py-slash-command 公式リファレンス
https://discord-py-slash-command.readthedocs.io/en/latest/

Discord Developer Portalドキュメンテーション Interactions: Slash Commands
https://discord.com/developers/docs/interactions/slash-commands

11
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
CyberRex
毎日がマイペース。写真、プログラ厶大好き。 主にWebサイト、サーバーサイドプログラムのデザイン・開発を行っております。 Linux経験豊富です。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
11
Help us understand the problem. What is going on with this article?