为啥我在尝试编辑离开语音频道的用户时会收到 DiscordAPIError?
Posted
技术标签:
【中文标题】为啥我在尝试编辑离开语音频道的用户时会收到 DiscordAPIError?【英文标题】:Why do I get a DiscordAPIError when trying to edit a user as they leave a voice channel?为什么我在尝试编辑离开语音频道的用户时会收到 DiscordAPIError? 【发布时间】:2020-12-18 11:53:12 【问题描述】:让我先说这是我第一次尝试编写 Discord 机器人。此外,在过去的几天里,我一直在努力解决这个问题,所以我的大脑感觉像糊状。话虽如此,如果其他人对此问题的答案似乎很明显,我深表歉意。
为了解释我在这里所做的事情,我的机器人用于特定的游戏,在该游戏中有一段时间我们不希望人们能够听到彼此的谈话(或不由自主地对正在发生的事情做出反应)游戏)。运行游戏的人使用命令将语音通道中的每个人静音或取消静音。该机器人在这方面工作得很好。它已经过多人多次测试。
不过,我想添加一个意外事件,因为我们不希望过早离开游戏的人最终无限期地关闭服务器(直到管理员可以对此采取措施)。我对此的回答是有一个特定的角色,当他们被静音时被分配,当他们被取消静音时被移除。然后,机器人应该在该人离开语音频道时检查该角色,如果有,请确保该角色已被删除并且该人未静音。 (这确保了如果他们因为除此机器人以外的原因而被服务器静音,他们就无法使用机器人功能来解决这个问题。)
所以这是我写的(并重写了很多次,试图让它工作):
client.on('voiceStateUpdate', (oldState, newState) =>
let oldServer = oldState.guild;
let oldChannel = oldState.channel;
let oldMember = oldState.member;
// If user leaves a voice channel (ignores voiceStateUpdate caused by muting/unmuting in other functions).
if (oldChannel && oldChannel !== newState.channel)
console.log(`$oldMember.user.tag left channel $oldChannel.name ($oldServer.name).`);
// Check if they have the "Hushed" role.
if (oldMember.roles.cache.some(role => role.name === 'Hushed'))
// Remove the "Hushed" role, if the user has it.
let role = oldServer.roles.cache.find(role => role.name === 'Hushed');
oldMember.roles.remove(role).catch(console.error);
console.log(`- "Hushed" role removed from $oldMember.user.tag.`);
// Unmute this member.
oldMember.voice.setMute(false);
console.log(`- User $oldMember.user.tag unmuted.`);
)
它会识别某人何时离开语音频道并知道他们是否担任该角色,因为我的 console.log 消息会打印到控制台窗口,但这似乎是功能停止的地方。它不会删除角色或取消静音用户。这是我的 console.log(出于显而易见的原因,我已经掩盖了我认为是私有的所有信息):
MY_DISCORD_TAG left channel Testing (MY_DISCORD_SERVER).
- "Hushed" role removed from MY_DISCORD_TAG.
- User MY_DISCORD_TAG unmuted.
(node:17092) UnhandledPromiseRejectionWarning: DiscordAPIError: Target user is not connected to voice.
at RequestHandler.execute (C:\Users\MY_NAME\Discord\Hush\node_modules\discord.js\src\rest\RequestHandler.js:170:25)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:17092) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:17092) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
我对自己的代码进行编程或调试并不陌生,通常可以自己解决这些问题(通过阅读文档或在 Google 上搜索)。但是,在为此苦苦挣扎了几天之后,我没有运气。所以我决定尝试接触社区。我将不胜感激任何帮助了解导致此失败的原因。
【问题讨论】:
【参考方案1】:Discord documentation 表示,当用户不在语音频道时尝试设置用户的静音/耳聋会引发错误,因此您无法在用户离开频道后取消静音。相反,如果用户以“Hushed”角色加入频道(不在频道中之后),您可以取消静音:
client.on('voiceStateUpdate',(oldState, newState) =>
let oldServer = oldState.guild;
let oldChannel = oldState.channel;
let oldMember = oldState.member;
let newChannel = newState.channel;
// If the user changed voice channels or the user joined a channel (after not being in one)
if (oldChannel && newChannel && oldChannel !== newChannel || !oldChannel)
// Check if they have the "Hushed" role.
if (oldMember.roles.cache.some(role => role.name === 'Hushed'))
// Remove the "Hushed" role, if the user has it.
let role = oldServer.roles.cache.find(role => role.name === 'Hushed');
oldMember.roles.remove(role)
.then(() =>
// This will be logged after the role has been successfully removed.
// As removing roles is asynchronous, your code would have logged this
// regardless of whether the role was actually removed.
console.log(`- "Hushed" role removed from $oldMember.user.tag.`);
// Unmute this member.
return oldMember.voice.setMute(false);
)
.then(() => console.log(`- User $oldMember.user.tag unmuted.`))
.catch(error => console.error(error));
);
使用 ES2017 的 async
/await
:
client.on('voiceStateUpdate', async (oldState, newState) =>
let oldServer = oldState.guild;
let oldChannel = oldState.channel;
let oldMember = oldState.member;
let newChannel = newState.channel;
// If the user changed voice channels or the user joined a channel (after not being in one)
if (oldChannel && newChannel && oldChannel !== newChannel || !oldChannel)
// Check if they have the "Hushed" role.
if (oldMember.roles.cache.some(role => role.name === 'Hushed'))
// Remove the "Hushed" role, if the user has it.
let role = oldServer.roles.cache.find(role => role.name === 'Hushed');
try
await oldMember.roles.remove(role);
console.log(`- "Hushed" role removed from $oldMember.user.tag.`);
// Unmute this member.
await oldMember.voice.setMute(false);
console.log(`- User $oldMember.user.tag unmuted.`);
catch (error)
console.error(error);
);
【讨论】:
哇,我不敢相信我错过了。我确实说过我的大脑是糊状的!非常感谢您的帮助,这绝对是问题所在。以上是关于为啥我在尝试编辑离开语音频道的用户时会收到 DiscordAPIError?的主要内容,如果未能解决你的问题,请参考以下文章