From ce8e64fed22cdea24c864b6b36a8d88026bf4f64 Mon Sep 17 00:00:00 2001 From: Corwin Brust Date: Fri, 22 May 2026 12:38:48 +0530 Subject: [PATCH] add reconnect, catch/dump errors, quiet debugging --- bot.js | 116 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 73 insertions(+), 43 deletions(-) diff --git a/bot.js b/bot.js index 43998b9..ccd3b1a 100644 --- a/bot.js +++ b/bot.js @@ -35,14 +35,28 @@ const shredConfig = JSON.parse( fs.readFileSync( configFile ) ); function writeConfig() { fs.writeFileSync( configFile, JSON.stringify( shredConfig ) ) } -const token = fs.readFileSync( shredConfig.tokenFile ).toString(); - const uri = shredConfig.uri; -const bot = new eris.Client( token, { +const bot = new eris.Client(fs.readFileSync(shredConfig.tokenFile).toString(), { seedVoiceConnections: true, reconnectDelay: 17000 }); +bot.on('error', err => console.debug({ + what:"error", + where:"bot", + error:err +})); +process.on("unhandledRejection", err => console.debug({ + what:"unhandledRejection", + where:"process", + error:err +})); +process.on("uncaughtException", err => console.debug({ + what:"uncaughtException", + where:"process", + error:err +})); + const joinAndPlay = function (msg) { _internal_join_and_play( msg.member.voiceState.channelID, msg.channel.id); @@ -51,19 +65,24 @@ const joinAndPlay = function (msg) { let activeChannels = {}; const _internal_join_and_play = function( joinID, msgID ) { - bot.joinVoiceChannel(joinID).catch((err) => { // Join the user's voice channel + bot.joinVoiceChannel(joinID).catch((err) => { if(msgID) { - bot.createMessage(msgID, "Error joining voice channel: " + err.message); // Notify the user if there is an error + bot.createMessage(msgID, "Error joining voice channel: " + err.message); } - console.log({'error joining voice channel': err,chan:joinID}); // Log the error + console.debug({ + what:"catch", + where:"join", + joinID:joinID, + msgID:msgID, + error:err + }); }).then((connection) => { - //connection.play( uri, { voiceDataTimeout: -1 } ); // Play the file and notify the user const ac = { playing: false, timer: false }; ac.stop = function() { connection.stopPlaying(); }; ac.play = function() { - connection.play( uri, { voiceDataTimeout: -1 }); + connection.play( uri, { voiceDataTimeout: 17000 }); ac.playing = true }; ac.before = function() { @@ -72,14 +91,11 @@ const _internal_join_and_play = function( joinID, msgID ) { } }; ac.when = function() { - if(msgID) { - bot.createMessage(msgID, `Now playing **${uri}**`); - } + //if(msgID) bot.createMessage(msgID, `Now playing **${uri}**`); }, ac.after = function() { - //if(msgID) bot.createMessage(msgID, `Finished **${uri}**`); // Say when the file has finished playing ac.playing = false; - console.log(`Finished in ${ joinID }`); + //console.log(`Finished in ${ joinID }`); }, ac.cancel = function() { @@ -100,11 +116,15 @@ const _internal_join_and_play = function( joinID, msgID ) { ac.start(); } } catch(err) { - console.log('ERROR: failed in maybeStart ' + err); + console.debug({ + what:"catch", + where:"maybeStart", + error:err + }); } }; activeChannels[ joinID ] = ac; - ac.timer = setInterval( ac.maybeStart, 1000 ); + ac.timer = setInterval( ac.maybeStart, 100 ); }); }; @@ -118,7 +138,13 @@ const doAutoJoin = function () { _internal_join_and_play( autoJoin[i].channel ); } catch (err) { - console.log('ERROR: failed to autojoin channel #' + i + ' guild:' + autoJoin[i].guild + ' ID:'+ autoJoin[i].channel + ' -> ' + err); + console.debug({ + what:"catch", + where:"doAutoJoin", + guild:auoJoin[i].guild, + id:autoJoin[i].channel, + error:err + }); } } }; @@ -148,8 +174,7 @@ function formatTrackTitle(meta) { + encodeURI( filename.replace('/spokes/gw11/storage/ftp/music/','') ); - //console.log({title:title,who:who,fileUri:fileUri,artist:artist,album:album,date:date,year:year,filename:filename}); - // //'[🔗]('+ fileUri +') '+ '**' + + //console.log({title:title,who:who,fUri:fileUri,artist:artist,album:album,date:date,year:year,fname:filename}); const rv = title +' '+ formatArtist(artist,album,year||date); return [rv,fileUri]; } @@ -157,29 +182,28 @@ const setStatus = async function() { try { const response = await fetch( shredConfig.titleUri ); if(!response.ok) { - //await msg.channel.createMessage( 'Playing (error retreiving title)' ); - //throw new Error(`Title response status: ${response.status}`); - console.log(`ERROR: Title status response: ${response.status}`); + console.debug({ + what:"request.ok", + where:"setStatus", + error:err + }); } const json = await response.json(); - // if(json && json.title && json.title !== title) { - // //await msg.channel.createMessage( "Playing: " + json.title ); - // title = json.title; - // console.log("New track title: " + json.title); - // bot.editStatus("online", [ { name: title, type: 0, url: "https://shred.ing" }]); - // } - //const {t,ar,al,dt,yr,fn} = await response.json(); if(json) { let [newTitle,newLink] = formatTrackTitle(Object.fromEntries( json )); if(newTitle && newTitle != title) { - console.log("Playing[discord]: " + newTitle + ' at ' + newLink); + //console.log("Playing[discord]: " + newTitle + ' at ' + newLink); title = newTitle; trackUri = newLink; bot.editStatus("online", [ { name: title, type: 0, url: newLink}]); } } } catch (err) { - console.log('ERROR: fetching title ' + err); + console.debug({ + what:"catch", + where:"setStatus", + error:err + }); } }; let timer = setInterval( setStatus, 10000 ); @@ -212,32 +236,38 @@ bot.on('messageCreate', async (msg) => { } else { joinAndPlay( msg ); } + } else if( msg.content.indexOf( 'reconnect' ) != -1) { + // request to join a channel + if( msg.member.voiceState.channelID) + joinAndPlay( msg ); } else { // treat everything else a request for current track title - // const response = await fetch( 'https://shred.ing/json' ); - // if(!response.ok) { - // await msg.channel.createMessage( 'Playing (error retreiving title)' ); - // throw new Error(`Title response status: ${response.status}`); - // } - // const json = await response.json(); await msg.channel.createMessage(title +"\n\n[Download/Permalink]("+ trackUri +")\n"); - //setStatus(); } } catch (err) { // There are various reasons why sending a message may fail. // The API might time out or choke and return a 5xx status, // or the bot may not have permission to send the // message (403 status). - console.warn('Failed to respond to mention.'); - console.warn(err); + console.debug({ + what:"replyMessageError", + where:"messageCreate", + error:err + }) } } }); -bot.on('error', err => { - console.warn(err); -}); +let autoJoinTimer; +function setAutoJoinTimeout( waitTime ) { + if(autoJoinTimer) return; + autoJoinTimer = setTimeout( () => { + autoJoinTimer=null; + doAutoJoin(); + }, waitTime ); + return autoJoinTimer; +} bot.connect(); -const autoJoinTimer = setTimeout( doAutoJoin, 10000 ); +setAutoJoinTimeout( 1000 );