Discord机器人/showallroles命令报DiscordAPIError[10062]求助
Discord斜杠命令/showallroles触发Unknown interaction错误排查
问题描述
开发Discord斜杠命令/showallroles,用于展示服务器内指定角色的所有用户及其角色过期时间,但执行命令时触发DiscordAPIError[10062]: Unknown interaction错误。
报错信息
C:\bot\bot_discord_js_time_role\node_modules\@discordjs\rest\dist\index.js:640 throw new DiscordAPIError(data, "code" in data ? data.code : data.error, status, method, url, requestData); ^ DiscordAPIError[10062]: Unknown interaction at handleErrors (C:\bot\bot_discord_js_time_role\node_modules\@discordjs\rest\dist\index.js:640:13) at processTicksAndRejections (node:internal/process/task_queues:96:5) at async BurstHandler.runRequest (C:\bot\bot_discord_js_time_role\node_modules\@discordjs\rest\dist\index.js:736:23) at async REST.request (C:\bot\bot_discord_js_time_role\node_modules\@discordjs\rest\dist\index.js:1387:22) at async ChatInputCommandInteraction.reply (C:\bot\bot_discord_js_time_role\node_modules\discord.js\src\structures\interfaces\InteractionResponses.js:111:5) { requestBody: { files: [], json: { type: 4, data: { content: 'deleted_user_361e19ab73da: Role: Subscribe Valid Sampai 5/02/2024 14:38 (setahun)\n' + 'cierocielo: Role: Subscribe Valid Sampai 21/01/2025 6:59 (22 menit)\n' + 'vincee94: Role: Subscribe Valid Sampai 23/01/2025 16:36 (2 hari)\n' + 'aruturuuu: Role: Subscribe Valid Sampai 24/01/2025 19:36 (4 hari)\n' + 'nobo88: Role: Subscribe Valid Sampai 25/01/2025 22:32 (5 hari)\n' + 'arjuna_inguh: Role: Subscribe Valid Sampai 25/01/2025 22:35 (5 hari)\n' + 'mayrekber: Role: Subscribe Valid Sampai 27/01/2025 10:13 (6 hari)\n' + 'uzziel: Role: Subscribe Valid Sampai 30/01/2025 16:17 (9 hari)\n' + 'kunard: Role: Subscribe Valid Sampai 1/02/2025 22:06 (12 hari)\n' + 'adre0064: Role: Subscribe Valid Sampai 3/02/2025 21:17 (14 hari)\n' + '.beelee: Role: Subscribe Valid Sampai 4/02/2025 2:31 (14 hari)\n' + 'monte_24678: Role: Subscribe Valid Sampai 17/02/2025 19:58 (sebulan)\n' + 'harmankardon5: Role: Subscribe Valid Sampai 18/02/2025 14:43 (sebulan)\n' + 'booboo1433: Role: Subscribe Valid Sampai 18/02/2025 19:53 (sebulan)\n' + 'irric: Role: Subscribe Valid Sampai 21/02/2025 19:42 (sebulan)\n' + 'navii2121: Role: Subscribe Valid Sampai 8/04/2025 19:38 (3 bulan)\n', tts: false, nonce: undefined, embeds: undefined, components: undefined, username: undefined, avatar_url: undefined, allowed_mentions: undefined, flags: 64, message_reference: undefined, attachments: undefined, sticker_ids: undefined, thread_name: undefined } } }, rawError: { message: 'Unknown interaction', code: 10062 }, code: 10062, status: 404, method: 'POST', url: 'https://discord.com/api/v10/interactions/1331044983817375835/aW50ZXJhY3Rpb246MTMzMTA0NDk4MzgxNzM3NTgzNTpic0NmSjRqMG9XS1pnQWNYUDdNN1lVaVBRNklwdmVYWktWZ2lRMXdQSnJxaXVZSWRMQjdZQjhrSW5EYkJiNjNVaGk2OTBvQTJkbkkzRlZvQ3FORW1HSEg3U3ZyNWU0V2oxRTFpRlNkcDk0VElvdnZlM2ZrSml0TlhrS25GM0wyMQ/callback' }
完整代码
const moment = require("moment"); const { SlashCommandBuilder, AttachmentBuilder } = require('discord.js'); module.exports = { data: new SlashCommandBuilder() .setName('showallroles') .setDescription('Show the expiration time of all roles') .addRoleOption(option => option.setName('role').setDescription('The role to show users for').setRequired(true)) .addStringOption(option => option.setName('sort').setDescription('Sort order').addChoices({name: 'Ascending', value: 'asc'}, {name: 'Descending', value: 'desc'}).setRequired(true)), async execute(client, interaction, guildId, db) { const roleId = interaction.options.getRole('role').id; const sortOrder = interaction.options.getString('sort') || 'asc'; // Default to ascending if sort option not provided let reply = ""; const users = db.prepare("SELECT * FROM members WHERE role = ? ORDER BY unixTimestamp " + (sortOrder === 'asc' ? 'ASC' : 'DESC')).all(roleId); // Get all users from the database, sorted by expiry if (users.length > 0) { for (const user of users) { const date = moment.unix(user.unixTimestamp); // Convert const currentData = moment(); moment.locale('id'); const duration = moment.duration(date.diff(currentData)); const formattedDuration = duration.humanize(); const member = await client.users.fetch(user.memberId); // Fetch the user object from Discord API if (member) { reply += `${member.username}: Role: ${(await interaction.guild.roles.fetch(user.role))?.name} Valid Sampai ${date.format("D/MM/YYYY H:mm")} (${formattedDuration})\n`; } } } else { reply = "Tidak ada Time Role"; } if (reply.length < 2000) { await interaction.reply({ content: reply, ephemeral: true }); } else { const attachment = new AttachmentBuilder(Buffer.from(reply), { name: 'output.txt' }); await interaction.reply({ files: [attachment], ephemeral: true }); } } };
问题原因
Discord要求所有交互必须在3秒内做出响应,否则会判定交互失效并返回Unknown interaction错误。你的代码在循环中多次调用client.users.fetch()和interaction.guild.roles.fetch(),这些都是异步API请求,当用户数量较多时,总耗时会超过3秒,导致交互超时失效。
解决方案
1. 先发送延迟回复,延长交互有效期
在代码开始处调用interaction.deferReply(),告诉Discord正在处理请求,将交互有效期延长至15分钟,之后用editReply()更新回复内容。
2. 优化API请求,减少异步等待时间
- 避免在循环内重复调用
interaction.guild.roles.fetch(),直接复用命令参数中获取的目标角色对象 - 批量获取用户信息,减少API调用次数(进一步优化性能)
修改后的代码
const moment = require("moment"); const { SlashCommandBuilder, AttachmentBuilder } = require('discord.js'); module.exports = { data: new SlashCommandBuilder() .setName('showallroles') .setDescription('Show the expiration time of all roles') .addRoleOption(option => option.setName('role').setDescription('The role to show users for').setRequired(true)) .addStringOption(option => option.setName('sort').setDescription('Sort order').addChoices({name: 'Ascending', value: 'asc'}, {name: 'Descending', value: 'desc'}).setRequired(true)), async execute(client, interaction, guildId, db) { // 先发送延迟回复,延长交互有效期 await interaction.deferReply({ ephemeral: true }); const targetRole = interaction.options.getRole('role'); const roleId = targetRole.id; const roleName = targetRole.name; const sortOrder = interaction.options.getString('sort') || 'asc'; let reply = ""; const users = db.prepare("SELECT * FROM members WHERE role = ? ORDER BY unixTimestamp " + (sortOrder === 'asc' ? 'ASC' : 'DESC')).all(roleId); if (users.length > 0) { // 批量收集用户ID,减少API调用次数 const userIds = users.map(u => u.memberId); const fetchedUsers = await client.users.fetch({ user: userIds }); moment.locale('id'); const currentDate = moment(); for (const user of users) { const date = moment.unix(user.unixTimestamp); const duration = moment.duration(date.diff(currentDate)); const formattedDuration = duration.humanize(); const member = fetchedUsers.get(user.memberId); if (member) { reply += `${member.username}: Role: ${roleName} Valid Sampai ${date.format("D/MM/YYYY H:mm")} (${formattedDuration})\n`; } } } else { reply = "Tidak ada Time Role"; } if (reply.length < 2000) { await interaction.editReply({ content: reply }); } else { const attachment = new AttachmentBuilder(Buffer.from(reply), { name: 'output.txt' }); await interaction.editReply({ files: [attachment] }); } } };
内容的提问来源于stack exchange,提问作者dndcorp
相关产品推荐
相关产品推荐

