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

Discord.js v14中如何隐藏Embed并点击按钮后显示?

解决方案:让Embed默认隐藏,仅点击按钮时展示

问题背景

我在命令执行函数中创建了一个Embed,希望仅在点击按钮时显示它。当前功能仅实现一半,问题是Embed默认会显示,且点击按钮时会再次重复显示。想实现Embed默认隐藏,直到按钮被点击才展示;同时由于数据来自API响应且未保存,无法将Embed创建逻辑移至index.js,也不想用数据库。

修改方案

核心思路是不直接发送Embed到消息中,而是将生成Embed所需的API数据(或Embed本身的序列化数据)存入按钮的自定义ID中,点击按钮时再解析数据生成并展示Embed。

1. 修改command.js:不发送Embed,将数据存入按钮

// Call API
let data = await response.json();
// 序列化API返回的关键数据(用encodeURIComponent避免字符冲突)
const serializedInfo = encodeURIComponent(JSON.stringify(data.images.info));

// 创建按钮,自定义ID中加入序列化数据,用|分隔标识与数据
const getGenerationDataButton = new ButtonBuilder()
  .setCustomId(`get_image_generation_data|${serializedInfo}`)
  .setLabel("Get Image Generation Data")
  .setStyle(ButtonStyle.Primary);

const actionRow = new ActionRowBuilder().addComponents(getGenerationDataButton);

// 仅发送文件和按钮,不包含Embed
await interaction.editReply({
  files: files,
  components: [actionRow],
});

2. 修改index.js:解析按钮数据,生成并发送Embed

if (interaction.isButton()) {
  // 拆分自定义ID,分离标识和序列化数据
  const [customId, serializedInfo] = interaction.customId.split('|');
  if (customId === "get_image_generation_data") {
    // 解析数据
    const info = JSON.parse(decodeURIComponent(serializedInfo));
    const fields = Object.entries(info);
    
    // 重新构建Embed
    const embed = new EmbedBuilder()
      .setColor(0x0099ff)
      .setTitle("txt2img")
      .addFields(fields)
      .setTimestamp();

    // 以临时消息形式发送Embed
    await interaction.reply({
      embeds: [embed],
      ephemeral: true,
    });
  }
}

替代方案(复用Embed配置)

如果不想在index.js中重复编写Embed构建逻辑,可以直接序列化整个Embed的配置:

修改command.js

// Call API
let data = await response.json();
const fields = Object.entries(JSON.parse(data.images.info))

// 创建Embed
const embed = new EmbedBuilder()
  .setColor(0x0099ff)
  .setTitle("txt2img")
  .addFields(fields)
  .setTimestamp();

// 序列化Embed为JSON并编码
const serializedEmbed = encodeURIComponent(JSON.stringify(embed.toJSON()));

// 创建按钮
const getGenerationDataButton = new ButtonBuilder()
  .setCustomId(`get_image_generation_data|${serializedEmbed}`)
  .setLabel("Get Image Generation Data")
  .setStyle(ButtonStyle.Primary);

const actionRow = new ActionRowBuilder().addComponents(getGenerationDataButton);

// 仅发送文件和按钮
await interaction.editReply({
  files: files,
  components: [actionRow],
});

修改index.js

if (interaction.isButton()) {
  const [customId, serializedEmbed] = interaction.customId.split('|');
  if (customId === "get_image_generation_data") {
    // 解析并还原Embed
    const embedData = JSON.parse(decodeURIComponent(serializedEmbed));
    const embed = EmbedBuilder.from(embedData);

    await interaction.reply({
      embeds: [embed],
      ephemeral: true,
    });
  }
}

注意事项

  • Discord按钮的自定义ID长度限制为100字符,若序列化后的数据过长,建议优先选择仅序列化API返回的关键数据(而非整个Embed)来缩短长度。
  • 使用encodeURIComponent和decodeURIComponent避免JSON中的特殊字符破坏自定义ID格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 21:05:42