discord.js guildCreate.js 事件未触发

Posted

技术标签:

【中文标题】discord.js guildCreate.js 事件未触发【英文标题】:discord.js guildCreate.js event not firing 【发布时间】:2021-04-08 09:31:43 【问题描述】:

我们正在努力使我们的guildCreate.js 事件触发器适用于 Corion。但它抛出以下错误:

3|Corion   | (node:16154) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'cache' of undefined

这是我们的代码:

module.exports = async (client, guild) => 
    const channel = guild.channels.cache.find(channel => channel.type === 'text' && channel.permissionsFor(guild.me).has('SEND_MESSAGES'))
    console.log(`$client.name` + `has entered` + `$guild.name.`)
    channel.send(`Thanks for invite me!\n\nType **c!help** to see a full list of available commands!`).catch(console.error)
;

如果有帮助,这是我们的事件处理程序:

const events = fs.readdirSync('./events').filter(file => file.endsWith('.js'));

for (const file of events) 
    console.log(`Loading discord.js event $file`);
    const event = require(`./events/$file`);
    client.on(file.split(".")[0], event.bind(null, client));
;

我们正在运行 discord.js:12.5.1

【问题讨论】:

【参考方案1】:

由于client.on("guildCreate") 的回调是如何工作的,这在这种特殊情况下不起作用。事实上,您可能会发现这对于 Discord 的几乎所有不同事件都无法正常工作,因为回调的工作方式与您使用 .bind() 的方式相结合。

问题

想想client.on() 在其回调方面是如何工作的。使用client.on() 时,您可以执行以下操作:client.on("guildCreate", callback)。这就是client.on() 在触发该事件时所做的事情:它调用callback(guild)

现在想想你在代码中做了什么。你在你的事件处理函数上做event.bind(null, client),它的形式是callback(client, guild)。所以这就是发生的事情:

    您通过.bind() 在您的Discord.Client 的回调中设置client 的值。所以现在你的client 参数是Discord.Client,你的guild 参数是undefined。 当事件被触发时,它现在将您的第一个参数 (client) 设置为 Guild 对象。所以现在你的client 参数是Guild 而你的guild 参数仍然是 undefined。 现在在您的回调中,您尝试执行guild.channels.cacheguild 仍然未定义,因此 guild.channels 未定义,因此您会收到错误:Cannot read property 'cache' of undefined

解决方案

好的,那么您如何解决这个问题?好吧,您的第一直觉可能是简单地在回调中切换 clientguild 参数的顺序,然后适当地调整您的 .bind()。这可能适用于这个特定事件,但请记住,某些事件在其回调中有两个或多个参数。 guildCreate 只向您发送一个公会参数,但像 guildUpdate 这样的东西会向您发送两个(因此导致您当前遇到的完全相同的错误)。

无论您追求什么解决方案,您都需要完全废弃client 参数。如果您想考虑任意数量的参数并仍然使用方便的.bind() 方法,那么您可以将您的客户端绑定到this 关键字,而不是将您的客户端绑定到回调的第一个参数。这是我的意思的一个例子:

事件处理程序:

const events = fs.readdirSync('./events').filter(file => file.endsWith('.js'));

for (const file of events) 
    console.log(`Loading discord.js event $file`);
    const event = require(`./events/$file`);
    client.on(file.split(".")[0], event.bind(client));
;

guildCreate.js:

module.exports = async function (guild) 
    const client = this;
    const channel = guild.channels.cache.find(channel => channel.type === 'text' && channel.permissionsFor(guild.me).has('SEND_MESSAGES'))
    console.log(`$client.user.username` + `has entered` + `$guild.name.`)
    channel.send(`Thanks for invite me!\n\nType **c!help** to see a full list of available commands!`).catch(console.error)
;

这应该确保client.on() 不会与client 的值混淆,从而修复您遇到的特定错误。

发生了什么变化

总的来说,您需要:在事件处理程序中将.bind(null, client) 更改为.bind(client),从您的guildCreate.js 回调中删除client 参数,使用this 访问您的客户端,将client.name 更改为client.user.username 因为前者不正确,并从 ES6 箭头函数 (() => ) 切换到标准函数语法 (function() ) 因为 this 关键字在前者中的工作方式。

我尚未测试此解决方案,但假设它至少可以解决您当前面临的错误。如果没有,或者此代码中是否存在其他相关错误,请告诉我,我将编辑答案以修复它们。

【讨论】:

以上是关于discord.js guildCreate.js 事件未触发的主要内容,如果未能解决你的问题,请参考以下文章

我将如何使用两个不同版本的 discord.js | Discord.js 机器人

Discord 错误错误 Discord.js 中的无效令牌

Discord 仅识别 discord.js 中的“ping”命令

错误“const Discord = require(discord.js) ^ ReferenceError: discord is not defined”

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

Discord.js 和 discord.js-commando 防止命令在特定通道中运行