@Nikita1244
Anonymous

Ошибка DiscordAPIError[400], как исправить?

Здравствуйте! Я создал слеш-команду для гугла. Работает, как ожидается. Отправляет результаты поиска. Но, после ввода этой команды вылетает фатальная(под фатальной ошибкой я подразумеваю ошибку, из-за которой бот полностью падает) ошибка:
Ошибка

/home/nikita/apkdownloaderbot/node_modules/@discordjs/rest/dist/lib/handlers/SequentialHandler.cjs:287
        throw new DiscordAPIError.DiscordAPIError(data, "code" in data ? data.code : data.error, status, method, url, requestData);
              ^

DiscordAPIError[40060]: Interaction has already been acknowledged.
    at SequentialHandler.runRequest (/home/nikita/apkdownloaderbot/node_modules/@discordjs/rest/dist/lib/handlers/SequentialHandler.cjs:287:15)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async SequentialHandler.queueRequest (/home/nikita/apkdownloaderbot/node_modules/@discordjs/rest/dist/lib/handlers/SequentialHandler.cjs:99:14)
    at async REST.request (/home/nikita/apkdownloaderbot/node_modules/@discordjs/rest/dist/lib/REST.cjs:52:22)
    at async ChatInputCommandInteraction.reply (/home/nikita/apkdownloaderbot/node_modules/discord.js/src/structures/interfaces/InteractionResponses.js:110:5)
    at async /home/nikita/apkdownloaderbot/commands/google.js:41:28 {
  rawError: {
    message: 'Interaction has already been acknowledged.',
    code: 40060
  },
  code: 40060,
  status: 400,
  method: 'POST',
  url: 'https://discord.com/api/v10/interactions/1008075133002465321/aW50ZXJhY3Rpb246MTAwODA3NTEzMzAwMjQ2NTMyMTphWEpNRVV3cG51WUM4c3Vkd0N6WW9XamlWYzlvWHVNdUR6VVJHWmp3dkFUVnBKbFFsWFN0RzlVV1h1QXBYNzhjWDZRYWtNZDVtbTdpR01URjdaRE9PVGJBWUhSUURWZ21pckhTeVlQbWRHeXRMdWtXTW41ZHZzakdXOXpmd3ZyRg/callback',
  requestBody: {
    files: [],
    json: {
      type: 4,
      data: {
        content: undefined,
        tts: false,
        nonce: undefined,
        embeds: [ { author: [Object], color: 39423, fields: [Array] } ],
        components: undefined,
        username: undefined,
        avatar_url: undefined,
        allowed_mentions: undefined,
        flags: undefined,
        message_reference: undefined,
        attachments: undefined,
        sticker_ids: undefined
      }
    }
  }
}

Node.js v18.7.0


// Modules of Discord.js and libraries
const {SlashCommandBuilder, EmbedBuilder} = require('discord.js');
const {googleAPI, googleID} = require('../config.json')
const axios = require('axios')
module.exports = {
    // Config of slash command
    data: new SlashCommandBuilder()
        .setName('google')
        .setNameLocalizations({'ru': "гугл"})
        .setDescription('Easy Google!')
        .setDescriptionLocalizations({"ru": "Загугли легко!", "fr": "Google facile!", "es-ES": "¡Google fácil!"})
        .addStringOption(option =>
            option.setName('text')
                .setNameLocalizations({"ru": "текст", "fr": "texte", "es-ES": "texto"})
                .setDescription('Google search text')
                .setDescriptionLocalizations({'ru': 'Текст поиска Google', "fr": "Texte de recherche Google", "es-ES": 'Texto de búsqueda de Google'})
                .setRequired(true)),
    // Code
    async execute(interaction) {
        let localizations = {
            "ru": 'Результаты поиска в Google',
            "fr": "Résultats de recherche Google",
            "es-ES": "resultados de búsqueda de Google",
            "other": "Google search results",
        }
        const avatar = interaction.user.avatarURL()
        const embed = new EmbedBuilder()
            .setAuthor({name: localizations[interaction.locale] ?? localizations["other"], iconURL: avatar})
            .setColor(0x0099FF)
        const req = interaction.options.getString('text')
        await axios.get(`https://www.googleapis.com/customsearch/v1?key=${googleAPI}&cx=${googleID}&q=${encodeURIComponent(req)}`) // Search in Google
            .then((response) => {
                response.data.items.forEach(async(item) => { //
                    let localizations = {
                        "ru": 'Ссылка',
                        "fr": "Lien",
                        "es-ES": "Enlace",
                        "other": "Link"
                    }
                    embed.addFields({name: `${item.title}`, value: `${item.snippet} \n[${localizations[interaction.locale] ?? localizations['other']}](${item.link})`})
                    return await interaction.reply({embeds: [embed]})
                })
            }).catch(async (error) => {
            console.log(error);
            let localizations = {
                "ru": 'Возникла проблема при поиске в Google. Пожалуйста, попробуйте позже.',
                "fr": "Il y a eu un problème avec la recherche Google",
                "es-ES": "Hubo un problema con la búsqueda de Google",
                "other": "There was a problem with Google search",
            }
            return await interaction.reply({
                content: localizations[interaction.locale] ?? localizations["other"],
                ephemeral: true
            })
        });
    }
}
  • Вопрос задан
  • 229 просмотров
Решения вопроса 1
Alexandre888
@Alexandre888 Куратор тега discord.js
Javascript-разработчик
отрывок из discord.js guide по этой теме (перевод)

Как уже говорилось ранее, у вас есть три секунды, чтобы ответить на Interaction, прежде чем его токен станет недействительным. Но что, если у вас есть команда, выполняющая задачу, которой требуется больше времени, чем три секунды?

В этом случае вы можете воспользоваться методом BaseInteraction#deferReply(), который запускает <application> is thinking..., а также действует как начальный ответ. Это позволит вам получить 15 минут на выполнение задач перед ответом.

https://discordjs.guide/interactions/slash-command...

по всей видимости, на выполнение axios.get() иногда уходит более 3 секунд, из-за чего к моменту запуска .then() токен Interaction уже является недействительным, что и вызывает ошибку.

поэтому перед axios.get() нужно поставить await interaction.deferReply(), а после чего уже использовать await interaction.editReply(...) вместо await interaction.reply(...).

на протяжении всего времени, которое понадобится на выполнение axios.get(), юзер будет видеть надпись имя_бота думает... (или имя_бота is thinking..., в зависимости от языка).
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы