Skip to content
This repository has been archived by the owner on Aug 16, 2024. It is now read-only.

bot times out after a few seconds when !troll (person) is ran #5

Open
Xplodin opened this issue Jul 3, 2024 · 2 comments
Open

bot times out after a few seconds when !troll (person) is ran #5

Xplodin opened this issue Jul 3, 2024 · 2 comments

Comments

@Xplodin
Copy link

Xplodin commented Jul 3, 2024

C:\Users\somet\Downloads\discord-interrupter-main\node_modules\discord.js\src\client\voice\VoiceConnection.js:303
this.emit('error', new Error(reason));
^

Error [VOICE_CONNECTION_TIMEOUT]: Connection not established within 15 seconds.
at VoiceConnection.authenticateFailed (C:\Users\somet\Downloads\discord-interrupter-main\node_modules\discord.js\src\client\voice\VoiceConnection.js:303:26)
at C:\Users\somet\Downloads\discord-interrupter-main\node_modules\discord.js\src\client\voice\VoiceConnection.js:324:61
at Timeout. (C:\Users\somet\Downloads\discord-interrupter-main\node_modules\discord.js\src\client\BaseClient.js:83:7)
at listOnTimeout (node:internal/timers:569:17)
at process.processTimers (node:internal/timers:512:7) {
[Symbol(code)]: 'VOICE_CONNECTION_TIMEOUT'
}

@YockerFX
Copy link

YockerFX commented Jul 15, 2024

Explanation:

1.	Voice Connection Timeout Handling: Added a timeout handling mechanism to wait for the connection to become ready.
2.	Reconnection Logic: Implemented logic to handle reconnection attempts if the connection is disrupted.
3.	Updated to @discordjs/voice: Using the latest voice library to handle voice connections more reliably.
4.	Improved Intents: Specified intents to ensure the bot can receive the necessary events.

By implementing these changes, your bot should be able to handle voice connections more robustly and avoid common issues such as timeouts and disconnections.

Code:

const { Client, Intents } = require("discord.js");
const { joinVoiceChannel, createAudioPlayer, createAudioResource, AudioPlayerStatus, VoiceConnectionStatus, entersState } = require("@discordjs/voice");

const client = new Client({
    intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_VOICE_STATES]
});

/* Config */
const token = ""; // Bot token here
const ownerID = ""; // Optional, put your own ID here so that you're the only one who can run bot commands
/* Config */

let victim = ""; // This variable will be dynamically updated to the ID of the person you specify with !troll, best to leave this alone

client.once("ready", () => {
    console.log(`The bot is ready! Logged in as ${client.user.username}#${client.user.discriminator}`);
});

async function joinChannel(channel) {
    const connection = joinVoiceChannel({
        channelId: channel.id,
        guildId: channel.guild.id,
        adapterCreator: channel.guild.voiceAdapterCreator,
    });

    try {
        await entersState(connection, VoiceConnectionStatus.Ready, 30000); // Wait up to 30 seconds for the connection to become ready
        console.log(`Successfully joined 🔊 ${channel.name}!`);
        
        const player = createAudioPlayer();
        const resource = createAudioResource('audio.mp3');
        
        player.play(resource);
        connection.subscribe(player);

        player.on(AudioPlayerStatus.Idle, () => {
            player.play(resource); // Loop audio
        });

        connection.on('stateChange', (oldState, newState) => {
            if (oldState.status !== newState.status) {
                console.log(`Connection status changed from ${oldState.status} to ${newState.status}`);
            }
        });

        connection.on('error', error => {
            console.error('Voice connection error:', error);
        });

        connection.on(VoiceConnectionStatus.Disconnected, async (oldState, newState) => {
            try {
                await Promise.race([
                    entersState(connection, VoiceConnectionStatus.Signalling, 5000),
                    entersState(connection, VoiceConnectionStatus.Connecting, 5000),
                ]);
                console.log('Reconnected to the voice channel');
            } catch (error) {
                console.error('Failed to reconnect to the voice channel:', error);
                connection.destroy();
            }
        });
    } catch (error) {
        console.error('Failed to join the voice channel within 30 seconds:', error);
        connection.destroy();
    }
}

client.on("messageCreate", async (message) => {
    if (message.content.startsWith("!troll")) {
        if (ownerID && message.author.id !== ownerID) return; // If ownerID is specified, ignore everyone else besides the owner
        const args = message.content.split(" ");
        if (args[1] == null) {
            message.author.send("You need to put the ID of the person you're trying to troll after the command (example: !troll 1234567890)");
            return;
        }
        const victimMember = message.guild.members.cache.get(args[1]); // Get member object from ID
        if (victimMember != null) {
            victim = args[1];
            message.author.send(`I set the victim to <@${args[1]}>! If they're already in a VC, I'll auto-join. If not, I'll join the VC right after they do!`);
            console.log(`Now trolling: ${victimMember.user.username}#${victimMember.user.discriminator} (ID: ${victim})`);
            if (victimMember.voice.channel) {
                joinChannel(victimMember.voice.channel); // Join the victim's VC if they're already in one
            }
        } else {
            message.author.send("I couldn't find that user in your server, double-check the ID?");
        }
    }
});

client.on('voiceStateUpdate', (oldState, newState) => {
    if (newState.channel && newState.member.id === victim) {
        joinChannel(newState.channel); // Follow the victim into the voice channel
    } else if (!newState.channel && oldState.channel && oldState.member.id === victim) {
        const connection = getVoiceConnection(oldState.guild.id);
        if (connection) connection.destroy(); // Leave the voice channel if the victim leaves
    }
});

