简体   繁体   English

为什么在用户离开语音频道时尝试编辑用户时会出现 DiscordAPIError?

[英]Why do I get a DiscordAPIError when trying to edit a user as they leave a voice channel?

Let me preface this by saying that this is my first attempt at coding a Discord bot.首先让我说这是我第一次尝试编码 Discord 机器人。 Also, I have been pounding my head into this for the past couple of days, so my brain feels like mush.另外,这几天我一直在为此苦苦思索,所以我的大脑感觉像糊状一样。 That being said, I apologize if the answer to this seems obvious to others.话虽这么说,如果这个问题的答案对其他人来说显而易见,我深表歉意。

To explain what I'm doing here, my bot is used with a particular game where there are periods of time that we don't want people to be able to hear each other talking (or involuntarily reacting to what is happening in the game).为了解释我在这里做什么,我的机器人用于一个特定的游戏,在这个游戏中有一段时间我们不希望人们能够听到彼此的谈话(或不由自主地对游戏中发生的事情做出反应) . The person running the game uses commands, which will mute or unmute everyone in the voice channel.运行游戏的人使用命令,这将使语音通道中的每个人静音或取消静音。 The bot works perfectly in that respect.该机器人在这方面工作得很好。 It has been tested, many times over, by multiple people.它已经过多人多次测试。

I wanted to add a contingency, however, because we don't want someone who leaves the game prematurely to end up server-muted indefinitely (until an admin can do something about it).然而,我想添加一个应急措施,因为我们不希望过早离开游戏的人最终无限期地被服务器静音(直到管理员可以对此采取措施)。 My answer to this was to have a specific role which is assigned when they are muted and removed when they are unmuted.我对此的回答是有一个特定的角色,当他们被静音时分配,当他们取消静音时被删除。 Then, the bot should check for that role when the person leaves the voice channel and, if they have it, makes sure the role is removed and the person is unmuted.然后,机器人应该在该人离开语音频道时检查该角色,如果有,则确保该角色已被删除并且该人已取消静音。 (This ensures that if they are server-muted for a reason OTHER than this bot, they can't use the bot functionality to get around that.) (这确保了如果他们由于除此机器人之外的其他原因而被服务器静音,他们将无法使用机器人功能来解决这个问题。)

So here is what I've written (and rewritten a number of times, trying to get it to work):所以这是我写的(并重写了很多次,试图让它发挥作用):

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.`);
        }
    }
})

It recognizes when someone leaves a voice channel and knows whether they have the role, because my console.log messages print to the console window, but that seems to be where the functionality stops.当有人离开语音通道时它会识别并知道他们是否有角色,因为我的 console.log 消息打印到控制台 window,但这似乎是功能停止的地方。 It doesn't remove the role or unmute the user.它不会删除角色或取消静音用户。 Here is my console.log (I've masked any information I consider private, for obvious reasons):这是我的 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.

I'm not new to programming or debugging my own code, and can usually figure these things out on my own (either through reading the documentation or searching on Google).我对编程或调试自己的代码并不陌生,通常可以自己解决这些问题(通过阅读文档或在 Google 上搜索)。 After struggling with this for a couple of days, though, I'm having no luck.但是,在为此苦苦挣扎了几天之后,我没有运气。 So I decided to try and reach out to the community.所以我决定尝试接触社区。 I would appreciate any assistance with getting to the bottom of what is causing this to fail.如果能深入了解导致失败的原因,我将不胜感激。

The Discord documentation says that trying to set the muteness/deafness of a user when they are not in a voice channel will throw an error, so you can't unmute a user once they have left a channel. Discord 文档说,当用户不在语音通道中时尝试设置用户的静音/耳聋会引发错误,因此一旦用户离开通道,您就无法取消静音。 Instead, you could unmute the user if they join a channel (after not being in a channel) with the 'Hushed' role:相反,如果用户以“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));
            }
        }
    }
});

With ES2017's async / await :使用 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);
            }
        }
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM