Node.js Discord机器人离开服务器时缺失告别文本消息求助
Discord机器人问题排查与修复
问题描述
在MacOS Monterey系统上使用Node.js 16.17.0开发Discord机器人,已实现用户进出服务器的问候/告别功能:
- 用户加入时,机器人可正常发送欢迎文本消息及带用户头像的嵌入消息
- 使用小号离开服务器时,机器人仅发送头像嵌入消息,告别文本消息缺失
触发的错误信息
尝试在intents中添加GUILD_PRESENCES时,出现以下BitField无效错误:
/Users/saisonxiang/genshi/node_modules/discord.js/src/util/BitField.js:168 throw new RangeError(ErrorCodes.BitFieldInvalid, bit); ^ RangeError [BitFieldInvalid]: Invalid bitfield flag or number: undefined. at Function.resolve (/Users/saisonxiang/genshi/node_modules/discord.js/src/util/BitField.js:168:11) at /Users/saisonxiang/genshi/node_modules/discord.js/src/util/BitField.js:163:54 at Array.map (<anonymous>) at Function.resolve (/Users/saisonxiang/genshi/node_modules/discord.js/src/util/BitField.js:163:40) at Client._validateOptions (/Users/saisonxiang/genshi/node_modules/discord.js/src/client/Client.js:482:41) at new Client (/Users/saisonxiang/genshi/node_modules/discord.js/src/client/Client.js:78:10) at Object.<anonymous> (/Users/saisonxiang/genshi/index7.js:20:16) at Module._compile (node:internal/modules/cjs/loader:1126:14) at Object.Module._extensions..js (node:internal/modules/cjs/loader:1180:10) at Module.load (node:internal/modules/cjs/loader:1004:32) { code: 'BitFieldInvalid' }
已尝试的无效解决方法
- 将告别消息移出
ready事件回调 - 删除并重装
node_modules文件夹 - 删除重装Node.js(已更新版本)
当前可运行但存在问题的代码
// Import Discord.js const { Client, Collection, GatewayIntentBits, Partials, EmbedBuilder } = require('discord.js'); const { token } = require('./config.json'); // I like importing the intents and partials this way, just to make things a little more visible. // But the main things we're importing here are the Guild, and GuildMembers [PLURAL] const { Guilds, GuildMembers, MessageContent, GuildMessages, GUILD_PRESENCES } = GatewayIntentBits; // And here, we're importing the GuildMember [SINGULAR] for our Partials const { User, Message, Channel, GuildMember } = Partials; // Create Discord Client const client = new Client({ intents: [ Guilds, GuildMembers, // IMPORTANT GuildMessages, MessageContent, ], partials: [ User, Channel, Message, GuildMember, // IMPORTANT ], }); // When the client is ready, run this code (only once) client.once('ready', () => { // Adding the GuildMembers to our intents, and GuildMember to our partials allows for us to // receive the info we need for a welcome message; ei. when a member joins // And lastly, when a member joins. I noticed you had the event inside your ready event, // but it needs to be outside the ready so be sure to double check that :) client.on('guildMemberAdd', async (GuildMember) => { console.log(GuildMember); // View the member data await GuildMember.guild.channels.cache.get('1010768161349587035').send(`Well... ${GuildMember.user.username + "#" + GuildMember.user.discriminator} joined the server so I guess we will be okay`); }); client.on('guildMemberAdd', guildMember =>{ const embed7 = new EmbedBuilder() .setAuthor({name: `${guildMember.user.username}`, iconURL: guildMember.displayAvatarURL({dyanmic: true})}) .setThumbnail(guildMember.displayAvatarURL({dynamic: true})) guildMember.guild.channels.cache.get('1010768161349587035').send({embeds: [embed7]}) }); client.on('GuildMemberRemove', async (GuildMember) => { console.log(GuildMember); // View the member data await GuildMember.guild.channels.cache.get('1010768161349587035').send(`Apparently ${GuildMember.user.username + "#" + GuildMember.user.discriminator} can't handle our bullshit anymore and decided to leave the server. They will be missed.`); }); client.on('guildMemberRemove', guildMember => { const embed8 = new EmbedBuilder() .setAuthor({name: guildMember.user.username, iconURL: guildMember.displayAvatarURL({dyanmic: true})}) .setThumbnail(guildMember.displayAvatarURL({dynamic: true})) guildMember.guild.channels.cache.get('1010768161349587035').send({embeds: [embed8]}) }); }) console.log('(。··)_且'); // Login to Discord with your client's token client.login(token);
修复方案
1. 修正事件名大小写错误
Discord.js的事件名采用小写开头的驼峰式命名,你之前绑定的GuildMemberRemove是错误的,应该改为guildMemberRemove——这就是告别文本消息不触发的核心原因,事件名写错导致回调根本不会执行。
2. 修正GUILD_PRESENCES的导入名称
Discord.js v14中,GatewayIntentBits下的常量是驼峰式命名,正确的名称是GuildPresences而非全大写的GUILD_PRESENCES。如果需要使用该意图,还要在Discord开发者后台开启对应的特权网关意图(Presence Intent)。
3. 将事件监听移到ready事件外部
不要在client.once('ready')的回调里绑定事件监听,否则客户端重新连接时会重复绑定事件,导致重复触发。所有事件监听应该直接放在全局作用域下。
4. 合并重复的事件监听
同一个事件(如guildMemberAdd、guildMemberRemove)绑定了两次,可以合并为一个回调,避免重复发送消息和潜在的逻辑冲突。
修复后的完整代码
// Import Discord.js const { Client, GatewayIntentBits, Partials, EmbedBuilder } = require('discord.js'); const { token } = require('./config.json'); // 修正意图常量的命名(驼峰式) const { Guilds, GuildMembers, MessageContent, GuildMessages, GuildPresences } = GatewayIntentBits; const { User, Channel, GuildMember } = Partials; // Create Discord Client const client = new Client({ intents: [ Guilds, GuildMembers, GuildMessages, MessageContent, // 如果需要Presence意图,取消注释并在开发者后台开启特权意图 // GuildPresences ], partials: [ User, Channel, GuildMember, ], }); // 用户加入事件:合并文本与嵌入消息的发送逻辑 client.on('guildMemberAdd', async (guildMember) => { console.log(guildMember); const welcomeChannel = guildMember.guild.channels.cache.get('1010768161349587035'); if (!welcomeChannel) return; // 发送欢迎文本 await welcomeChannel.send(`Well... ${guildMember.user.username}#${guildMember.user.discriminator} joined the server so I guess we will be okay`); // 发送欢迎嵌入 const welcomeEmbed = new EmbedBuilder() .setAuthor({ name: guildMember.user.username, iconURL: guildMember.displayAvatarURL({ dynamic: true }) }) .setThumbnail(guildMember.displayAvatarURL({ dynamic: true })); welcomeChannel.send({ embeds: [welcomeEmbed] }); }); // 用户离开事件:修正事件名,合并文本与嵌入消息的发送逻辑 client.on('guildMemberRemove', async (guildMember) => { console.log(guildMember); const goodbyeChannel = guildMember.guild.channels.cache.get('1010768161349587035'); if (!goodbyeChannel) return; // 发送告别文本 await goodbyeChannel.send(`Apparently ${guildMember.user.username}#${guildMember.user.discriminator} can't handle our bullshit anymore and decided to leave the server. They will be missed.`); // 发送告别嵌入 const goodbyeEmbed = new EmbedBuilder() .setAuthor({ name: guildMember.user.username, iconURL: guildMember.displayAvatarURL({ dynamic: true }) }) .setThumbnail(guildMember.displayAvatarURL({ dynamic: true })); goodbyeChannel.send({ embeds: [goodbyeEmbed] }); }); // 客户端就绪事件 client.once('ready', () => { console.log('(。··)_且'); }); // 登录机器人 client.login(token);
内容的提问来源于stack exchange,提问作者TOKI
相关产品推荐
相关产品推荐

