You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用discord.js开发公告机器人遇awaitMessages未定义错误求助

解决discord.js中awaitMessages报"Cannot read property 'awaitMessages' of undefined"的问题

嘿,我来帮你搞定这个报错!你遇到的TypeError其实是个discord.js里的常见小坑——你直接访问的msg.member.dmChannel可能还没被创建出来。当你第一次给用户发DM的时候,Discord不会立刻生成DM通道对象,这时候dmChannel就是undefined,自然调用不了awaitMessages啦。

另外看你的代码还有几个小问题:多层嵌套的.then()简直是回调地狱,读起来头疼;catch块里直接创建Embed是无效的;还有变量没加let/const,容易搞出全局污染;最后Embed创建的顺序也有点问题,可能导致未定义就使用的情况。

修复后的代码(用async/await简化流程)

我把你的代码重构了一下,用async/await替代嵌套回调,同时确保DM通道存在,还统一了错误处理:

const allyAnnouncementChannel = client.channels.cache.get('756701256122236941');

// 假设Ping、Title、Message、Image、ImageURL、Finished都是你定义的提示文本
if (msg.content === '-na') {
  // 先检查是不是在DM里用指令
  if (msg.channel.type === 'DM') {
    return msg.reply('请在服务器频道里用这个指令哦!');
  }
  // 检查用户有没有权限角色
  if (!msg.member.roles.cache.has('756713479003701338')) {
    return msg.reply('你没有使用这个指令的权限哒!');
  }

  try {
    // 先创建/获取用户的DM通道,确保它存在
    const dmChannel = await msg.author.createDM();
    
    // 第一步:收集Ping内容
    await dmChannel.send(Ping);
    const pingCollected = await dmChannel.awaitMessages({
      filter: m => m.author.id === msg.author.id,
      max: 1,
      time: 300000, // 5分钟超时
      errors: ['time']
    });
    const embedPing = pingCollected.first().content;

    // 第二步:收集公告标题
    await dmChannel.send(Title);
    const titleCollected = await dmChannel.awaitMessages({
      filter: m => m.author.id === msg.author.id,
      max: 1,
      time: 300000,
      errors: ['time']
    });
    const embedTitle = titleCollected.first().content;

    // 第三步:收集公告内容
    await dmChannel.send(Message);
    const messageCollected = await dmChannel.awaitMessages({
      filter: m => m.author.id === msg.author.id,
      max: 1,
      time: 300000,
      errors: ['time']
    });
    const embedMessage = messageCollected.first().content;

    // 第四步:询问是否需要添加图片
    await dmChannel.send(Image);
    const imageConfirmCollected = await dmChannel.awaitMessages({
      filter: m => m.author.id === msg.author.id,
      max: 1,
      time: 300000,
      errors: ['time']
    });
    const needImage = imageConfirmCollected.first().content.toLowerCase() === 'yes';

    // 先创建基础Embed
    let announcementEmbed = new Discord.MessageEmbed()
      .setColor('#FFD700')
      .setTitle(embedTitle)
      .setDescription(embedMessage)
      .setTimestamp()
      .setFooter(`Sent By: ${msg.author.tag}`);

    if (needImage) {
      await dmChannel.send(ImageURL);
      const imageUrlCollected = await dmChannel.awaitMessages({
        filter: m => m.author.id === msg.author.id,
        max: 1,
        time: 300000,
        errors: ['time']
      });
      const embedImage = imageUrlCollected.first().content;
      announcementEmbed.setImage(embedImage);
      await dmChannel.send('图片已添加,马上发送公告!');
    } else {
      await dmChannel.send(Finished);
    }

    // 把公告发到指定频道
    await allyAnnouncementChannel.send(embedPing, announcementEmbed);
    await dmChannel.send('公告发送成功啦!');

  } catch (error) {
    // 处理超时或其他错误
    const cancelEmbed = new Discord.MessageEmbed()
      .setColor('#FFD700')
      .setTitle('Announcement Cancelled')
      .setDescription('It has been 5 minutes without a response. The announcement has been cancelled.')
      .setFooter('Please do the command again if you wish to send an announcement.');
    await msg.author.send({ embeds: [cancelEmbed] });
  }
}

关键改进说明

  1. 确保DM通道存在:用msg.author.createDM()方法,它会返回一个Promise,保证DM通道已经创建好,再也不会出现dmChannelundefined的情况。
  2. 告别回调地狱:用async/await把异步代码写成同步风格,读起来和维护起来都轻松多了。
  3. 统一错误处理:一个try/catch搞定所有超时和异常,不用重复写四次相同的错误Embed了。
  4. 变量规范:用const/let声明变量,避免全局污染,命名也改成了JavaScript常用的小驼峰格式。
  5. 逻辑优化:调整了Embed创建的顺序,确保所有变量都初始化后再使用,避免出现未定义的错误。

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

火山引擎 最新活动