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

Discord.js 特定角色分配后无法发送通知消息问题求解

职位成就通知功能实现方案

现有代码失效原因

  • 触发事件选型错误:当前绑定的messageCreate事件仅在用户发送消息时触发,无法监听用户获得职位角色的动作,用户拿到角色时如果没有发消息,逻辑完全不会执行。
  • 角色发放逻辑错误:代码里的member.roles.cache.get()仅会从本地缓存读取角色对象,没有执行实际的添加角色操作,Discord.js中给成员加角色需要调用member.roles.add()方法。
  • 逻辑判断反向:现有判断是「用户没有目标角色时执行逻辑」,和需求里「用户获得角色时触发成就通知」的触发条件完全不符。
  • 冗余无效代码:定义了公告频道变量canal、引入了wait延迟方法,但全程没有调用,属于无效代码。
  • API调用错误:messageCreate事件中获取发消息用户应该用message.author,原代码写的message.user是不存在的属性,运行会直接报错。

正确实现代码

核心逻辑改用guildMemberUpdate事件监听成员角色变更,精准捕捉用户获得职位的时机,再触发通知逻辑,代码如下:

const client = require("../index.js");

// 监听服务器成员信息变更(角色增减、昵称修改等操作都会触发该事件)
client.on('guildMemberUpdate', async (oldMember, newMember) => {
  // 配置参数,替换为你服务器实际的ID值
  const TARGET_PS_ROLE_ID = "980553630782464068"; // PlayStation职位对应的角色ID
  const ACHIEVEMENT_CHANNEL_ID = "980553632116269080"; // 成就公告频道ID

  // 校验是否为刚获得目标角色的场景:更新前无角色,更新后有角色
  const hadRole = oldMember.roles.cache.has(TARGET_PS_ROLE_ID);
  const gotRole = newMember.roles.cache.has(TARGET_PS_ROLE_ID);
  if (hadRole || !gotRole) return;

  try {
    // 给用户发私信解锁通知
    await newMember.send(`${client.emoji.success} 恭喜你解锁PlayStation职位成就,对应身份组已自动到账!`);
    
    // 需要在频道发全服成就公告就放开下面的注释
    // const announceChannel = newMember.guild.channels.cache.get(ACHIEVEMENT_CHANNEL_ID);
    // if (announceChannel) {
    //   await announceChannel.send(`🎉 恭喜 ${newMember.user.tag} 成功解锁PlayStation职位成就!`);
    // }
  } catch (error) {
    // 捕获用户关闭私信等异常,避免程序崩溃
    console.log(`向用户${newMember.user.tag}发送成就通知失败:`, error);
  }
});

// 可选兜底逻辑:用户发消息时自动检测资格补发角色,不需要可以删除
client.on('messageCreate', async message => {
  // 跳过机器人消息、非服务器消息
  if (message.author.bot || !message.guild) return;
  
  const TARGET_PS_ROLE_ID = "980553630782464068";
  // 强制拉取最新的成员信息,避免缓存导致判断不准
  const member = await message.guild.members.fetch({
    user: message.author.id,
    force: true 
  });

  // 替换成你自己的资格判断规则,比如积分达标、完成指定任务等
  const matchRoleRequirement = true;
  if (matchRoleRequirement && !member.roles.cache.has(TARGET_PS_ROLE_ID)) {
    await member.roles.add(TARGET_PS_ROLE_ID);
    // 角色发放成功后,上面的角色更新监听会自动触发成就通知逻辑,这里不用重复发
  }
})

部署注意事项

  • 需要给机器人账号开启「管理角色」权限,且机器人在服务器的最高角色层级,必须高于你要发放的职位角色,否则会出现加角色无权限的报错。
  • 如果要做多个职位对应多个成就的逻辑,只需要把角色ID、成就名称、通知内容做成键值对映射表遍历判断即可,不需要为每个职位单独写监听逻辑。
  • 参考的卡片式成就通知效果,可以用Discord.js的MessageEmbed嵌入消息实现,搭配成就封面图、解锁条件、奖励说明字段,就能做出和参考样式一致的通知卡片。

内容的提问来源于stack exchange,提问作者Alguém Top

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 06:18:22