Discordjs-无法向该用户发送消息

时间:2018-07-18 17:05:37

标签: javascript

我正在为自己所在的服务器制作一个discord.js机器人程序,但是在尝试向用户(刚刚被踢来通知他们的DM)发送DM之后,该机器人程序就不会发送它根本会吐出一个错误

  

“ UnhandledPromiseRejection警告:DiscordAPIError:无法发送   给该用户的消息”

现在它失去控制了,因为它将起作用,我将添加一个小东西,它将停止工作(或多或少会出现预期),然后当我还原该添加项时,它将再次吐出错误。

这是我的kick命令代码

const Discord = require("discord.js");
const Client = new Discord.Client
const prefix = "m!"

module.exports.run = async(bot, message, args) => {
params = message.content.slice(prefix.length).trim().split(/ +/g);

command = args.shift().toLowerCase();

let memberKick = message.mentions.members.first();

let reasonKick = args.slice(1).join(" ");

if(message.member.roles.find("name", "MedaFrost Controller")) {
    var userReslv = message.guild.members.find("id", memberKick.id);
    let usericon = memberKick.displayAvatarURL;
    let botembed = new Discord.RichEmbed
    botembed.setDescription("❌ You Were Kicked From Roscord!");
    botembed.setColor("FF0000");
    botembed.setThumbnail(usericon);
    botembed.addField("Reason:", `${reasonKick}`);
    userReslv.send(botembed);
    memberKick.kick(reasonKick);
    message.channel.send("✅ " + `${memberKick}` + " was kicked! ✅")
} else {
    const userId = message.member.id
    message.channel.send("Sorry, " + `<@${userId}>` + ", but you do not have sufficient permissions!")
}
}

module.exports.help = {
name: "kickplayer",
description: "Kicks mentioned user."
}

(证明表情符号不是问题)   Link to image

4 个答案:

答案 0 :(得分:2)

您不应该使用延迟或计时器来解决此问题。 Discord.js中的异步调用返回Promises,您应该使用这些Promise。

承诺基本上可以使您的异步工作流同步:发生某些事情时->执行此操作。

这是工作流程:

  1. 向公会会员发送消息
  2. 正确发送邮件后踢

不用担心,由于Promises的帮助,他们没有时间对消息做出反应,因为这些动作很可能会立即发生。没有其他延迟。

所以基本上:

GuildMember
  .createDM()
  .then((DMChannel) => {
    // We have now a channel ready.
    // Send the message.
    DMChannel
      .send(reason)
      .then(() => {
        // Message sent, time to kick.
        GuildMember.kick(reason);
      });
  });

Here's the referenced GuildMember

您也可以抓住,应该抓住。当Promise无法执行分配给它的任务时,就会发生捕获。

GuildMember
  .createDM()
  .then((DMChannel) => {
    // We have now a channel ready.
    // Send the message.
    DMChannel
      .send(reason)
      .then(() => {
        // Message sent, time to kick.
        GuildMember
          .kick(reason)
          .catch((e) => {
            console.log('Failed to kick!', e);
            // Do something else instead...
          });
      });
  });

(您也可以捕获发送消息或创建频道的消息。)

在这里您可以了解有关Promises的更多信息,Promises是JavaScript的重要组成部分:https://javascript.info/promise-basics

答案 1 :(得分:1)

从评论中扩展:也许在消息和实际踢球之间添加了延迟?

由于您的函数是async,因此最好编写一个小的async延迟助手:

const delay = (msec) => new Promise((resolve) => setTimeout(resolve, msec));

现在您可以简单地

userReslv.send(botembed);
await delay(100); // 100 msec = 0.1 seconds
memberKick.kick(reasonKick); 
// ...

答案 2 :(得分:1)

您似乎正在使用的许多功能都是异步的。

特别是:

此外,您正在尝试将send更改为GuildMember。我对这个API并不十分熟悉,但是我认为在您踢完之后,它们可能会被不再视为GuildMember,在这种情况下,引用可能会过时。我认为您应该在kick之后直接发送到User

此外,我认为您总体上等待的不够。 kicksend都返回Promise,您可能应该await来解决,尤其是kick

获得该引用后,然后send与构造的消息一起使用:

async function kicker(bot, message, args) {
  /** @type GuildMember */
  const guildMemberToKick = message.mentions.members.first();

  /** @type User */
  const guildMemberUser = guildMemberToKick.user;

  /** @type RichEmbed */
  const kickRichMessage = new Discord.RichEmbed;

  /** @type String */
  const kickReason = "You've been a baaaad person";

  // Build the rich kick message
  kickRichMessage.setDescription("❌ You Were Kicked From Roscord!");
  kickRichMessage.setColor("FF0000");
  kickRichMessage.setThumbnail(guildMemberUser.displayAvatarURL);
  kickRichMessage.addField("Reason:", kickReason);

  // Kick and wait
  await guildMemberToKick.kick(kickReason);

  // Tell the user we kicked them and wait
  await guildMemberUser.send(kickRichMessage);

  // Tell the channel we kicked and wait
  await message.channel.send(`✅ ${guildMemberToKick.displayName} was kicked! ✅`);
}

答案 3 :(得分:0)

继续AKX的响应...

对于任何为此苦苦挣扎的人!

我将const延迟放在我的var userReslv上方,并将等待延迟(100)放在我的踢和消息发送之间。 (可能有很多更好的方式来表达这一点。)