discord.js guildCreate.js 事件未触发

discord.js guildCreate.js event not firing

我们正在尝试让我们的 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

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

的方式相结合

问题

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

现在想想您在代码中做了什么。您正在对事件处理函数执行 event.bind(null, client),其格式为 callback(client, guild)。所以这就是发生的事情:

  1. 您通过 .bind() 在回调中将 client 的值设置为 Discord.Client。所以现在你的 client 参数是 Discord.Client,你的 guild 参数是 undefined.
  2. 当事件被触发时,它现在将您的第一个参数 (client) 设置为 Guild 对象。所以现在你的 client 参数是 Guild 而你的 guild 参数 仍然是 undefined.
  3. 现在在你的回调中,你尝试做 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 关键字在前者中的工作方式。

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