Search code examples
discorddiscord.jsbots

Discord.js Trying to send a message if a user joins a voice channel


I'm trying to make my bot mention my server staff in a specific text channel when someone enters in the voice support waiting room.

Here's the script I use:

const { DiscordAPIError } = require('discord.js');
const BaseEvent = require('../../utils/structures/BaseEvent');
const Discord = require("discord.js");
const client = new Discord.Client();

module.exports = class ReadyEvent extends BaseEvent {
  constructor() {
    super('ready');
  }
  async run (client) {
  console.log(`Bot prêt, connecté en tant qu'${client.user.username}!`);
  }
}

client.on('voiceStateUpdate', (newMember) => {
  const newUserChannel = newMember.voice.channelID
  const textChannel = client.channels.cache.get('815316823275995139')

  if(newUserChannel === '815316796067414016') {
    textChannel.send(`worked`)
  }
})

There's no error in the console and when I'm joining the voice support channel, nothing happens.

This:

textChannel.send(`worked`)

is for test purposes, the line I use is

textChannel.send(`Hey ! Le <@&${753367852299321404}>, ${newMember.user.username} (${newMember.id}) est en Attente de Support !`)

The first part of the script that logs me the script is working ... is working, so I'm sure the script is correctly loaded, the bot is on my server and have all the permissions he needs.

Console and script screen

My discord.js version is 12.5.3

EDIT:

Yes, now I can see the log, so I put back my script to detect and send a message:

const { DiscordAPIError } = require('discord.js');
const BaseEvent = require('../../utils/structures/BaseEvent');
const Discord = require("discord.js");
const client = new Discord.Client();

module.exports = class ReadyEvent extends BaseEvent {
  constructor() {
    super('ready');
  }
  async run (client) {
  console.log(`Bot prêt, connecté en tant qu'${client.user.username}!`);
  client.on('voiceStateUpdate', (newState) => {
    const newUserChannel = newState.voice.channelID
    const textChannel = client.channels.cache.get('815316823275995139')
  
    if(newUserChannel === '815316796067414016') {
      textChannel.send(`working`)
    }
  }); 
  }
}

but I have this error:


D:\DiscordBot\Ariabot\src\events\ready\ReadyEvent.js:13
    const newUserChannel = newState.voice.channelID
                                          ^

TypeError: Cannot read property 'channelID' of undefined
    at Client.<anonymous> (D:\DiscordBot\Ariabot\src\events\ready\ReadyEvent.js:13:43)
    at Client.emit (events.js:376:20)
    at VoiceStateUpdate.handle (D:\DiscordBot\Ariabot\node_modules\discord.js\src\client\actions\VoiceStateUpdate.js:40:14)
    at Object.module.exports [as VOICE_STATE_UPDATE] (D:\DiscordBot\Ariabot\node_modules\discord.js\src\client\websocket\handlers\VOICE_STATE_UPDATE.js:4:35)
    at WebSocketManager.handlePacket (D:\DiscordBot\Ariabot\node_modules\discord.js\src\client\websocket\WebSocketManager.js:384:31)
    at WebSocketShard.onPacket (D:\DiscordBot\Ariabot\node_modules\discord.js\src\client\websocket\WebSocketShard.js:444:22)
    at WebSocketShard.onMessage (D:\DiscordBot\Ariabot\node_modules\discord.js\src\client\websocket\WebSocketShard.js:301:10)
    at WebSocket.onMessage (D:\DiscordBot\Ariabot\node_modules\ws\lib\event-target.js:132:16)
    at WebSocket.emit (events.js:376:20)
    at Receiver.receiverOnMessage (D:\DiscordBot\Ariabot\node_modules\ws\lib\websocket.js:834:20)
[nodemon] app crashed - waiting for file changes before starting...

Solution

  • The voiceStateUpdate event calls the callback with two VoiceStates. (oldState and newState)

    You should use the newState property for this purpose.

    A VoiceState does not contain a voice property but does contain a channelID property.

    Thus, your code should look something like this:

    const { DiscordAPIError } = require('discord.js');
    const BaseEvent = require('../../utils/structures/BaseEvent');
    const Discord = require("discord.js");
    const client = new Discord.Client();
    
    module.exports = class ReadyEvent extends BaseEvent {
      constructor() {
        super('ready');
      }
      async run (client) {
      console.log(`Bot prêt, connecté en tant qu'${client.user.username}!`);
    
      // use 2 parameters
      client.on('voiceStateUpdate', (oldState, newState) => {
        // use the .channelID property (.voice doesn't exist)
        const newUserChannel = newState.channelID;
        const textChannel = client.channels.cache.get('815316823275995139');
      
        if(newUserChannel === '815316796067414016') {
          textChannel.send("working");
        }
      }); 
      }
    }
    

    When calling functions, the name of the parameter does not matter, the position determines what is assigned to those variables.

    For example, in the code above, I could have named the variables foo and bar (instead of oldState and newState), and it would have still worked.