Discord.js 尝试在用户加入语音频道时发送消息

Posted

技术标签:

【中文标题】Discord.js 尝试在用户加入语音频道时发送消息【英文标题】:Discord.js Trying to send a message if a user joins a voice channel 【发布时间】:2021-08-27 11:22:49 【问题描述】:

当有人进入语音支持等候室时,我正试图让我的机器人在特定的文本频道中提及我的服务器工作人员。

这是我使用的脚本:

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`)
  
)

控制台没有错误,当我加入语音支持频道时,没有任何反应。

这个:

textChannel.send(`worked`)

用于测试目的,我使用的行是

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

记录我脚本正在运行的脚本的第一部分......正在运行,所以我确定脚本已正确加载,机器人在我的服务器上并且拥有他需要的所有权限。

Console and script screen

我的 discord.js 版本是12.5.3

编辑:

是的,现在我可以看到日志了,所以我放回我的脚本来检测并发送消息:

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`)
    
  ); 
  

但我有这个错误:


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...

【问题讨论】:

voiceStateUpdate 事件被触发时,您是否尝试过登录控制台?这可行吗?如果可行,您能否在用户加入时记录用户数据? 感谢@LaytonGB 的回答我刚刚试过这个:```client.on('voiceStateUpdate', voice => console.log(voice); ); ``` 控制台什么也没有发生 绝对需要先让它工作,尽管据我所知你的代码是正确的。尝试在async run (client) 部分内移动voiceStateUpdate 事件设置?这样它应该在ready 事件触发时运行,而不是之前。可以解决所有问题。 再次感谢@LaytonGB,我正在进步,现在我看到了日志并将我的脚本放回原处,但是现在,我有一个错误,我编辑了我的帖子以添加所有信息。 正如错误所说,Cannot read property 'channelID' of undefined,意味着 newState 没有 voice 属性。在网上查看后,我发现 this 表明您的函数应该有两个输入,(oldMember, newMember) =&gt; (参见第 384 行),您可能正在尝试引用 newMember(而您当前的代码使用 newState 来引用 @987654338 @)。据我所知,使用client.on('voiceStateUpdate', (oldMember, newMember) =&gt; const newUserChannel = newMember.voice.channelID; ... 应该可以。 【参考方案1】:

voiceStateUpdate 事件使用两个 VoiceStates 调用回调。 (oldStatenewState

您应该为此使用newState 属性。

VoiceState 不包含 voice 属性,但包含 channelID 属性。

因此,您的代码应如下所示:

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");
    
  ); 
  

调用函数时,参数的名称无关紧要,位置决定了分配给这些变量的内容。

例如,在上面的代码中,我可以将变量命名为 foobar(而不是 oldStatenewState),它仍然可以工作。

【讨论】:

【参考方案2】:

非常感谢你们两位,现在一切正常。

如果脚本对路人有用:

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 ready, connected as $client.user.username!`);

  client.on('voiceStateUpdate', (oldState, newState) => 
    const newUserChannel = newState.channelID;
    const textChannel = client.channels.cache.get('852643030477307995');
// 852643030477307995 = ID of the text channel, I use, where the message will be posted
  
    if(newUserChannel === '759339336663040020') 
// 759339336663040020 = ID of the voice channel I want to lookup
      textChannel.send(`Hey <@&752168551103856700> ! $newState.member is waiting for help !`);
// <@&752168551103856700> = ID of the role I want to tag
    
  ); 
  

【讨论】:

以上是关于Discord.js 尝试在用户加入语音频道时发送消息的主要内容,如果未能解决你的问题,请参考以下文章

加入机器人 discord.js 的语音频道后如何忽略相同的命令

准备好加入语音频道(discord.js)

Discord.js 机器人无法离开语音频道

Discord.js如何使用用户ID获取用户昵称

(Discord 机器人)当用户加入 Discord 服务器(discord.js)时,如何发送欢迎消息?

Discord.js v12 角色查询