You need to enable JavaScript to run this app. Discord.js 编写!message指令向提及用户发私信时出现undefined属性读取报错
优惠活动
大模型
产品
解决方案
定价
更多

Discord.js 编写!message指令向提及用户发私信时出现undefined属性读取报错

Discord.js 自定义私信指令报错修正

报错核心原因

逐行对应现有代码的逻辑问题,完全匹配控制台报错的触发链路:

  • 变量覆盖冲突:在分支内用var message = args[2]直接覆盖了外层传入的Discord消息对象,后续代码里调用message.author时,实际拿到的是args[2]截取的字符串片段,字符串本身不存在author属性,读取嵌套属性author.username时就会抛出Cannot read property 'username' of undefined的类型错误
  • 取值逻辑错位:把args[1]赋值给username后直接尝试读取username.id,但args[1]是指令文本拆分出的字符串,本身没有id属性;同时guild.members.fetch()是异步接口,没有做Promise处理,直接链式调用message.send的结构本身就不符合Discord.js的API设计
  • 异步操作无捕获:所有涉及网络请求的API方法都没有加异常捕获,Promise执行失败时就会触发未处理的Promise拒绝警告

修正后可运行代码

注意代码所在的消息事件回调必须声明为async才能正常使用异步等待逻辑:

client.on('messageCreate', async (message) => {
  // 跳过机器人发送的消息,避免逻辑死循环
  if (message.author.bot) return;
  const args = message.content.trim().split(/ +/g);
  const cmd = args.shift().toLowerCase();

  if (cmd === '!message') {
    // 未检测到提及用户时提示用法
    if (!message.mentions.users.size) {
      return message.channel.send("```用法示例: !message @目标用户 要发送的内容```");
    }
    // 直接从提及列表取第一个被@的服务器成员
    const targetMember = message.mentions.members.first();
    // 拼接除了指令、@提及之外的所有文本作为私信正文
    const privateMsg = args.slice(1).join(' ');
    // 未输入私信正文时给出提示
    if (!privateMsg) {
      return message.channel.send("```请输入需要发送的私信内容```");
    }
    // 发送私信并捕获异常
    try {
      await targetMember.user.send(`${message.author.tag} 给你发送了一条站内私信: ${privateMsg}`);
      message.channel.send(`消息已成功发送给 ${targetMember.user.tag}`);
    } catch (sendErr) {
      message.channel.send("```发送失败:目标用户关闭了服务器私信接收权限```");
    }
  }
})

额外注意事项

  • 禁止用var声明会覆盖外层作用域的变量,优先使用const/let做块级作用域声明,避免意外的变量提升、覆盖问题
  • Discord.js v14+版本已经废弃了原来的message事件,统一替换为messageCreate事件,继续使用老事件会出现API找不到的兼容问题
  • 所有涉及接口请求的方法(成员拉取、消息发送)都需要做异常捕获,避免因为用户关闭私信、网络波动等情况触发未处理的Promise警告

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.03 08:54:03