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

discord.js向被踢用户发消息报50007错误排查方案

报错现象

使用discord.js开发Discord机器人,实现「用户被踢出服务器后机器人自动向其发送私信」功能时,触发如下报错:

DiscordAPIError: Cannot send messages to this user at RequestHandler.execute (C:\Users\Shushan\Desktop\discordbot\node_modules\discord.js\src\rest\RequestHandler.js:154:13)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async RequestHandler.push (C:\Users\Shushan\Desktop\discordbot\node_modules\discord.js\src\rest\RequestHandler.js:39:14) {
  method: 'post',
  path: '/channels/988657628710334484/messages',
  code: 50007,
  httpStatus: 403
}

对应业务代码为kick.js,原始代码如下:

const Discord = require('discord.js');

const client = new Discord.Client({ intents: 
  [Discord.Intents.FLAGS.GUILDS, Discord.Intents.FLAGS.GUILD_MESSAGES] });

const prefix = 'plz ';


const fs = require('fs');
client.commands = new Discord.Collection();

module.exports = {
    name: 'kick',
    description: 'This Command Kicks People!',
    execute(message, args){
        const member = message.mentions.users.first();
        if(member){
            const memberTarget = message.guild.members.cache.get(member.id);
            const f = String(memberTarget);
            newStr = f.replace('@', '');
            newStrTwo = newStr.replace('<', '');
            newStrThree = newStrTwo.replace('>', '');
            client.users.fetch(newStrThree).then((user) => {
                try {
                    user.send("txt");   ;
                } catch (err){
                    console.log("err");
                }
            })
            memberTarget.kick();
            message.channel.send("This User Was Kicked Successfully.");
        }else{
            message.channel.send("This User Couldn't Be Kicked.");
        }
    }
}


client.login('TOKEN');
报错原因
  • 执行顺序逻辑错误:user.send()是异步网络请求,代码没有等待请求完成就直接执行了memberTarget.kick(),多数场景下踢人操作会比私信请求先执行完成。用户被踢出服务器后,和机器人不再有共同服务器关系,默认权限下机器人无法向非共同服务器的用户发送私信,直接触发403 50007错误。
  • 异步错误捕获失效:user.send()返回Promise对象,属于异步操作,普通同步try/catch无法捕获异步抛出的错误,导致发送失败的错误直接穿透到进程层抛出。
  • 冗余逻辑易引发异常:通过字符串替换从成员tag中提取用户ID的写法完全多余,discord.js的成员对象本身就带有id属性可以直接获取用户ID,字符串替换存在匹配失败、取错ID的风险。同时在命令文件中重复初始化Discord Client实例,会导致客户端状态不一致,进一步提升请求异常概率。
  • 缺少场景兜底判断:即使用户还在服务器内,也存在用户关闭「允许服务器成员发送私信」开关、用户已拉黑机器人等无法发送私信的场景,代码没有对这类场景做兼容处理。
修复方案
  1. 调整执行顺序:将execute方法改为异步函数,等待私信发送流程(无论成功失败)走完后,再执行踢人操作。
  2. 修正错误捕获逻辑:使用async/await搭配try/catch,或者直接给Promise加.catch()处理异步发送失败的场景,避免报错中断程序。
  3. 删除冗余逻辑:去掉字符串替换取ID、命令文件内重复初始化Client的无效代码,直接通过成员对象获取用户实例。
  4. 增加兜底逻辑:私信发送失败时只打印日志,不中断后续踢人流程。

修正后的kick.js参考代码:

module.exports = {
    name: 'kick',
    description: 'This Command Kicks People!',
    async execute(message, args) {
        const targetUser = message.mentions.users.first();
        if (!targetUser) {
            return message.channel.send("This User Couldn't Be Kicked.");
        }
        const memberTarget = message.guild.members.cache.get(targetUser.id);
        // 先执行私信发送,捕获所有可能的发送失败场景
        try {
            await targetUser.send("你已被移出当前服务器");
        } catch (err) {
            console.log(`向用户${targetUser.tag}发送私信失败,错误码:${err.code}`);
        }
        // 私信流程结束后再执行踢人
        await memberTarget.kick();
        message.channel.send("This User Was Kicked Successfully.");
    }
}

额外注意:需要在机器人主程序初始化Client时,开启对应权限意图,同时确保机器人在对应服务器拥有踢人权限、机器人隐私设置中允许向共同服务器成员发送私信。

内容的提问来源于stack exchange,提问作者Shushan Arora

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 17:51:23