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

Discord.js按钮交互:获取消息对象、移除按钮、传参实现方法

Discord.js 单次点击按钮实现方案

核心实现思路

  • 按钮传参不需要额外存储,直接将目标成员ID拼接在按钮的custom_id字段中即可,该字段支持最长100个字符,完全满足单参数传递需求
  • 点击按钮后直接编辑触发交互的原消息,将components字段设为空数组即可移除所有按钮,实现仅能点击一次的效果
  • 你当前直接传入原始API结构的组件写法完全可用,和官方Builder封装写法的功能没有区别,不需要强制重构

步骤1:调整消息发送逻辑(messages.ts)

修改按钮的custom_id字段,将发送消息时绑定的目标成员ID拼接进去,方便后续交互时解析:

import DiscordJS from 'discord.js'

const botChannelID = '000000';
const pointsNeeded = 400;

export function postEnoughActivityMessage(guildMember: DiscordJS.GuildMember) {
    const targetChannel = guildMember.guild.channels.cache.find(
        (x: DiscordJS.GuildBasedChannel) => x.id === botChannelID
    ) as DiscordJS.TextChannel;

    targetChannel.send({
        tts: false,
        components: [
            {
                type: 1,
                components: [
                    {
                        style: 3,
                        label: `Zum Member Befördern`,
                        // 格式:操作前缀_目标成员ID,下划线做分隔符方便后续拆分
                        custom_id: `addToMember_${guildMember.id}`,
                        disabled: false,
                        type: 2
                    }
                ]
            }
        ],
        embeds: [
            {
                type: "rich",
                title: `<:tada:988855833809002546> Neue Aktivitätsstufe erreicht! <:tada:988855833809002546>`,
                description: `**${guildMember.displayName}** hat **${pointsNeeded}** Punkte gesammelt und somit die Chance verdient in den Member Rang gehoben zu werden.`,
                color: 0x3b4ea3,
                thumbnail: {
                    url: guildMember.displayAvatarURL(),
                    height: 0,
                    width: 0
                }
            }
        ]
    });
}

步骤2:调整按钮交互监听逻辑(app.ts)

在交互回调中解析custom_id拿到目标成员ID,处理完业务逻辑后清空消息上的按钮组件:

client.on('interactionCreate', async interaction => {
    if (!interaction.isButton()) return;

    // 拆分custom_id拿到操作类型和目标成员ID
    const [actionType, targetMemberId] = interaction.customId.split('_');
    if (actionType !== 'addToMember') return;

    // 必须在3秒内响应交互,否则Discord会报交互失败错误
    await interaction.deferUpdate();

    // 从服务器成员缓存中取出发送消息时绑定的目标成员对象
    const targetGuildMember = interaction.guild?.members.cache.get(targetMemberId);
    if (!targetGuildMember) {
        await interaction.followUp({
            content: '目标成员不存在,操作失败',
            ephemeral: true
        });
        return;
    }

    // 此处编写按钮点击后的业务逻辑,比如给目标成员加正式成员角色
    console.log('待晋升成员信息:', targetGuildMember);

    // 编辑原消息,清空所有组件,按钮会被直接移除,后续无法再点击
    await interaction.editReply({
        components: []
    });
});

补充说明

  • 如果不需要完全移除按钮,只想让按钮点击后置灰不可用,可以将按钮的disabled字段设为true后回传到components字段,不需要传空数组
  • 如果需要传递更多参数,可以将参数序列化为短字符串后拼接在custom_id中,注意总长度不要超过100字符限制即可
  • 所有交互相关的异步操作都需要加await,避免时序问题导致响应超时

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 19:21:31