client.login(token);```

@Xplodin
Copy link
Author

Xplodin commented Jul 15, 2024

Explanation:

1.	Voice Connection Timeout Handling: Added a timeout handling mechanism to wait for the connection to become ready.
2.	Reconnection Logic: Implemented logic to handle reconnection attempts if the connection is disrupted.
3.	Updated to @discordjs/voice: Using the latest voice library to handle voice connections more reliably.
4.	Improved Intents: Specified intents to ensure the bot can receive the necessary events.

By implementing these changes, your bot should be able to handle voice connections more robustly and avoid common issues such as timeouts and disconnections.

Code:

const { Client, Intents } = require("discord.js");
const { joinVoiceChannel, createAudioPlayer, createAudioResource, AudioPlayerStatus, VoiceConnectionStatus, entersState } = require("@discordjs/voice");

const client = new Client({
    intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_VOICE_STATES]
});

/* Config */
const token = ""; // Bot token here
const ownerID = ""; // Optional, put your own ID here so that you're the only one who can run bot commands
/* Config */

let victim = ""; // This variable will be dynamically updated to the ID of the person you specify with !troll, best to leave this alone

client.once("ready", () => {
    console.log(`The bot is ready! Logged in as ${client.user.username}#${client.user.discriminator}`);
});

async function joinChannel(channel) {
    const connection = joinVoiceChannel({
        channelId: channel.id,
        guildId: channel.guild.id,
        adapterCreator: channel.guild.voiceAdapterCreator,
    });

    try {
        await entersState(connection, VoiceConnectionStatus.Ready, 30000); // Wait up to 30 seconds for the connection to become ready
        console.log(`Successfully joined 🔊 ${channel.name}!`);
        
        const player = createAudioPlayer();
        const resource = createAudioResource('audio.mp3');
        
        player.play(resource);
        connection.subscribe(player);

        player.on(AudioPlayerStatus.Idle, () => {
            player.play(resource); // Loop audio
        });

        connection.on('stateChange', (oldState, newState) => {
            if (oldState.status !== newState.status) {
                console.log(`Connection status changed from ${oldState.status} to ${newState.status}`);
            }
        });

        connection.on('error', error => {
            console.error('Voice connection error:', error);
        });

        connection.on(VoiceConnectionStatus.Disconnected, async (oldState, newState) => {
            try {
                await Promise.race([
                    entersState(connection, VoiceConnectionStatus.Signalling, 5000),
                    entersState(connection, VoiceConnectionStatus.Connecting, 5000),
                ]);
                console.log('Reconnected to the voice channel');
            } catch (error) {
                console.error('Failed to reconnect to the voice channel:', error);
                connection.destroy();
            }
        });
    } catch (error) {
        console.error('Failed to join the voice channel within 30 seconds:', error);
        connection.destroy();
    }
}

client.on("messageCreate", async (message) => {
    if (message.content.startsWith("!troll")) {
        if (ownerID && message.author.id !== ownerID) return; // If ownerID is specified, ignore everyone else besides the owner
        const args = message.content.split(" ");
        if (args[1] == null) {
            message.author.send("You need to put the ID of the person you're trying to troll after the command (example: !troll 1234567890)");
            return;
        }
        const victimMember = message.guild.members.cache.get(args[1]); // Get member object from ID
        if (victimMember != null) {
            victim = args[1];
            message.author.send(`I set the victim to <@${args[1]}>! If they're already in a VC, I'll auto-join. If not, I'll join the VC right after they do!`);
            console.log(`Now trolling: ${victimMember.user.username}#${victimMember.user.discriminator} (ID: ${victim})`);
            if (victimMember.voice.channel) {
                joinChannel(victimMember.voice.channel); // Join the victim's VC if they're already in one
            }
        } else {
            message.author.send("I couldn't find that user in your server, double-check the ID?");
        }
    }
});

client.on('voiceStateUpdate', (oldState, newState) => {
    if (newState.channel && newState.member.id === victim) {
        joinChannel(newState.channel); // Follow the victim into the voice channel
    } else if (!newState.channel && oldState.channel && oldState.member.id === victim) {
        const connection = getVoiceConnection(oldState.guild.id);
        if (connection) connection.destroy(); // Leave the voice channel if the victim leaves
    }
});

client.login(token);```

ty for the updated code, but it seems like it throws an error with
throw new Error("Cannot play a resource that has already ended.");
^

Error: Cannot play a resource that has already ended.
    at AudioPlayer.play (C:\Users\somet\Downloads\discord-interrupter-main\node_modules\@discordjs\voice\dist\index.js:943:13)
    at AudioPlayer.<anonymous> (C:\Users\somet\Downloads\discord-interrupter-main\index.cjs:37:20)
    at AudioPlayer.emit (node:events:513:28)
    at set state [as state] (C:\Users\somet\Downloads\discord-interrupter-main\node_modules\@discordjs\voice\dist\index.js:935:12)
    at AudioPlayer.checkPlayable (C:\Users\somet\Downloads\discord-interrupter-main\node_modules\@discordjs\voice\dist\index.js:1040:18)
    at C:\Users\somet\Downloads\discord-interrupter-main\node_modules\@discordjs\voice\dist\index.js:212:60
    at Array.filter (<anonymous>)
    at audioCycleStep (C:\Users\somet\Downloads\discord-interrupter-main\node_modules\@discordjs\voice\dist\index.js:212:34)
    at Timeout.<anonymous> (C:\Users\somet\Downloads\discord-interrupter-main\node_modules\@discordjs\voice\dist\index.js:221:45)
    at listOnTimeout (node:internal/timers:569:17)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants