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

Discord.js如何在InteractionCreate事件中传参,实现按钮触发注册命令传递赛事名称

你要的功能完全可以实现,以下是具体修改方案:

方案1:按钮ID携带参数(推荐,实现简单)

Discord按钮的customId支持自定义字符串,你可以直接把赛事名称编码后拼接在ID中,点击触发交互时拆分ID即可拿到对应参数。

第一步:修改VIEW命令中按钮的customId配置

找到VIEW命令内创建各类按钮的代码段,将固定的customId改为「标识前缀+赛事名」的动态格式,示例如下:

// 注册按钮修改
const registerBTN = new Discord.MessageButton()
// 用下划线作为分隔符,建议选择不会出现在赛事名称中的字符作为分隔符
.setCustomId(`registerBTN_${encodeURIComponent(tournament.name)}`)
.setLabel('Register')
.setStyle('PRIMARY');

// 其他需要关联赛事的按钮(取消注册、管理、删除按钮)都按这个规则修改customId
const unregisterBTN = new Discord.MessageButton()
.setCustomId(`unregisterBTN_${encodeURIComponent(tournament.name)}`)
.setLabel('Unregister')
.setStyle('DANGER');

用encodeURIComponent编码赛事名是为了避免赛事名里的特殊字符(如下划线、空格)影响后续拆分逻辑。

第二步:修改InteractionCreate事件代码

修正原有代码的错误,拆分customId获取赛事参数:

const BaseEvent = require('../utils/structures/BaseEvent');

module.exports = class InteractionCreate extends BaseEvent {
  constructor() {
    super('interactionCreate');
  }
  
  async run(client, interaction) {
    if (!interaction.isButton() && !interaction.isSelectMenu()) return;
    // 拆分customId,获取操作类型和编码后的赛事名
    const [action, encodedTournamentName] = interaction.customId.split('_');
    const tournamentName = decodeURIComponent(encodedTournamentName);
    switch (action) {
      case 'registerBTN':
        const cmd = client.commands.get('register');
        // interaction.message就是按钮所在的原消息,直接传给run方法的message参数
        await cmd.run(client, interaction.message, [tournamentName]);
        // 如果你的REGISTER命令需要给点击按钮的用户返回提示,建议用interaction.reply,避免按钮交互超时
      break;
      // 其他按钮的逻辑同理,根据action判断后执行对应命令即可
    }
  }
}

方案2:全局映射存储(适合参数过长场景)

如果需要传递的参数很多,超出了customId最多100字符的限制,可以用客户端全局对象存储消息ID和赛事信息的映射:

  1. 在VIEW命令发送完带按钮的消息后添加存储逻辑:
const sentMsg = await message.channel.send({embeds: [embed], components: [row]});
// 初始化全局映射表
client.tournamentMsgMap = client.tournamentMsgMap || new Map();
// 关联消息ID和赛事名
client.tournamentMsgMap.set(sentMsg.id, tournament.name);
  1. 在InteractionCreate事件中通过消息ID获取赛事名:
case 'registerBTN':
  const tournamentName = client.tournamentMsgMap.get(interaction.message.id);
  const cmd = client.commands.get('register');
  await cmd.run(client, interaction.message, [tournamentName]);
break;

如果需要机器人重启后映射依然有效,可以把映射关系存入数据库,关联消息ID和赛事信息即可。

注意:如果你的REGISTER命令需要获取点击按钮的用户身份,原有message.author会返回调用VIEW命令的用户,而非点击按钮的用户,你可以修改REGISTER命令的run方法入参,增加interaction参数,或者直接把interaction.user作为补充参数传入即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 20:42:02