You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DiscordJS 如何根据选中的反应复制Embed消息发送到其他聊天频道

Discord.js v14 实现反应触发Embed转发的方案

前置准备

  • 确保你的Bot已经开启开发者门户中Privileged Gateway Intents下的三个开关:Server Members Intent、Message Content Intent、Guild Message Reactions Intent
  • 确保Bot拥有原消息所在频道的Send Messages、Embed Links、Read Message History权限,目标转发频道的Send Messages、Embed Links权限

核心逻辑实现

1. 注册事件监听与过滤无效触发

首先监听messageReactionAdd事件,过滤掉Bot自身触发的反应、非目标三个反应的操作,避免误触发:

const { Client, GatewayIntentBits, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js');
const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.GuildMessageReactions,
    GatewayIntentBits.MessageContent,
    GatewayIntentBits.GuildMembers
  ]
});

// 配置项:替换为你实际的三个目标反应emoji、转发目标频道ID、Bot Token
const TARGET_EMOJIS = ['✅', '❌', '⚠️']; 
const FORWARD_CHANNEL_ID = '替换为目标转发频道ID';
const BOT_TOKEN = '替换为你的Bot Token';

client.on('messageReactionAdd', async (reaction, user) => {
  // 忽略Bot自身触发的反应
  if (user.bot) return;
  // 忽略非目标emoji的反应
  if (!TARGET_EMOJIS.includes(reaction.emoji.name)) return;
  // 处理部分加载的消息/反应
  if (reaction.partial) await reaction.fetch();
  if (reaction.message.partial) await reaction.message.fetch();
  // 忽略没有Embed的消息
  if (!reaction.message.embeds.length) return;
  // 可选:移除用户添加的反应,避免重复触发
  await reaction.users.remove(user.id);

2. 生成确认交互弹窗

用按钮组件生成确认交互,发送给触发反应的用户:

// 构造确认/取消按钮
  const confirmBtn = new ButtonBuilder()
    .setCustomId(`confirm_forward_${reaction.message.id}_${user.id}`)
    .setLabel('确认转发')
    .setStyle(ButtonStyle.Success);
  const cancelBtn = new ButtonBuilder()
    .setCustomId(`cancel_forward_${reaction.message.id}_${user.id}`)
    .setLabel('取消')
    .setStyle(ButtonStyle.Danger);
  const row = new ActionRowBuilder().addComponents(confirmBtn, cancelBtn);

  // 给触发用户发送确认消息,只有触发用户可见
  const confirmMsg = await reaction.message.reply({
    content: `${user}, 确认要将该Embed转发到指定频道吗?`,
    components: [row],
    allowedMentions: { users: [user.id] },
    ephemeral: true
  });
});

3. 监听按钮交互,执行转发逻辑

监听interactionCreate事件,判断用户点击的按钮,执行对应操作:

client.on('interactionCreate', async interaction => {
  if (!interaction.isButton()) return;
  // 匹配转发相关的按钮ID,过滤无关交互
  const idParts = interaction.customId.split('_');
  if (idParts.length !==4 || (idParts[0]!=='confirm' && idParts[0]!=='cancel')) return;
  const [action, _, msgId, triggerUserId] = idParts;
  // 忽略非当前触发用户的点击操作
  if (interaction.user.id !== triggerUserId) {
    return interaction.reply({ content: '你无权操作该确认', ephemeral: true });
  }

  if (action === 'confirm') {
    // 获取原消息的Embed内容
    const originalMsg = await interaction.channel.messages.fetch(msgId);
    const targetEmbeds = originalMsg.embeds;
    // 获取转发目标频道
    const forwardChannel = await client.channels.fetch(FORWARD_CHANNEL_ID);
    // 发送Embed到目标频道
    await forwardChannel.send({ embeds: targetEmbeds });
    // 更新确认消息,移除按钮
    await interaction.update({ content: '✅ 已成功转发Embed', components: [] });
  } else if (action === 'cancel') {
    // 取消操作,更新确认消息移除按钮
    await interaction.update({ content: '❌ 已取消转发操作', components: [] });
  }
});

// 登录Bot
client.login(BOT_TOKEN);

注意事项

  • 如果你的反应是自定义emoji,需要把TARGET_EMOJIS里的内容替换为自定义emoji的ID
  • 如果需要区分不同反应转发到不同频道,可以把TARGET_EMOJIS修改为键值对映射,根据触发的emoji匹配对应的转发频道ID
  • 生产环境建议添加try/catch异常捕获,避免消息/频道不存在等报错导致Bot崩溃

内容的提问来源于stack exchange,提问作者User57

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 22:54:05