バージョン 1.5 で追加.

ゲートウェイインテント入門

バージョン1.5では Intents が導入されました。これにより、Botの書き方が根本的に変わります。基本的にインテントは、特定のイベント群をBotにサブスクライブさせるためのものです。各インテントに対応するイベントは、 Intents のドキュメントに個別の属性として記載されています。

インテントは intents 引数を介して Client またはそのサブクラス(AutoShardedClient, AutoShardedBot, Bot)のコンストラクタに渡されます。

インテントが渡されなかった場合、標準の設定が使用されます。標準の設定では現在特権インテントとされている Intents.presencesIntents.presences 以外のインテントが全て有効になります。

どのインテントが必要でしょうか?

あなたのBotに必要なインテントは、あなたにしかわかりません。 Intents クラスのドキュメントの各属性欄には、どの events に対応し、どのようなキャッシュを有効化するのか記述されています。

たとえば、プレゼンスやタイピングといったわずらわしいイベント抜きに動作するbotを書きたい場合、次のようにします。

 import discord
 intents = discord.Intents.default()
 intents.typing = False
 intents.presences = False

 # Somewhere else:
 # client = discord.Client(intents=intents)
 # or
 # from discord.ext import commands
 # bot = commands.Bot(command_prefix='!', intents=intents)

なお、特権インテントであるため、 Intents.members は有効になりません。

別の例: メッセージとギルド情報だけを扱うボット:

 import discord
 intents = discord.Intents(messages=True, guilds=True)
 # If you also want reaction events enable the following:
 # intents.reactions = True

 # Somewhere else:
 # client = discord.Client(intents=intents)
 # or
 # from discord.ext import commands
 # bot = commands.Bot(command_prefix='!', intents=intents)

特権インテント

API変更に伴い、Bot製作者がインテントを指定する必要が生じました。いくつかのインテントはより制約され、手動での設定を必要とするようになりました。これらのインテントを 特権インテント と呼びます。

特権インテントは、開発者ポータルで手動で有効にしなければならないインテントです。有効化の手順は以下のとおりです。

  1. Discordのウェブサイト にログインできていることを確認してください。

  2. アプリケーションページ に移動します。

  3. 特権インテントを有効にしたいBotをクリックします。

  4. 画面の左側にあるBotタブに移動します。

    アプリケーションページのボットタブ。
  5. 「Privileged Gateway Intents」セクションまでスクロールし、必要なものを有効にします。

    特権ゲートウェイのインテントセレクタ。

警告

もしあなたのBotが100以上のギルドで利用されているなら、特権インテントを有効化するために bot verification が必要です。すでに認証済みのBotで特権インテントを有効化したい場合、 Discord support で報告してください。

注釈

開発者ポータルでインテントを有効化した後は、コード内でインテントを有効化しましょう。

私には特権インテントが必要ですか?

ある特権インテントが必要かについての簡単なチェックリストを用意しました。

プレゼンスインテント

メンバーインテント

  • メンバーの参加や退出を追跡するか。それぞれ on_member_join()on_member_remove() イベントが対応します。

  • ニックネームやロールの変更など、メンバーの更新を追跡するか。

  • ユーザー名、アバター、識別子などのユーザーの更新を追跡するか。

  • Guild.chunk()Guild.fetch_members() でギルドメンバーリストをリクエストするか。

  • Guild.members で高精度メンバーキャッシュを使用するか。

メンバーキャッシュ

