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
相关产品推荐
相关产品推荐

