Ожидание прямого сообщения Discord js не работает

#javascript #node.js #async-await #discord.js

Вопрос:

Итак, мой бот discord запрашивает у пользователя в DM секрет API. Я хочу дождаться ответа пользователя, чтобы я мог делать дальнейшие действия со своим ключом.

Начиная с client.on('messageCreate') того момента, как пользователь запросит добавить ключ, я вызываю эту функцию

 async function takeApiSecret(msg) {

    const botMsg = await msg.author.send("Please provide your api secret");
    const filter = collected => collected.author.id === msg.author.id;

    const collected = await botMsg.channel.awaitMessages(filter, {
      max: 1,
      time: 50000,
  }).catch(() => {
    msg.author.send('Timeout');
  });
 

Однако я не могу дождаться ответа пользователя и собрать его. Вместо этого, когда я отвечаю, я получаю другое сообщение на своем client.on('messageCreate') . Есть какие-нибудь зацепки, что я могу делать не так?

Комментарии:

1. Что говорится в сообщении вместо этого?

2. @MrMythical ничего … Я вообще не получаю никаких ошибок.

3. Какая версия discord.js ты в курсе?

4. @MrMythical 13.10 и узел 16.8.0

5. Ну, вы должны знать, что фильтры awaitMessages теперь находятся в первом аргументе как свойство объекта, поэтому это должно выглядеть так: awaitMessages({filter, max: 1, time: 50000})

Ответ №1:

В discord.js v13.x, параметры awaitMessages() немного изменились. Больше нет отдельных параметров для filter и options ; filter теперь содержится в параметрах. Это должно решить вашу проблему:

 const filter = collected => collected.author.id === msg.author.id;

const collected = await botMsg.channel.awaitMessages({
    filter,
    max: 1,
    time: 50000,
}).catch(() => {
    msg.author.send('Timeout');
});
 

Вы можете найти документацию здесь. По какой-то причине параметры, похоже, не полностью задокументированы, но вы можете просмотреть пример на этой странице, чтобы увидеть новый формат.


Кроме того, если этот код вызывается всякий раз, когда сообщение отправляется через DM, вам может потребоваться запретить запуску собранных сообщений остальной части кода messageCreate прослушивателя событий. Вот один из способов, которым вы могли бы это сделать:

Внешний messageCreate обработчик:

 const respondingUsers = new Set();
 

Прямо перед awaitMessages()

 respondingUsers.add(msg.author.id);
 

Внутри .then() тебя и .catch() на твоем awaitMessages() :

 respondingUsers.delete(msg.author.id);
 

В верхней части вашего messageCreate обработчика, сразу после других проверок (например, проверка того, является ли сообщение DM):

 if (respondingUsers.has(msg.author.id)) return;
 

Если мы соберем все это вместе, это может выглядеть примерно так (очевидно, измените это для работы с вашим кодом).:

 const respondingUsers = new Set();

client.on('messageCreate', msg => {

    if (msg.channel.type != "DM") return;
    if (respondingUsers.has(msg.author.id)) return;

    respondingUsers.add(msg.author.id);
    
    const filter = collected => collected.author.id === msg.author.id;

    const collected = botMsg.channel.awaitMessages({
        filter,
        max: 1,
        time: 50000,
    })
    .then(messages => {
        msg.author.send("Received messages");
        respondingUsers.delete(msg.author.id);
    })
    .catch(() => {
        msg.author.send('Timeout');
        respondingUsers.delete(msg.author.id);
    });

})
 

Комментарии:

1. Спасибо за подробный ответ! Действительно помог. Нам не нужно ждать, хотя, если мы используем . тогда, как вы упоминаете в своем коде, хотя

2. Правда, я не видел await там лол. Спасибо, что указали на это. Я убрал это из ответа. Вы можете адаптировать это для работы, async/await если хотите (честно говоря, так намного чище, чем при использовании .then ).