创建带按钮的Embed遇TypeError报错,按钮需向两频道发不同消息
问题解决:Discord.js中
embed.addComponents is not a constructor报错 报错信息
TypeError: embed.addComponents is not a constructor at Object.execute (C:\Users\hecto\Desktop\Davey Jones\commands\Onboarding\clockify-request.js:85:5) at Object.execute (C:\Users\hecto\Desktop\Davey Jones\events\interactionCreate.js:18:21) at Client.<anonymous> (C:\Users\hecto\Desktop\Davey Jones\index.js:67:46) at Client.emit (node:events:514:28) at InteractionCreateAction.handle (C:\Users\hecto\Desktop\Davey Jones\node_modules\discord.js\src\client\actions\InteractionCreate.js:97:12) at module.exports [as INTERACTION_CREATE] (C:\Users\hecto\Desktop\Davey Jones\node_modules\discord.js\src\client\websocket\handlers\INTERACTION_CREATE.js:4:36) at WebSocketManager.handlePacket (C:\Users\hecto\Desktop\Davey Jones\node_modules\discord.js\src\client\websocket\WebSocketManager.js:355:31) at WebSocketManager.<anonymous> (C:\Users\hecto\Desktop\Davey Jones\node_modules\discord.js\src\client\websocket\WebSocketManager.js:239:12) at WebSocketManager.emit (C:\Users\hecto\Desktop\Davey Jones\node_modules\@vladfrangu\async_event_emitter\dist\index.cjs:282:31) at WebSocketShard.<anonymous> (C:\Users\hecto\Desktop\Davey Jones\node_modules\@discordjs\ws\dist\index.js:1173:51)
错误原因
在Discord.js v14及以上版本中,Embed对象没有addComponents方法,不能直接给Embed绑定交互组件。按钮这类组件需要封装在ActionRowBuilder中,作为发送消息时的独立参数传递,而非挂载到Embed上。
修正方案
1. 导入必要的Discord.js类
确保代码顶部导入所需构造器:
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js');
2. 分别创建Embed和按钮组件
// 构建Embed内容 const embed = new EmbedBuilder() .setTitle('Clockify权限申请') .setDescription('点击下方按钮提交权限申请,工作人员会尽快处理'); // 构建按钮 const requestButton = new ButtonBuilder() .setCustomId('clockify_submit') // 自定义ID,用于后续识别按钮点击 .setLabel('提交申请') .setStyle(ButtonStyle.Primary); // 按钮样式,可选Primary/Secondary/Success/Danger // 将按钮放入ActionRow(组件必须通过ActionRow包裹) const actionRow = new ActionRowBuilder() .addComponents(requestButton);
3. 发送带Embed和组件的消息
发送时同时传入embeds和components参数:
// 示例:在命令交互中回复消息 await interaction.reply({ embeds: [embed], components: [actionRow] });
4. 监听按钮点击并发送消息到指定频道
在interactionCreate事件中处理按钮交互:
module.exports = { async execute(interaction) { // 非按钮交互直接跳过 if (!interaction.isButton()) return; // 判断点击的是目标按钮 if (interaction.customId === 'clockify_submit') { // 获取目标频道(替换为你的实际频道ID) const logChannel = interaction.guild.channels.cache.get('日志频道ID'); const notifyChannel = interaction.guild.channels.cache.get('通知频道ID'); // 发送不同消息到对应频道 if (logChannel) await logChannel.send(`用户 ${interaction.user.tag} 提交了Clockify权限申请`); if (notifyChannel) await notifyChannel.send(`请处理 ${interaction.user} 的Clockify权限申请`); // 给用户发送临时回复 await interaction.reply({ content: '申请已提交,工作人员会尽快处理!', ephemeral: true // 仅用户自己可见 }); } } };
注意事项
- 替换代码中的频道ID、标题、描述等为你的实际业务内容
- 若使用Discord.js v13版本,类名需调整为
MessageEmbed、MessageActionRow、MessageButton - 按钮的
customId要保证唯一,避免和其他按钮冲突
内容的提问来源于stack exchange,提问作者Hector Souffront
相关产品推荐
相关产品推荐

