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

discord.js:按钮交互时如何获取斜杠命令的字符串选项?

Discord.js中按钮交互时如何获取原斜杠命令的字符串选项?

我用discord.js开发了一个斜杠命令,它接收字符串选项,调用API查询数据后以Embed形式返回结果,回复里还附带了一个刷新按钮用来更新数据。现在的问题是,用户点击按钮触发交互时,我怎么获取当初斜杠命令使用的那个字符串选项?

我试过把字符串选项通过ActionRow Builder传递、设为按钮的customId、甚至放到Embed里,但要么没法正常工作,要么感觉很不规范。想知道能不能通过交互ID拿到对应的原交互实例,进而获取那个字符串选项?

相关代码如下:

async execute(interaction) {
  const search = interaction.options.getString("search");
  const pairs = await getQuery(search);
  const refreshButton = new ButtonBuilder()
    .setCustomId(search)
    .setLabel("Refresh")
    .setStyle(ButtonStyle.Secondary);

  const row = new ActionRowBuilder().addComponents([refreshButton]);
  const embed = makeEmbed(pairs[0]);

  if (pairs.length > 0) {
    interaction.reply({
      embeds: [embed],
      components: [row],
    });
  } else {
    interaction.reply(
      `No results for search term ${search}. Please check your query and try again.`
    );
  }
},

// NEED ACCESS TO THE STRING OPTION search IN THIS FUNCTION
async refresh(interaction) {
  const pairs = await getQuery(interaction.customId);
  const embed = makeEmbed(pairs[0]);

  console.log(interaction.customId);
  if (pairs.length > 0) {
    interaction.update({ embeds: [embed] });
  } else {
    interaction.update(
      `No results for search term ${search}. Please check your query and try again.`
    );
  }
}

解决方案

首先明确:Discord不会保存原斜杠命令的交互选项数据,无法直接通过交互ID获取原交互实例的选项。以下是几种规范可行的实现方式:

1. 结构化Custom ID(最简便规范)

直接将搜索词作为customId存在风险(特殊字符、长度限制),可以给customId加前缀并编码,避免冲突和格式问题:

修改execute中的按钮构建代码:

const refreshButton = new ButtonBuilder()
  // 加前缀区分刷新按钮,对搜索词编码处理特殊字符
  .setCustomId(`refresh_${encodeURIComponent(search)}`)
  .setLabel("Refresh")
  .setStyle(ButtonStyle.Secondary);

在refresh函数中解析提取搜索词:

async refresh(interaction) {
  const [prefix, encodedSearch] = interaction.customId.split('_');
  // 校验确保是目标刷新按钮
  if (prefix !== 'refresh') return;
  
  const search = decodeURIComponent(encodedSearch);
  const pairs = await getQuery(search);
  const embed = makeEmbed(pairs[0]);

  if (pairs.length > 0) {
    interaction.update({ embeds: [embed] });
  } else {
    interaction.update(
      `No results for search term ${search}. Please check your query and try again.`
    );
  }
}

2. 从原消息Embed中提取隐藏信息

如果不想将搜索词暴露在customId中,可以把搜索词存入Embed的隐藏区域(比如footer):

修改execute中的Embed构建:

const embed = makeEmbed(pairs[0])
  // 将搜索词存入footer,用户不会注意到
  .setFooter({ text: `search:${search}` });

在refresh函数中获取原消息并解析:

async refresh(interaction) {
  // 获取原回复消息
  const originalMessage = await interaction.fetchReply();
  const originalEmbed = originalMessage.embeds[0];
  // 从footer提取搜索词
  const search = originalEmbed.footer.text.split(':')[1];
  
  const pairs = await getQuery(search);
  const embed = makeEmbed(pairs[0])
    .setFooter({ text: `search:${search}` }); // 更新后保留标识

  if (pairs.length > 0) {
    interaction.update({ embeds: [embed] });
  } else {
    interaction.update(
      `No results for search term ${search}. Please check your query and try again.`
    );
  }
}

3. 缓存/数据库存储关联数据

如果搜索词过长或需要长期关联,可以用缓存(如Redis)或数据库存储原交互ID与搜索词的映射:

修改execute函数:

async execute(interaction) {
  const search = interaction.options.getString("search");
  // 将原交互ID与搜索词存入缓存,设置过期时间(示例为1小时)
  await cache.set(`interaction_${interaction.id}`, search, 3600);
  
  // 按钮用固定customId即可
  const refreshButton = new ButtonBuilder()
    .setCustomId('refresh_button')
    .setLabel("Refresh")
    .setStyle(ButtonStyle.Secondary);

  // 其余回复代码不变
}

在refresh函数中查询缓存:

async refresh(interaction) {
  // 获取原斜杠命令的交互ID
  const originalInteractionId = interaction.message.interaction.id;
  // 从缓存取出搜索词
  const search = await cache.get(`interaction_${originalInteractionId}`);
  
  if (!search) {
    return interaction.update({ 
      content: "该查询已过期,请重新发起搜索。", 
      components: [] 
    });
  }
  
  const pairs = await getQuery(search);
  const embed = makeEmbed(pairs[0]);

  if (pairs.length > 0) {
    interaction.update({ embeds: [embed] });
  } else {
    interaction.update(
      `No results for search term ${search}. Please check your query and try again.`
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 13:31:01