我该如何做到让我的机器人在用户重复一组数字时为其赋予角色?

时间:2019-06-28 05:45:03

标签: javascript node.js discord.js

我正在尝试创建一个使用户具有完全访问Discord服务器权限的机器人。

我已经让漫游器提供了一个随机数,并在用户加入时给用户一个来宾角色,但是当他们重复该数字时,我需要我的漫游器为他们赋予成员角色。

这是我的代码:

let code;

client.on('guildMemberAdd', member => { 
    const channel = member.guild.channels.find(ch => ch.name === 'captcha');
    if (!channel) return;

        member.addRole(member.guild.roles.find("name", "Guest"));

        code = Math.floor(Math.random() + Math.random() + Math.random() + Math.random() * 992875 + Math.random());

        channel.send('Welcome, ' + member.toString() + '! Please repeat these numbers to get access to this server: ' + code);

     if (message.content == code) {

        member.addRole(member.guild.roles.find("name", "Member"));

        code = -1;

    }
});

client.on('message', async message => {
    if (message.content === 'fakeJoin--') {
        client.emit('guildMemberAdd', message.member || await message.guild.fetchMember(message.author));
    }
});

我没有收到任何错误消息,机器人也没有崩溃。当我重复号码时什么也没发生。

1 个答案:

答案 0 :(得分:0)

在发送带有代码的消息后,您的客户无法神奇地知道响应是什么。但是,您的代码似乎假定了这一点;您尝试在guildMemberAdd事件中没有任何消息的情况下阅读message.content

要解决此问题,您需要捕获通道中发送的消息,然后阅读用户的响应。


选项A:邮件收集器

可以创建MessageCollector来收集(您猜对了!)通道中发送的消息。根据您的情况,您可以创建一个,在收集时检查消息,然后将内容与正确的代码进行比较。

client.on('guildMemberAdd', async member => {
  if (member.user.bot) return;

  const channel = member.guild.channels.find(c => c.type === 'text' && c.name === 'captcha');

  const guestRole = member.guild.roles.find(r => r.name === 'Guest');
  const memebrRole = member.guild.roles.find(r => r.name === 'Member');

  try {
    await member.addRole(guestRole);

    let code = '';
    for (let i = 0; i < 6; i++) code += `${Math.floor(Math.random() * 10)}`;

    await channel.send(`Welcome, ${member}. Please repeat this code to continue: \`${code}\``);

    const collector = channel.createMessageCollector(message => message.author.id === member.id, { maxMatches: 1 });
    collector.on('collect', async message => {
      if (message.content === code) {
        await channel.send('Thank you. You may now continue into the server.');

        await member.removeRole(guestRole);
        await member.addRole(memberRole);
      } else await member.kick('Failed verification.');
    });
  } catch(err) {
    console.error(err);
  }
});

选项B:等待消息

TextChannel.awaitMessages是消息收集器的异步等效项。但是,Promise始终以Collection进行解析。

client.on('guildMemberAdd', async member => {
  if (member.user.bot) return;

  const channel = member.guild.channels.find(c => c.type === 'text' && c.name === 'captcha');

  const guestRole = member.guild.roles.find(r => r.name === 'Guest');
  const memebrRole = member.guild.roles.find(r => r.name === 'Member');

  try {
    await member.addRole(guestRole);

    let code = '';
    for (let i = 0; i < 6; i++) code += `${Math.floor(Math.random() * 10)}`;

    await channel.send(`Welcome, ${member}. Please repeat this code to continue: \`${code}\``);

    const collected = await channel.awaitMessages(message => message.author.id === member.id, { maxMatches: 1 });
    const message = collected.first(); // The only message in the returned Collection.
    if (message.content === code) {
      await channel.send('Thank you. You may now continue into the server.');

      await member.removeRole(guestRole);
      await member.addRole(memberRole);
    } else await member.kick('Failed verification.');
  } catch(err) {
    console.error(err);
  }
});

您会注意到我对基本代码进行了一些更改。我想解释其中的一些改进。

  • 必须将事件回调定义为异步,才能在其中使用关键字await
  • 如果新用户是漫游器,则无需进行验证。他们仍然无法完成它,因此您必须具有MANAGE_SERVER权限才能首先添加它。
  • 有关this question的已弃用用法,请参见Collection.find()
  • 在处理Promises时,您应始终确保处理任何拒绝,因此要处理try...catch语句。
  • 代码生成将导致包含6个随机整数的字符串。其他随机数生成方法不是随机的或包含性的。
  • 当用户通过验证时,将发送一条新消息,并且还将从“来宾”角色中删除这些消息(假设它是临时的)。
  • 用户验证失败时,他们会被踢。