はじめに
Discord.py ver2.0 以降から、Bot と Discord を接続する際に必須となったパラメータ Intents についてまとめてみました。
Intents とは
Intents とは Discord.py Ver1.5 で実装され、Ver2.0 から Bot が Discord に接続する際に必須のパラメータとなりました。Intents を利用することで、"どのイベントを受信し、どのイベントを受信しないか" を Bot が選択できるようになります。不必要なイベントを取得せずに済むため Bot の負荷低減が見込めます。
使い方
一部の Intents には制約が設けられており、コードに記述した上で手動で有効にする必要があります。これらの Intents をまとめて Privieged Intents と呼びます。
有効化の手順は以下の通りです。
- Discord Developer Portal にログインします。
- アプリケーションページに移動します。
- Privieged Intents を有効にしたい Bot を選択します。
- 画面左側にある [Bot] タブに移動します。
-
Privileged Gateway Intents
から必要なものを有効にします。よく分からなければ全て有効でも問題ありません。Bot の権限を制限したい場合、個別に有効化して下さい。
それぞれの Privieged Intents については以下のとおりです。
- PRESENCE INTENT
- メンバーのステータスを追跡するかどうか
- メンバーのアクティビティを確認するかどうか
- SERVER MEMBERS INTENT
- メンバーの参加や退出を追跡するかどうか
- ニックネームやロールの変更など、メンバーの更新を追跡するかどうか
- ユーザー名、アバター、識別子などのユーザーの更新を追跡するかどうか
- ギルドメンバーリストをリクエストするかどうか。
- MESSAGE CONTENT INTENT(Ver2.0 で追加されました)
- メッセージの内容を確認するかどうか
- メッセージの添付ファイルを確認するかどうか
- メッセージの埋め込みを確認するかどうか
- メッセージコンポーネントをチェックするかどうか
注意点として Bot を 100 以上のサーバで運用していている場合、Privieged Intents を有効化するために bot verification が必要になります。Privieged Intents についての詳しい説明は Discord のドキュメントを参考して下さい。
一例として、メッセージへのリアクションに反応してメッセージ主にメンションを送る Bot を見てみましょう。Bot の内容に関しては以下記事で解説しています。
#!/usr/bin/env python3
import discord
TOKEN = 'YourAccessToken'
intents=discord.Intents.none()
intents.reactions = True
intents.guilds = True
# discord.py Ver2.0 以降は必要
#intent.message_content = True
client = discord.Client(intents=intents)
@client.event
async def on_ready():
print('ログインしました')
@client.event
async def on_raw_reaction_add(payload):
txt_channel = client.get_channel(payload.channel_id)
message = await txt_channel.fetch_message(payload.message_id)
user = payload.member
if (message.author == user):
return
reaction = payload.emoji
CHANNEL_ID = 106308992804
channel = client.get_channel(CHANNEL_ID)
msg = f"{message.author.mention} {reaction}\nFrom:{user.display_name} \
\nMessage:{message.content}\n{message.jump_url}"
await channel.send(msg)
client.run(TOKEN)
このコードではまず、5行目の discord.Intents.none()
メソッドで全てのイベントを取得しないように制限しています。その後、個別に使用したい Intents を有効にします。どの Intents を有効にすればいいのかですが、非同期処理と client クラスで使用しているメソッドに着目します(この作業はエラーと API リファレンスとを睨めっこしながら探すことになると思います)。ここでは、on_ready()
、on_raw_reaction_add()
、client.get_channel()
、channel.send
などが対象になります。例えば on_raw_reaction_add()
を使うためには Intents.reactions
を有効にする必要があります。
エラーと睨めっこしながら必要な Intents を探すのもいいですが、普通はこんな煩わしいことはしたくないと思います(Bot の処理をどうしても軽くしたい場合はしてもいいですが…)。そんな時のために Privieged Intents 以外の全ての Intents を True
としてくれる discord.Intents.default()
というメソッドが用意されています。以下のように使用します。
client = discord.Client(intents=discord.Intents.default())
default()
メソッド以外にも、Privieged Intents も含めた全ての Intents を True
とする all()
メソッド、Intents 全てを False
とする none()
メソッドがあります。基本的には default()
メソッドを使用すれば問題ないと思います(何も考えたくなければ all()
メソッドを使用し、Privieged Intents を全て有効化しましょう)。必要に応じて Privieged Intents を有効化する場合は、以下のようにします。
intents = discord.Intents.default()
intents.message_content = True
client = discord.Client(intents=intents)
注意点
Privieged Intents を True
とした場合や、discord.Intents.all()
と指定した場合には、Discord Developer Portal にて対応する Privieged Intents を有効化する必要があります。有効化しないと以下のようなエラーが吐かれます。
discord.errors.PrivilegedIntentsRequired: Shard ID None is requesting privileged intents that have not been explicitly enabled in the developer portal.
Privieged Intents を使用する場合は、コードの記述だけでなく手動で有効化もして下さいということですね。
また、Discord.py Ver2.0 以降から、Bot と Discord を接続する際に使用する Client クラスに Intents の指定が必須となりました。Intents を指定しない場合以下のようなエラーメッセージが出力されます。
TypeError: __init__() missing 1 required keyword-only argument:'intents'
対応として以下のように変更しましょう。
# 変更前
client = discord.Client()
# 変更後
client = discord.Client(intents=discord.Intents.default())
最後に
discord.py の更新により Bot の書き方が大きく変わりました。古い Bot などは注意点で挙げたエラーなどが吐かれて動かないことがあると思います。本記事の対応策が一助になれば幸いです。