newState.speaking vs oldState.speaking doesn't seem to be working :(

I want to establish a timestamp both when user starts speaking and also stops speaking. My startTimer function starts like this: async function startTimer() { if (queueActive) { try { const currentUser = queue[0]; await unmuteUser(currentUser); userActive = true; unmuteTimestamp = Date.now(); const listener = speakingListener(currentUser); client.on('voiceStateUpdate', listener); while (userActive) { The while loop runs some continuous checks on the timestamps. The speakingListener looks like this (outside of the startTimer function): const speakingListener = (currentUser) => { return (oldState, newState) => { if (newState.member && String(newState.member.id) === String(currentUser.id)) { if (newState.speaking && !oldState.speaking && !startedSpeakingTimestamp) { console.log(${currentUser.user.tag} started speaking); startedSpeakingTimestamp = Date.now(); } else if (!newState.speaking && oldState.speaking) { console.log(${currentUser.user.tag} stopped speaking); stoppedSpeakingTimestamp = Date.now(); } } }; }; The speakingListener doesn't seem to ever be activated - am I missing something? 😦
6 Replies
d.js toolkit
d.js toolkit8mo ago
- What's your exact discord.js npm list discord.js and node node -v version? - Not a discord.js issue? Check out #other-js-ts. - Consider reading #how-to-get-help to improve your question! - Explain what exactly your issue is. - Post the full error stack trace, not just the top part! - Show your code! - Issue solved? Press the button!
monbrey
monbrey8mo ago
You're using a blocking while loop, this is a pretty terrible idea The timestamp approach is otherwise okay, I dont know why the loop is there
duck
duck8mo ago
<VoiceState>.speaking also doesn't exist you'd need to establish a VoiceConnection with joinVoiceChannel from @discordjs/voice and listen to the start/end event on <VoiceConnection>.receiver.speaking
geeks
geeksOP8mo ago
there's other stuff under the while loop 😉 just didn't include it interesting, thanks - will check it out
monbrey
monbrey8mo ago
Yeah but its still a blocking while loop
geeks
geeksOP8mo ago
perhaps this clarifies? my userSwitchInterval is just the 'check period' until the speakingListener changes some of the timestamps. 🙂 async function startTimer() { if (queueActive) { try { const currentUser = queue[0]; await unmuteUser(currentUser); userActive = true; unmuteTimestamp = Date.now(); const listener = speakingListener(currentUser); client.on('voiceStateUpdate', listener); while (userActive) { elapsedTime = Date.now() - unmuteTimestamp; if (!startedSpeakingTimestamp && (elapsedTime >= startedSpeakingLimit)) { // User didn't start speaking quickly enough console.log(${currentUser.user.tag} did not start speaking.); await muteUser(currentUser); queue.push(queue.shift()); userActive = false; } else if (elapsedTime >= speakTime) { console.log(${currentUser.user.tag} reached maximum speak time.); await muteUser(currentUser); queue.push(queue.shift()); userActive = false; } // Repeat after userSwitchInterval await new Promise(resolve => setTimeout(resolve, userSwitchInterval)); } // Reset timestamps startedSpeakingTimestamp = null; stoppedSpeakingTimestamp = null; unmuteTimestamp = null; // Unregister the event listener once the loop is done client.off('voiceStateUpdate', listener); // Run startTimer again for the next currentUser await startTimer(); } catch (error) { console.error('Error in user timer:', error); } } }
Want results from more Discord servers?
Add your server