TL; DR
2025年8月3日現在、この手法は使用可能です。
本記事のコードをコピーした記事に、バグを利用しているとの記述がありますが、バグや非推奨オプションではありません。
const client = new Discord.Client({
ws: {
buildStrategy: manager => new (class MobileSimpleShardingStrategy extends SimpleShardingStrategy {
constructor(manager) {
manager.options.identifyProperties = {
os: "ios",
device: "device",
browser: "Discord iOS"
};
super(manager);
}
})(manager)
}
});
モバイルステータスって?
実はこれ、スマホだとモバイルとして表示されないんですよね。なぜでしょう…?
技術的な内容
実はこれは、接続元デバイスから判定しており、その情報はDiscord Gatewayに接続する際1、identifyに自己申告する形で含まれています2。
そのため、identifyを変更すればよいわけです。要は User-Agent 書き換えのようなものですね。
本題
v13まで
v133までは Client のコンストラクタに指定するオプションで指定できていました。
const client = new Discord.Client({
ws: {
properties: { $browser: "Discord iOS" }
}
});
しかし、いつからかこのオプションが削除され、変更できなくなりました。
また、直接的な関係はありませんが、Discord API v10においても $browser 短縮プロパティが削除されました2。
そのため、この方法はレガシーな方法といえるでしょう。
v14では
しかし、v14ではそもそも Client のオプションの ws に関連する設定が見当たりません。
ではどうすればいいのかというと、ソースを読んでコールツリーを頭の中で生成し、抜け道を探します(力技)4。
前提
Discord.js において、WebSocketに実際に接続する役割は @discordjs/ws というライブラリが担っています。このライブラリと、Discord.js 本体どちらにも WebSocketManager・WebSocketShard が存在するので、5今回は前者を WSWebSocketManager・WSWebSocketShard と呼称します。
今回は TypeScript で動作する環境で Client オブジェクトのコンストラクタのオプションのみで、identify オブジェクトを変更することが目的です。
コールツリー
- コード6を読むと、実際に送信される
propertiesは<WSWebSocketShard>.strategy.options.identifyPropertiesを参照しています7。 -
<WSWebSocketShard>.strategyについては、IContextFetchingStrategyが使用されています8。この変数は、コンストラクタによって代入されています9。 -
WSWebSocketShardは、<SimpleShardingStrategy>.spawnにて生成されています10。 - この
SimpleShardingStrategyは、<WSWebSocketManager>.strategyに存在しています11。以後、型はIShardingStrategyとなります。 -
<WSWebSocketManager>.strategyは、<WSWebSocketManager>.options.buildStrategy関数によって生成されています12。 -
<WSWebSocketManager>.optionsは、デフォルトが指定されているもののoptionsで上書きされています13。 -
WSWebSocketManagerは、<WebSocketManager>.connectにて生成されています。 -
wsOptions.buildStrategyは、ws.buildStrategyを参照しています14。 -
wsは、this.client.optionsを参照しています。この先は自明であると思いますが、Clientのコンストラクタに指定できるオプションが参照されています。
結論
つまり、Client のコンストラクタのオプションの、 ws.buildStrategy 関数にカスタムクラスを一枚挟んで、受け取る manager (WSWebSocketManager) の options を変更すればいいということです。
なお、TypeScript と言っておきながら manager は下記コードでは any 型です。@discordjs/ws をインポートして解決することはできますが、私はめんどくさいので any でつぶしています。ごめんね。
const client = new Discord.Client({
ws: {
buildStrategy: manager => new (class MobileSimpleShardingStrategy extends SimpleShardingStrategy {
constructor(manager) {
manager.options.identifyProperties = {
os: "ios",
device: "device",
browser: "Discord iOS"
};
super(manager);
}
})(manager)
}
});
おわりに
Discord.js はドキュメントがふわふわしてたり分かれていたり互換性がなかったり…
TypeScript / JavaScript 信者なので、一番使いやすいライブラリではあるんですが、なんか絶妙な使いたくなさがありますね。
-
https://discord.com/developers/docs/topics/gateway#connection-lifecycle ↩
-
https://discord.com/developers/docs/topics/gateway-events#identify-identify-connection-properties ↩ ↩2
-
不明瞭な情報です。古いコード記載されていたのはこの方式で、その時のDiscord.jsのバージョンがv13だった記憶があるからです。よく調べてません、今使えないものは使えないんで。 ↩
-
2時間かかりました。 ↩
-
お前、嘘だろ…ネーミングセンス………… ↩
-
https://github.com/discordjs/discord.js/blob/bfc7bb55641c60d4d67e57c27c9d1e63b6f30c9b/packages/ws/src/ws/WebSocketShard.ts#L460 ↩
-
https://github.com/discordjs/discord.js/blob/bfc7bb55641c60d4d67e57c27c9d1e63b6f30c9b/packages/ws/src/ws/WebSocketShard.ts#L446 ↩
-
https://github.com/discordjs/discord.js/blob/bfc7bb55641c60d4d67e57c27c9d1e63b6f30c9b/packages/ws/src/ws/WebSocketShard.ts#L117 ↩
-
https://github.com/discordjs/discord.js/blob/bfc7bb55641c60d4d67e57c27c9d1e63b6f30c9b/packages/ws/src/ws/WebSocketShard.ts#L129 ↩
-
https://github.com/discordjs/discord.js/blob/bfc7bb55641c60d4d67e57c27c9d1e63b6f30c9b/packages/ws/src/strategies/sharding/SimpleShardingStrategy.ts#L29 ↩
-
https://github.com/discordjs/discord.js/blob/bfc7bb55641c60d4d67e57c27c9d1e63b6f30c9b/packages/ws/src/ws/WebSocketManager.ts ↩
-
https://github.com/discordjs/discord.js/blob/bfc7bb55641c60d4d67e57c27c9d1e63b6f30c9b/packages/ws/src/ws/WebSocketManager.ts#L231 ↩
-
https://github.com/discordjs/discord.js/blob/bfc7bb55641c60d4d67e57c27c9d1e63b6f30c9b/packages/ws/src/ws/WebSocketManager.ts#L230 ↩
-
https://github.com/discordjs/discord.js/blob/bfc7bb55641c60d4d67e57c27c9d1e63b6f30c9b/packages/discord.js/src/client/websocket/WebSocketManager.js#L159 ↩

