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

NodeJS开发的Discord Bot昵称设置偶发失败问题求助

Discord Bot昵称设置偶发失败问题排查与解决

问题描述

使用Node.js开发的Discord Bot,除昵称设置功能外其余功能正常。用户提交Modal后,昵称有时能按规则修改成功,但多数时候失败。Bot已配置管理员权限,需排查代码错误或服务器设置导致的问题,相关代码如下:

client.on('interactionCreate', async (interaction) =>
{ 
    try {
        if(interaction.isButton()) //Every Button Pressed
            if(interaction.customId == process.env.FIRST_ROLE) 
            {
                const role = interaction.guild.roles.cache.get(process.env.FIRST_ROLE)
        
                if(!role) //a
                {
                    return;
                }
        
                //Modal Part
                const modal = new ModalBuilder(
                    {
                        customId: `rolePMSetModal-${interaction.user.id}`,
                        title: 'Informações',
                    });
                
                const nameInput = new TextInputBuilder(
                    {
                        customId: 'nameInput',
                        label: process.env.FIRST_INPUT_TEXT,
                        style: TextInputStyle.Short,
                    });

                const idInput = new TextInputBuilder(
                    {
                        customId: 'idInput',
                        label: process.env.SECOND_INPUT_TEXT,
                        style: TextInputStyle.Short,
                    });

                const firstActionRow = new ActionRowBuilder().addComponents(nameInput);
                const secondActionRow =  new ActionRowBuilder().addComponents(idInput);

                modal.addComponents(firstActionRow, secondActionRow);

                await interaction.showModal(modal)         
            } 
        
            if(interaction.customId == process.env.SECOND_ROLE) //Butoes De Selecionar Set
            {
                const role = interaction.guild.roles.cache.get(process.env.SECOND_ROLE)
        
                if(!role) //s
                {
                    return;
                }
        
                //Modal
                const modal = new ModalBuilder(
                    {
                        customId: `roleExercitoSetModal-${interaction.user.id}`,
                        title: 'Informações',
                    });
                
                const nameInput = new TextInputBuilder(
                    {
                        customId: 'nameInput',
                        label: process.env.FIRST_INPUT_TEXT,
                        style: TextInputStyle.Short,
                    });

                const idInput = new TextInputBuilder(
                    {
                        customId: 'idInput',
                        label: process.env.SECOND_INPUT_TEXT,
                        style: TextInputStyle.Short,
                    });

                const firstActionRow = new ActionRowBuilder().addComponents(nameInput);
                const secondActionRow =  new ActionRowBuilder().addComponents(idInput);

                modal.addComponents(firstActionRow, secondActionRow);

                await interaction.showModal(modal)
            }      

        if(interaction.isModalSubmit)
        {
            if(interaction.customId == `roleExercitoSetModal-${interaction.user.id}`)
            {
                const role = interaction.guild.roles.cache.get(process.env.SECOND_ROLE)
                const nameValue = interaction.fields.getTextInputValue('nameInput')
                const idValue = interaction.fields.getTextInputValue('idInput')
                if(Number.isInteger(idValue)) return;
                if(nameValue.length > 12) return;
                try {
                    interaction.guild.members.cache.get(interaction.user.id).setNickname(`[AL SD | EB] ${nameValue} | ${idValue}`).catch(error => {console.log('There is a error to change nickname!')});    
                    interaction.member.roles.add(process.env.SECOND_ROLE);
                    interaction.member.roles.add(process.env.MAIN_ROLE);
                    interaction.guild.channels.cache.get(process.env.LOG_CHANNEL).send(`Usuario: ${interaction.user}, Selecionou Uma Guarnição...\nGuarnição: ${role}\nId: **${idValue}**\nNome: **${nameValue}**`); //Log
                    const replyMsg = interaction.reply("```Usuario Setado!```");
                    if(replyMsg){
                        interaction.deleteReply(replyMsg); 
                    } else {
                        console.log('Nao foi possivel Deletar A Mensagem.')
                    }
                } catch (error) {
                    console.log(error);
                }    
            }

            if(interaction.customId == `rolePMSetModal-${interaction.user.id}`)
            {
                const role = interaction.guild.roles.cache.get(process.env.FIRST_ROLE)
                const nameValue = interaction.fields.getTextInputValue('nameInput')
                const idValue = interaction.fields.getTextInputValue('idInput')
                if(Number.isInteger(idValue)) return;
                if(nameValue.length > 12) return;
                try {
                    interaction.guild.members.cache.get(interaction.user.id).displayName.se(`[ALN | PMA] ${nameValue} | ${idValue}`).catch(error => {console.log('There is a error to change nickname!')});     
                    interaction.member.roles.add(process.env.FIRST_ROLE);
                    interaction.member.roles.add(process.env.MAIN_ROLE);
                    interaction.guild.channels.cache.get(process.env.LOG_CHANNEL).send(`Usuario: ${interaction.user}, Selecionou Uma Guarnição...\nGuarnição: ${role}\nId: **${idValue}**\nNome: **${nameValue}**`); //Log
                    const replyMsg = interaction.reply("```Usuario Setado!```");
                    if(replyMsg){
                        interaction.deleteReply(replyMsg); 
                    } else {
                        console.log('Nao foi possivel Deletar A Mensagem.')
                    }
                } catch (error) {
                    console.log(error);
                }    
            }
        }
    } catch (error) {
        console.log(error);
    }
})

