Webhookを使ってメッセージの発信者を任意のユーザーに見せかける
messageやinteractionsを受信してその返信を作るときに、任意のユーザーとして返信したいときのTIPS。
厳密にはそのユーザーの発信ではないが、アバターと名前をそのユーザーに見せかけることは可能。
前準備
Dev Portal > Applications > OAuth2 > URL Generatorへアクセス。
SCOPE で bot、BOT PERMISSIONS で Manage Webhooksにチェックを入れる。
Manage Webhooksにチェックを入れることでbotにTextChannel#createWebhook()などを許可する。
メッセージの送受信やスラッシュコマンドを使う場合は適宜必要なSCOPE、BOT PERMISSONSを追加すること。
できたURLでブラウザにアクセスし、自分のサーバーにbotを参加させておく。
サンプルコード #v13
code:js
const Discord = require("discord.js");
//Webhookを管理するために"GUILD_WEBHOOKS"をつけておく
const client = new Discord.Client({
intents: "GUILDS", "GUILD_MESSAGES", "GUILD_WEBHOOKS",
});
//webhookのキャッシュ
const cacheWebhooks = new Map();
async function sendMessage(message) {
//メッセージ発信者の名前とアバターURL
const nickname = message.member.displayName;
const avatarURL = message.author.avatarURL({dynamic : true});
//Webhookの取得(なければ作成する)
const webhook = await getWebhookInChannel(message.channel);
//メッセージ送信(今回は受け取ったものをそのまま送信)
//usernameとavatarURLをメッセージ発信者のものに指定するのがミソ
webhook.send({
content : message.content,
username : nickname,
avatarURL : avatarURL,
}).catch(e => console.error(e));
}
async function getWebhookInChannel(channel) {
//webhookのキャッシュを自前で保持し速度向上
const webhook = cacheWebhooks.get(channel.id) ?? await getWebhook(channel)
return webhook;
}
async function getWebhook(channel) {
//チャンネル内のWebhookを全て取得
const webhooks = await channel.fetchWebhooks();
//tokenがある(=webhook製作者がbot自身)Webhookを取得、なければ作成する
const webhook = webhooks?.find((v) => v.token) ?? await channel.createWebhook("Bot Webhook");
//キャッシュに入れて次回以降使い回す
if (webhook) cacheWebhooks.set(channel.id, webhook);
return webhook;
}
client.on("messageCreate", message => sendMessage(message).catch(err => console.error(err)));
client.login(process.env.BOT_TOKEN).catch(err => {
console.error(err);
process.exit(-1);
});
なお、botが作成したWebhookを通じてメッセージを送信した場合、ニックネームの末尾に「bot」のマークがつく。
完全な偽装は不可能だし、やるべきではない。諦めよう。
#v14
channel.createWebhook("Bot Webhook") => channel.createWebhook({name: "Bot Webhook"})
ref
https://discord.com/channels/391390986770710528/1076965353961308210