# ゲートウェイインテント

WARNING

現在、インテントの送信はオプションですが2020年10月7日以降、必須となります。

ゲートウェイインテントはdiscord.js バージョン12から導入され、これによって、どのイベントをボットが受け取るか選択できるようになります。 インテントとはdiscord.js クライアントが受け取るそれぞれのイベントをグループに分けたもののことです。 例えば、DIRECT_MESSAGE_TYPING インテントを省略するとdiscord.js クライアントはダイレクトメッセージでのタイピングイベントを受け取ることができなくなります。 また、ボットのキャッシュを不要なデータによる圧迫から守ることができます。しかしまだ、イベントを受け取らないことによるライブラリ内部での副作用についてリストにすることができていません。

バージョン11ではインテントを利用することはできません。ボットでゲートウェイインテントを利用する場合はバージョン12を利用してください。

# インテントの有効化

ボットクライアントのインスタンスを作成する際、クライアントオプションでボットの受け取るインテントを選択できます。

ライブラリのサポートするインテントの一覧はthe discord.js documentationにあります。 イベントがどのインテントに含まれるかはdiscord API documentationに書いてあります。

TIP

GUILD_PRESENCES はギルドメンバーのデータを始めに受け取るために必要です。 もし指定されない場合はGUILD_MEMBERSを指定してもメンバーのキャッシュは空となり、更新されません。 あるインテントを無効にする(イベントの受信をやめる)前にボットが正常に動作しなくなることのないよう、ボットがどのように動いているのか考えなければなりません。 discord.js バージョン12では完全にはインテントをサポートしていません。一見無関係なデータが失われることがあります。

const { Client } = require('discord.js');
const client = new Client({ ws: { intents: ['GUILDS', 'GUILD_MESSAGES'] } });

# インテントビットフィールドのラッパー

discord.js はIntentsというユーティリティーを提供しており、ビットフィールドを容易に操作することができます。

また、staticフィールドとして、インテントをすべて含んだもの(Intents.ALL)、特権インテントをすべて含んだもの(Intents.PRIVILEGED)、特権を必要としないインテントをすべて含んだもの(Intents.NON_PRIVILEGED)が定義されています。 これをそのまま用いたり、Intentsコントラスタに渡して変更して用いたりすることができます。

const { Client, Intents } = require('discord.js');
const client = new Client({ ws: { intents: Intents.ALL } });

.add().remove() メソッドを用いてフラグを建てたり消したりし、ビットフィールドを変更することができます。 discord.jsは指定された引数にスプレッド演算子を使用するため、配列やビットフィールドだけでなくフラグ単体も引数に渡すことができます。 テンプレートとしてインテントのセットを使う場合はそれらをコントラスタに渡すこともできます。 いくつかのアプローチを以下に示します。

const { Client, Intents } = require('discord.js');
const myIntents = new Intents();
myIntents.add('GUILD_PRESENCES', 'GUILD_MEMBERS');

const client = new Client({ ws: { intents: myIntents } });

// ビットフィールドを操作する追加の例

const otherIntents = new Intents(Intents.NON_PRIVILEGED);
otherIntents.remove(['GUILDS', 'GUILD_MESSAGES']);

const otherIntents2 = new Intents(32509);
otherIntents2.remove(1, 512);

構築されたフラグを利用したい場合は.toArray().serialize().missing() メソッドを利用できます。 それぞれ、ビットフィールドで表されるフラグの配列、ビットフィールドをもとに、すべてのフラグ値をキーとしインテントが有効かどうかを真偽値として持つオブジェクト、 ビットフィールドが持っていないフラグを返します。(そのため、特定のインテントのビットフィールドを渡す必要があります)

# 特権インテント

Discordは、イベントを通じて送信されるデータの機密性から、いくつかのインテントを「特権」と定義しています。 この記事を書いている時点では、特権インテントは GUILD_PRESENCESGUILD_MEMBERS の2つです。

今のところ、これらのインテントは、Discord Developer Portalで切り替えを行うだけで有効にできます。 これは現在、非推奨期間であり、2020年10月7日以降に特権インテントを使用するにはホワイトリストに登録されたボットが必要です。 ホワイトリストについてはこちらのdiscordの記事をご覧ください。

[DISALLOWED_INTENTS]: Privileged intent provided is not enabled or whitelisted(与えられた特権インテントは有効になっていないか、ホワイトリストに登録されていません)といったエラーが表示された場合は、使用しているすべての特権インテントの設定を確認してください。 特権インテントの公式ドキュメントはdiscord API documentationとなります。

# ビットフィールドの詳細

Discordの権限は53ビット整数で保存され、ビット単位で計算されます。 その裏で何が起きているのかについて詳しく知りたい場合は、WikipediaMDNの記事をチェックしてください。

discord.jsでは、パーミッションビットフィールドは、ビットフィールドまたはフラグへの参照の有無として表されます。 パーミッションビットフィールド内のすべてのビットは、これらのフラグの状態を表します (1ならばtrue、0ならばfalse)。