discord.js: guildMemberSpeaking event no longer working?
Please describe the problem you are having in as much detail as possible:
All of a sudden the “guildMemberSpeaking” stopped working. The bot was running did not crash, no errors, all of a sudden the event stop working. It will however emit once when a user starts talking but never will again for that user.
The following is an example of my entire test bot to show the issue:
const path = require('path');
SERVER_DIST = (path.basename(__filename) == "bot.js" ? "prod" : "beta");
CONFIG = require('./config.js').loadVar(SERVER_DIST);
const Discord = require('discord.js');
const client = new Discord.Client();
client.on('error', console.error);
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
let voiceChan = client.channels.get(CONFIG.ids.mainVoiceChanID);
voiceChan.join().then(connection => {
console.log('Connected to voice channel.');
}).catch(err => console.log(err));
});
client.on('guildMemberSpeaking', (member, speaking) => {
if(speaking) {
console.log(member.displayName + ' started talking.');
}
else {
console.log(member.displayName + ' stopped talking');
}
});
client.login(CONFIG.discordApi.token);
Further details:
- discord.js version: 11.5.1
- Node.js version: v10.15.3
- Operating system: CentOS release 6.10 (Final)
- Priority this issue should have – please be realistic and elaborate if possible: We use this event to track voice activity in a voice channel, this is very important to this bots usage.
- I have also tested the issue on latest master, commit hash:
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 13
- Comments: 75 (25 by maintainers)
We (discord) now only send speaking event once per WS connection - as our clients dont need this event beyond doing initial ssrc => user_id association.
There is a work-around that involves synthesizing the speaking events from UDP packet flow (which is what the native client does.)
See this example psuedo-ish code for more details:
It seems that no speaking events are received after the first one from the voice gateway. I’ve asked for some more information on this 👍
I couldn’t wait for this to get fixed, since we actively use this feature in a relatively big production. So I investigated a bit and indeed inspecting the UDP packages seems to be the way to go. Here is my spin on a quick fix I made 2 days ago, which surprisingly resembles jhgg’s version pretty much.
This is designed for the latest stable version of discord.js, but it can be easily translated I’m sure.
src/client/voice/receiver/VoiceReceiver.js after L30 add:
this.speakingTimeouts = new Map();Before L52 add:
This gives you the connection.on(‘speaking’) and client.on(‘guildMemberSpeaking’) events back in a pretty much perfectly working state, as well as fix the streams not ending when someone stops speaking if you record them.
Remember you need to play some silence first in order for the bot to receive voice packages properly.
This is becoming a rather severe issue for us, is there any fix on the horizon?
Hate to be “that guy” but has there been any progress on this? Or is this even going to be addressed since it’s not technically supported by discord?
Can confirm this started happening for us yesterday as well and really killed us. In our case it happens with the connection.on(‘speaking’) event in the exact same way as described. I assume a discord API change?
Is anyone on this thread still experiencing this issue on the
masterbranch of discord.js?This still doesn’t work in V12? Buggy as hell
@sillyfrog
master, and 12 branches, electron with node 12
returning id of timeout, not object
No srsly we’re doomed.
Followup - changing it to grab the channel from master, it actually does work. There seems to be some kind of link between playing a sound and having the speaking event fire. Strange.
Seems to be busted again.
Connection.on('speaking',(user,speaking) => {console.log("speaking")})don’t output anything, same with the client’s guildMemberSpeaking and debug logging only outputs the one speaking event when the user first speaks after joining the VC.Anyone is welcome to make a PR to the master or 11.5-dev branches, which will be reviewed and merged if valid.
Discord have changed the way this works. It’s not part of the official API, hence the original breaking change. It now works differently in that the bot needs to be in the channel as there are no longer speaking/stop speaking events fired via the web socket (there is just one initial speaking event to tie the various ID’s together). I have put together a working example that runs in Docker so you can see it in action, then you can work from there to see what maybe different in your setup: https://github.com/sillyfrog/discord.js-listenexample
@Kunikita Do you have a fork with theses changes applied? Sounds like it maybe worth making a PR to get this into master as it would be great to have. I can also make a PR, but sounds like you have already done the work. Cheers.
Capturing voice only works if you send some audio first since a while. The latest master fixed this by making the bot play some silence upon joining a voice channel. Also in the latest stable release, due the onSpeaking event never coming through with a false value, the streams you create with createPCMStream() might not get destroyed properly when the user stops speaking
Same issue here. The connection.on(“speaking”) event seems to fire twice immediately and then never again. I’ve been debugging for hours trying to figure out what I did wrong before finally finding this thread.