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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:06:30