Gateway Intents の利用に関するガイド
各Gateway Intentsの役割などを大雑把に整理する。
これは特に間違いを含む可能性がある。
cacheという大きな状態に手を焼いていますtig.icon
Interactionsのみを使用するのであればIntentsを何も要求しなくても(0を指定しても)利用できる。
@discordjs/*系のパッケージを利用するべきかもしれないtig.icon
以下も参照
Gateway Intents を指定するサンプル
Presence IntentおよびServer Members Intentが影響する処理
2020年10月7日のDiscord APIの仕様変更
Gateway Intents と Discord.js の内部実装
GUILDS
現状これがないとギルドとギルドチャンネルがキャッシュに乗らない
discord.jsはこの2つがすべてキャッシュされている前提で書かれている
v13からInteractionsのサポートが入ったので必ずしもそうとは言えなくなった。tig.icon
基本的にキャッシュされる
つまりこれがないとdiscordjsはまともに動かない
DMのみ扱うとかなら動くかも知れない
partialは一部のイベントにおいて効果を発揮しない
例えば
チャンネルがキャッシュに乗っていないとmessageCreateがそのチャンネルで発火しない
ギルドがキャッシュにのっていないとpresenceUpdateが発火しない
botのguildへの追加、削除
guildの作成、更新、削除
ロールの作成、更新、削除
チャンネルの作成や更新、削除
スレッドの作成や更新
ステージの開始や更新、終了
以下のcollectorが内部でこのIntentsにより提供されるイベントをcollectorの停止のため、利用している
ReactionCollector
InteractionCollector
MessageCollector
GUILD_MEMBERS
これはPrivileged Intentsとされている
Server Members Intent
次のイベントを使用している場合
guildMemberAdd
guildMemberRemove
guildMemberUpdate
ただし、自身のニックネームの変更などの自身の情報の変更はこれを指定しなくても受け取れる
threadMembersUpdate
ただし、自身がスレッドに追加された場合はこれを指定しなくてもGUILDSがあれば受け取れる
サーバーのメンバーを全列挙している場合
guild.members.fetch()など
privileged intentsの"指定"は関係ない気がするyuta0801.icon
そういうトピックもまとめて扱いたかったのでタイトル変えましたtig.icon
ところでこれはREST APIではなくGateway API なので影響するはずです
Gateway APIにRequest Guild Membersがあったのを忘れた
サーバーの人数を利用している場合
Guild#memberCount など
ボットがAPIに接続したときの初期値は使えそうだが、更新がされない
更新はクライアント側でguildMemberAdd/Removeイベントを使ってカウントしてる
微妙に正確ではないけど理解としてはそうtig.icon
ただしこれはGuild#approximateMemberCountの利用で回避できる
ただし使う場合はGuild#fetchを呼び出すように実装する必要がある
自動では更新されないので、最新の結果を得たいのなら毎回fetchすることになる
GUILD_BANS
ギルドのbanの追加や削除に関する情報をGateway APIから受け取りたい場合
例えば、以下のイベントを使用している場合
guildBanAdd
guildBanRemove
GUILD_EMOJIS_AND_STICKERS
ギルドの絵文字やstickerの追加や削除に関する情報をGateway APIから受け取りたい場合
例えば、以下のイベントを使用している場合
emojiCreate
emojiUpdate
emojiDelete
stickerCreate
stickerUpdate
stickerDelete
起動後に追加されたサーバー絵文字がリアクションとして追加/削除された場合に反応したい場合も必要かもしれない
わからんtig.icon
Unicode絵文字に反応したいだけならいらない
GUILD_INTEGRATIONS
integrationsの更新に関する情報をGateway APIから受け取りたい場合
例えば、以下のイベントを使用している場合
guildIntegrationsUpdate
GUILD_WEBHOOKS
webhookの更新に関する情報をGateway APIから受け取りたい場合
例えば、以下のイベントを使用している場合
webhookUpdate
GUILD_INVITES
招待の作成や削除に関する情報をGateway APIから受け取りたい場合
例えば、以下のイベントを使用している場合
inviteCreate
inviteDelete
GUILD_VOICE_STATES
メンバーの音声に関する情報の更新をGateway APIから受け取りたい場合
例えば、以下のイベントを使用している場合
voiceStateUpdate
VoiceChannelクラスのmembersプロパティを使用している場合
VoiceChannel#joinには影響しないはず v12
@discordjs/voiceはこのイベントを必要とする v13
GUILD_PRESENCES
これはPrivileged Intentsとされている
Presence Intent
Presenceを利用している場合
ただしオンライン人数の取得についてはGuild#approximatePresenceCountを利用することもできる
使う場合はGuild#fetchを呼び出すように実装する必要がある
自動では更新されないので、最新の結果を得たいのなら毎回fetchすることになる
GuildMemberManager#fetchにwithPresenceを指定するのもだめ
メンバー/ユーザーのキャッシュが必要な場合
メンバーのキャッシュが必要な処理
ユーザーのキャッシュが必要な処理
指定しない場合、初期に送信されてくるユーザーの情報はVCにいるボットとユーザーのみになる
guild member addじゃなくてpresence updateなんだyuta0801.icon
Guild Createのはなししてるつもりだったtig.icon
If you are using Gateway Intents, members and presences returned in this event will only contain your bot and users in voice channels unless you specify the GUILD_PRESENCES intent.
あーそっちでもmembersが送信されるんだ
既存のメンバーはこっち。tig.icon
新規メンバーはGuild Member Add
guild member addが(guild createと同じように)接続時にも呼び出されると誤解していた
指定してもすべてのメンバーの情報が来るわけではない
largeなギルドなど
回避策のアイデア
partialsを指定する
その上で次のようなメソッドを使う
GuildMember#fetch
User#fetch
以下のようなメソッドを使用する
GuildMemberManager#fetch
UserManager#fetch
GUILD_MESSAGES
ギルドのテキストベースなチャンネル(テキストチャンネル、ニュースチャンネル、スレッドチャンネル等)のメッセージの作成や削除、更新についての情報を受け取りたい場合
例えば、以下のイベントをギルドのテキストベースなチャンネルで使用している場合
message v12
messageCreate v13
messageUpdate
messageDelete
以下のcollectorが内部でこのイベントをcollectorの停止のため、利用している
ReactionCollector
InteractionCollector
ただし、メッセージを対象としている場合
messageDeleteBulk
MessageCollectorは内部で上記のイベントを使用している
よって以下のものを利用するためにもこのIntentsが必要
TextBasedChannel#createMessageCollector
Message#awaitMessages
内部でMessageCollectorを利用している
メッセージ内容(content, embeds, attachments, components)の読み取りにはMessage Content Intentが必要
GUILD_MESSAGE_REACTIONS
ギルドのテキストベースなチャンネル(テキストチャンネル、ニュースチャンネル、スレッドチャンネル等)のメッセージにつけられたリアクションについての情報をGateway APIから受け取りたい場合
例えば、以下のイベントをギルドのテキストベースなチャンネルのメッセージで使用している場合
messageReactionAdd
messageReactionRemove
messageReactionRemoveAll
messageReactionRemoveEmoji
ReactionCollectorは内部で上記のイベントを使用している
よって以下のものを利用するためにもこのIntentsが必要
Message#createReactionCollector
Message#awaitReactions
内部でReactionCollectorを利用している
GUILD_MESSAGE_TYPING
以下のイベントをサーバー内のチャンネルで使用している場合
typingStart
DIRECT_MESSAGES
DMのメッセージについての情報をGateway APIから受け取りたい場合
例えば、以下のイベントをDMチャンネルで使用している場合
channelCreate v12
gateway v8以降これはDMでは発火しない。
message v12
messageCreate v13
messageUpdate
messageDelete
messageDeleteBulk
TextBasedChannel#createMessageCollector は内部で上記のイベントを使用している
DIRECT_MESSAGE_REACTIONS
DMのメッセージにつけられたリアクションについての情報をGateway APIから受け取りたい場合
例えば、以下のイベントをDMチャンネルで使用している場合
messageReactionAdd
messageReactionRemove
messageReactionRemoveAll
messageReactionRemoveEmoji
Message#createReactionCollectorは内部で上記のイベントを使用している
DIRECT_MESSAGE_TYPING
以下のイベントをDMチャンネルで使用している場合
typingStart