【问题标题】:How can I make it so that my bot gives a role to a user when they repeat a set of numbers?我怎样才能让我的机器人在用户重复一组数字时为其赋予角色?
【发布时间】:2019-11-10 02:14:28
【问题描述】:

我正在尝试制作一个机器人,为用户提供对 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));
    }
});

我没有收到任何错误消息,机器人没有崩溃。当我重复这个数字时没有任何反应。

【问题讨论】:

  • 您是否尝试自己解决问题?就像使用日志一样。例如,可以在 if 前添加console.log(message.content, code),在 if 中添加console.log('yes'),查看程序是否进入。通过一步一步地做这件事,你可能会解决你的问题,如果你没有成功,你会有更好的信息提供给帮助你的人
  • 如果这个系统的目的是防止用户帐户下的有害机器人,如果你知道消息的样子(取消息,提取代码,回复它),很容易绕过它。有 npm 包可帮助在图像中生成真正的 CAPTCHA,这更加安全且具有原生外观。

标签: javascript node.js discord.js


【解决方案1】:

在发送带有代码的消息后,您的客户端无法神奇地知道响应是什么。但是,您的代码似乎假设:当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 个随机整数组成的字符串。其他随机数生成方法没有随机性或包容性。
  • 当用户通过验证时,将发送一条新消息,并且他们也会从访客角色中移除(假设是临时角色)。
  • 如果用户验证失败,则会被踢出。

【讨论】:

    猜你喜欢
    • 2011-08-09
    • 2012-12-20
    • 2018-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-20
    • 2021-06-03
    相关资源
    最近更新 更多