From 5ec8754c73f7c95ab199a3fb5796cc95e925ae79 Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 12 May 2026 22:40:37 -0700 Subject: [PATCH] Finaly fixed discord audio connections, removed YTDL code as it was becoming unsupportable --- bot.js | 130 ++++++++++++++++++++++++++++++--------------------- package.json | 2 +- 2 files changed, 77 insertions(+), 55 deletions(-) diff --git a/bot.js b/bot.js index 65070e8..f765040 100755 --- a/bot.js +++ b/bot.js @@ -2,7 +2,7 @@ const { Client, Events, GatewayIntentBits } = require('discord.js'); const Voice = require('@discordjs/voice'); const { createReadStream, existsSync } = require('fs'); -const play = require('play-dl'); +//const play = require('play-dl'); // Local config files to import const { token } = require('./.data/config.json'); @@ -19,23 +19,38 @@ function signalExit(signal) { } // Subscribe to a few signal events process.on('SIGINT', signalExit); // For Ctrl-C when running in a TTY -process.on('SIGTERM', signalExit); // for systemd's stoppping of services +process.on('SIGTERM', signalExit); // for systemd's stopping of services // Define Discord Callbacks +// Phone Home when the process is started successfully client.on( Events.ClientReady, c => { console.log(`Logged in Successfully as ${c.user.tag}`); // Signal via discord that we are alive client.channels.fetch("860393205401255936") .then( papi => papi.send('hello papi') ); }); +// In order to leave a voice channel when its just us we need to process every voice change state in a guild we are in +client.on( Events.VoiceStateUpdate, async (oldState, newState) => { + // We can limit the exposure to only looking at oldState, the channel the user left + if(!oldState.channel) return; // User was not in a channel, this is probably a join + if(!oldState.channel.members.has(client.user.id)) return; // We are not in this channel + // grab the members, filtering out bots + const members = oldState.channel.members.filter(m => !m.user.bot); + if(members.size) return; // There are still others in the channel + const connection = Voice.getVoiceConnection(oldState.channel.guild.id); + connection.destroy(); +}); +// In order to process text commands we need to process every message sent in a guild we are in client.on( Events.MessageCreate, async message => { + if (message.content.match(/[\/;]/)) return; // we had to add '/' because moose tried to 'play' ../../../../etc/shadow // Variables that may be useful - var d = new Date(); // Today's date and timestamp + const d = new Date(); // Today's date and timestamp - // *** FIlter Section *** + // *** Filter Section *** // Prevent any triggering if the message is our own if( message.author.id === "860345552742907935" ) return; + //TODO: Also ignore other bots? message.author.bot // In the event of a DM... if (message.guild == null) { switch (message.author.id) { @@ -70,7 +85,7 @@ client.on( Events.MessageCreate, async message => { // *** Process Section *** - // Check for the shutup message + // Check for the shut up message if (message.content === "~") { console.log(`!stop issued by ${message.author.tag}`); if (!message.member.voice.channel) { @@ -82,7 +97,7 @@ client.on( Events.MessageCreate, async message => { return; } // Check for youtube play command - if (message.content.startsWith('!play') && message.member.voice.channel) { +/* if (message.content.startsWith('!play') && message.member.voice.channel) { console.log(`!play issued by ${message.author.tag} ${message.author.id}`); // Determine if we have a URL or a search term const ytmatch = message.content.match(/(?<=(?:https?:\/\/)(?:www\.)?youtu(?:(?:be\.com\/(?:(?:watch\?v=)|(?:shorts\/)))|(?:\.be\/)))[\w-]{11,12}/); @@ -92,7 +107,8 @@ client.on( Events.MessageCreate, async message => { console.log(`ytmatch yields ${ytmatch[0]}`); // Message matches the youtube video regex, see if it comes with a timestamp const timematch = message.content.match(/(?<=t=)(\d{1,4})s?(?=$)/); - if (timematch) { + if (timematch) {const connection = Voice.getVoiceConnection(message.guild.id); + connection.destroy(); console.log(`timematch yields $timematch[1]`); timestamp = timematch[1]; } @@ -130,12 +146,18 @@ client.on( Events.MessageCreate, async message => { connection.subscribe(player); // Setup Callbacks for when the player completes return; + } */ + if (message.content.match( "!new" )) { + const response = 'got tired of getting left in voice calls all night\n' + message.channel.send(response); + return; } - if (message.content === "!help" ) { + if (message.content.match( "!help" )) { console.log(`!help issued by ${message.author.tag} ${message.author.id}`); - var response = 'ZeSkypeBot v7.2.3 \'Angelica root\'\n'; + var response = 'ZeSkypeBot v7.2.5 \'What Year is it?\'\n'; response += 'Original by @moosecrap for Skype, Remade by @fredstonemason for Discord\n'; response += 'Changelog:\n'; + response += 'v4.2.4 First Update in 18 months, !play has been ripped out. Discord.js 14 updated to latest to fix no sound audio\n'; response += 'v7.2.1 Added !echo to try and deduce why theres lag in commands\n'; response += 'v7.2.0 Attempts to fix seemingly random searches, now should support age-restricted videos\n'; response += 'v7.1.0 Added support for searching in !play\n' @@ -151,12 +173,12 @@ client.on( Events.MessageCreate, async message => { response += '~ stop any sounds in progress and disconnect from voice\n'; response += '!help print this message\n'; response += 'To play Sounds, first join a voice channel then send a message in the text chat with the name of the sound\n'; - response += '!play [youtube url] play a youtube video over chat\n'; - response += '!play [search terms] play the first video that comes up after searching youtube with your terms\n'; +// response += '!play [youtube url] play a youtube video over chat\n'; +// response += '!play [search terms] play the first video that comes up after searching youtube with your terms\n'; message.channel.send(response); return; } - if (message.content === "!echo" ) { + if (message.content.match( "!echo" )) { var response = 'Debug Timers:\n```'; response += `Discord Timestamp: ${message.createdAt.toISOString()}\n`; response += `Local event start: ${d.toISOString()}\n`; @@ -177,53 +199,53 @@ client.on( Events.MessageCreate, async message => { return; } // Try to find a sound file that matches the message - if (!message.content.match(/[ \/;]/)) { - // we had to add '/' because moose tried to 'play' ../../../../etc/shadow - // Construct the expected sound path - const soundPath = ''; - if( d.getMonth() == 3 && d.getDate() == 1 ) { + if(message.content.match(' ')) return; + // Construct the expected sound path + var soundPath = ''; + if( d.getMonth() == 3 && d.getDate() == 1 ) { // TODO: april fools! // Scan the directory as an array // select randomly from the array - // play that sound instead - } - else soundPath = `./Sounds/${message.content}.ogg`; - if (message.author.id === "172538370440953867") { - switch(message.content) { - case "butthash": - message.react('859687015247511561'); - default: - } + // play that sound instead + } + else soundPath = `./Sounds/${message.content}.ogg`; + if (message.author.id === "172538370440953867") { + switch(message.content) { + case "butthash": + message.react('859687015247511561'); + default: } - if (message.author.id === "144317130026778624") { - switch(message.content) { - case "daytona": - case "e": - if ([0,5,6].includes(d.getDay()) && Math.random() < 0.8) return; - default: - } + } + if (message.author.id === "144317130026778624") { + switch(message.content) { + case "daytona": + case "e": + if ([0,5,6].includes(d.getDay()) && Math.random() < 0.8) return; + default: } - // Test if there is a file at the expected path - if (message.member.voice.channel && existsSync(soundPath)) { - console.log(`Sound '${message.content}' issued by ${message.author.tag} ${message.author.id}`); - // Join the Voice Channel of the author - const connection = Voice.joinVoiceChannel({ - channelId: message.member.voice.channelId, - guildId: message.guild.id, - adapterCreator: message.guild.voiceAdapterCreator, - }); - // Create an audio player for the desired sound - const resource = Voice.createAudioResource(createReadStream(soundPath)); - const player = Voice.createAudioPlayer(); - // Play the resource through the player to the connection (i hate discord v16) - player.play(resource); - // Connect the player to the voice connection (internal screaming intensifies) - connection.subscribe(player); - return; - } - } else { - //message.channel.send('NO FUCK YOU'); - console.log(`user ${message.author.tag} used some bad characters: ${message.content}`); + } + // Test if there is a file at the expected path + if (existsSync(soundPath)) { + // Get the VoiceChannel of the sender if there is one + const channel = message.member.voice.channel; + if (!(channel && channel.joinable && channel.speakable)) return; + console.log(`Sound '${message.content}' issued by ${message.author.tag} ${message.author.id}`); + // + // Join the Voice Channel of the author + const connection = Voice.joinVoiceChannel({ + channelId: channel.id, + guildId: message.guild.id, + adapterCreator: message.guild.voiceAdapterCreator, + }); + // Create an audio player for the desired sound + const resource = Voice.createAudioResource(createReadStream(soundPath)); + const player = Voice.createAudioPlayer(); + // Play the resource through the player to the connection (i hate discord v16) + player.play(resource); + // Connect the player to the voice connection (internal screaming intensifies) + connection.subscribe(player); + + return; } }); // Now our client is prepared, we can log in. diff --git a/package.json b/package.json index 74fac41..4f94b54 100755 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Goldar Squad's Skype Bot, ported for Discord\"", "main": "bot.js", "scripts": { - "preinstall": "npm install discord.js @discordjs/voice sodium @discordjs/opus ffmpeg-static play-dl", + "preinstall": "npm install discord.js @discordjs/voice sodium @discordjs/opus ffmpeg-static @snazzah/davey", "test": "echo \"Error: no test specified\" && exit 1" }, "repository": {