核心问题分析

  • 模态提交判断错误:代码中用if(interaction.isModalSubmit)(属性访问)而非if(interaction.isModalSubmit())(方法调用),导致模态提交逻辑多数时候完全不执行,只有意外场景才可能触发。
  • 成员缓存不可靠:依赖interaction.guild.members.cache.get()获取成员,Discord缓存不会实时包含所有成员,大服务器中用户大概率不在缓存内,直接导致setNickname调用失败。
  • 拼写错误:rolePMSetModal逻辑中错误调用displayName.se(),正确方法应为setNickname(),直接导致该分支昵称修改完全失效。
  • 异步操作未等待:修改昵称、添加角色、回复交互等异步操作未加await,导致操作顺序混乱,错误无法被捕获,且interaction.reply()返回Promise而非消息实例,后续deleteReply必然失败。
  • 输入验证失效:用Number.isInteger(idValue)验证字符串类型的ID,该方法对字符串永远返回false,验证逻辑完全无效。

解决方案

1. 修复模态提交判断

将模态提交判断改为方法调用:

if(interaction.isModalSubmit())

2. 改用可靠的成员获取方式

直接使用交互自带的interaction.member,无需依赖缓存:

await interaction.member.setNickname(`[AL SD | EB] ${nameValue} | ${idValue}`)

3. 修复拼写错误

将displayName.se()改为正确的setNickname():

await interaction.member.setNickname(`[ALN | PMA] ${nameValue} | ${idValue}`)

4. 统一处理异步操作

所有异步API调用添加await,确保操作顺序正确并捕获错误:

try {
    // 修改昵称
    await interaction.member.setNickname(`[AL SD | EB] ${nameValue} | ${idValue}`);
    // 批量添加角色
    await interaction.member.roles.add([process.env.SECOND_ROLE, process.env.MAIN_ROLE]);
    // 发送日志
    await interaction.guild.channels.cache.get(process.env.LOG_CHANNEL).send(`Usuario: ${interaction.user}, Selecionou Uma Guarnição...\nGuarnição: ${role}\nId: **${idValue}**\nNome: **${nameValue}**`);
    // 回复并延迟删除
    const replyMsg = await interaction.reply({ content: "```Usuario Setado!```", fetchReply: true });
    setTimeout(async () => {
        await interaction.deleteReply(replyMsg);
    }, 3000);
} catch (error) {
    console.error('操作出错:', error);
    await interaction.reply({ content: '设置失败,请联系管理员', ephemeral: true });
}

5. 修正输入验证逻辑

将字符串ID转为数字后验证:

const idNum = parseInt(idValue, 10);
if(isNaN(idNum)) {
    await interaction.reply({ content: 'ID必须是数字', ephemeral: true });
    return;
}
if(nameValue.length > 12) {
    await interaction.reply({ content: '名称长度不能超过12字符', ephemeral: true });
    return;
}

6. 完善错误日志

将错误打印改为console.error,输出详细错误信息:

.catch(error => {
    console.error('昵称修改失败详情:', error);
});

服务器设置排查

若代码修复后仍有问题,检查以下配置:

  • Bot角色位置需高于所有需修改昵称的用户角色,Discord不允许修改角色层级更高的用户昵称。
  • 检查服务器「会员特权」设置,是否存在用户被标记为「无法修改昵称」。
  • 确认Bot的「管理员」权限已启用,且未被服务器权限规则限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 23:55:01