Discord.js 添加角色时触发INVALID_TYPE与undefined.find错误
报错原因
两个报错都是代码缺少空值校验、取值逻辑错误导致的:
TypeError: Cannot read properties of undefined (reading 'find'):presenceUpdate事件触发时存在边缘场景,newPresence.member、newPresence.activities可能为undefined,直接读取嵌套属性时会触发空值引用错误;另外固定取activities[0]作为自定义状态的逻辑有问题,用户活动列表首位可能是游戏、音乐等非自定义状态活动,这类活动没有state属性,访问时也会触发undefined错误。INVALID_TYPE类型错误:通过角色ID获取角色时,如果角色不存在(ID错误、缓存未加载),role变量值为undefined,把undefined传入roles.add()/roles.remove()方法时,就会触发该类型校验错误——该方法只接受Role对象、角色ID(Snowflake)、或上述类型的数组/集合。
修复后代码
修复逻辑包含空值兜底、正确查找自定义状态、避免重复API调用、错误捕获:
client.on('presenceUpdate', async (oldPresence, newPresence) => { // 边缘场景空值兜底,避免访问undefined属性 if (!newPresence?.member || !newPresence.guild) return; const TARGET_ROLE_ID = "984959434256179221"; const targetRole = newPresence.guild.roles.cache.get(TARGET_ROLE_ID); // 目标角色不存在直接终止逻辑 if (!targetRole) return; const member = newPresence.member; // 从所有活动中筛选出用户的自定义状态,而非固定取第一个活动 const customStatus = newPresence.activities.find(activity => activity.type === "CUSTOM_STATUS"); // 检查自定义状态文本是否包含指定邀请链接 const hasTargetInvite = customStatus?.state?.includes(".gg/s7trZ2NF") || customStatus?.state?.includes("discord.gg/s7trZ2NF"); try { if (hasTargetInvite) { // 用户未持有目标角色时才添加,避免重复调用接口 if (!member.roles.cache.has(TARGET_ROLE_ID)) { await member.roles.add(targetRole); } } else { // 用户持有目标角色时才移除 if (member.roles.cache.has(TARGET_ROLE_ID)) { await member.roles.remove(targetRole); } } } catch (error) { // 捕获权限不足等接口错误,避免机器人进程崩溃 console.error("更新成员邀请角色失败:", error); } })
前置配置检查
代码能正常运行还需要确认两个配置:
- 打开Discord开发者门户,在你的Bot设置页面的「Privileged Gateway Intents」板块,开启Presence Intent和Server Members Intent两个权限开关,否则机器人无法接收成员状态更新事件、拿不到成员数据。
- 确保机器人在服务器内的角色排序,在你要分配的目标角色的上方,且机器人拥有「管理角色」权限,否则会触发接口权限报错。
内容的提问来源于stack exchange,提问作者Beamed Lmao
相关产品推荐
相关产品推荐