Discordは、インテントとともにメンバーをキャッシュする機能をさらに制限し、必要に応じてボット作成者がキャッシュできるようになりました。 しかし、適切にキャッシュを維持するには、退出したメンバーを追跡し、適切に退出させるために :attr:の Intents.members` インテントが必要です。

メンバーがキャッシュされる必要がないメンバーキャッシュを支援する ライブラリにメンバーキャッシュを制御するための MemberCacheFlags フラグが追加されました。 クラスのドキュメンテーションページは、可能な特定のポリシーに行きます。

可能な場合、Discordがメンバー情報を提供するため、メンバーキャッシュを必要としないことがあります。例えば:

  • キャッシュが無効になっていても、on_message()Message.author がメンバーになります。

  • キャッシュが無効の場合でも、on_voice_state_update()member パラメータをメンバーにします。

  • on_reaction_add() は、キャッシュが無効になっている場合でもギルド内の user パラメータをメンバーにします。

  • on_raw_reaction_add() は、キャッシュが無効になっていてもギルド内にいるときに RawReactionActionEvent.member がメンバーになります。

  • ダイレクトメッセージで追加されたリアクションは追加情報を含んでいません。これはDiscordの制限です。

  • リアクション削除イベントにメンバー情報がありません。これはDiscordの制限です。

Other events that take a Member will require the use of the member cache. If absolute accuracy over the member cache is desirable, then it is advisable to have the Intents.members intent enabled.

メンバーを取得中

キャッシュが無効になっている場合、または起動時にチャンキングギルドを無効にしている場合でも、メンバーをロードする方法が必要になる場合があります。 ライブラリには、以下の方法があります。

  • Guild.query_members()
    • ニックネームまたはユーザー名に一致するプレフィックスによってメンバーを照会するために使用されます。

    • これは、ユーザー ID によってメンバーを照会するためにも使用できます。

    • これは HTTP ではなくゲートウェイを使用します。

  • Guild.chunk()
    • これはゲートウェイからメンバーリスト全体を取得するために使用できます。

  • Guild.fetch_member()
    • HTTP APIを介してIDでメンバーを取得するために使用されます。

  • Guild.fetch_members()
    • HTTP APIを介して多数のメンバーを取得するために使用されます。

ゲートウェイには、60秒あたり120リクエストの厳格なレート制限があることに注意してください。

トラブルシューティング

強制的な意図変更に関連するいくつかの一般的な問題。

私のメンバーはどこに行ったの?

Due to an API change Discord is now forcing developers who want member caching to explicitly opt-in to it. This is a Discord mandated change and there is no way to bypass it. In order to get members back you have to explicitly enable the members privileged intent and change the Intents.members attribute to true.

例:

 import discord
 intents = discord.Intents.default()
 intents.members = True

 # Somewhere else:
 # client = discord.Client(intents=intents)
 # or
 # from discord.ext import commands
 # bot = commands.Bot(command_prefix='!', intents=intents)

on_ready を起動するのに時間がかかるのはなぜですか?

インテントに関するAPIの変更の一環として、Discordは最初のメンバーの読み込み方法も変更しました。 もともとライブラリは 75 個のギルドを一度にリクエストでき、 Guild を持つギルドのメンバーのみをリクエストできます。 arge 属性が True に設定されています。新しい意図が変更された場合、Discordはリクエストごとに1つのギルドしか送信できません。 これは75倍の減速を引き起こし、大規模なギルドだけでなく*すべての*ギルドが要求されているという事実によってさらに複雑になります。

There are a few solutions to fix this.

最初の解決策は、特権メンバーの意図とともに、特権メンバーの意図を要求し、両方を有効にすることです。 これにより、初期メンバーリストに以前のゲートウェイと同様にオンラインメンバーを含めることができます。 我々はまだリクエストごとに1つのギルドに制限されていることに注意してください。しかし、我々がリクエストしたギルドの数は大幅に減少します。

二つ目の解決方法は、クライアントを構築する際に chunk_guilds_at_startupFalse に設定することでメンバーのチャンクを無効にすることです。 ギルドのチャンキングが必要な場合は、 :ref:`メンバーを取得する <retrieving_members> `の様々なテクニックを使うことができます。

APIの変更によって引き起こされる減速を説明するために。 840ギルドに参加しているボットを取ると、そのギルドの95は「大」(250人以上のメンバー)です。

Under the original system this would result in 2 requests to fetch the member list (75 guilds, 20 guilds) roughly taking 60 seconds. With Intents.members but not Intents.presences this requires 840 requests, with a rate limit of 120 requests per 60 seconds means that due to waiting for the rate limit it totals to around 7 minutes of waiting for the rate limit to fetch all the members. With both Intents.members and Intents.presences we mostly get the old behaviour so we're only required to request for the 95 guilds that are large, this is slightly less than our rate limit so it's close to the original timing to fetch the member list.

申し訳ありませんが、この変更がDiscordから要求されているため、ライブラリがこれを軽減するためにできることはありません。

DiscordのAPIの方向性が本当に嫌いなら、support で連絡できます。