discord.js报错TypeError: Cannot read property 'channel' of undefined如何解决
报错根因
- 客户端初始化后未完成登录就提前拉取缓存数据:你在代码最外层直接执行
client.guilds.cache.get获取服务器对象时,client还没有调用登录接口,Discord 侧的服务器、频道数据还没拉取到本地缓存中,所以cheese变量的值为undefined,调用undefined的channel属性自然会抛出该错误。 - 属性名拼写错误:Discord.js 中 Guild 实例的频道集合属性名为
channels(带s),你代码中写的cheese.channel是不存在的属性,就算cheese有值也会报错。 - 其他隐性问题:
require('dotenv').config缺少调用括号,环境变量不会生效;cron表达式使用了非法的24小时值(小时取值范围为0-23),定时任务无法正常触发;将client.login放在定时回调中会导致每次触发任务都重复登录,容易触发Discord的频率限制。
修复方案
你可以直接使用下方修正后的代码:
const Discord = require('discord.js'); const { Client, Intents } = require('discord.js'); const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] }); const cron = require('node-cron'); const express = require('express'); // 修正dotenv调用 require('dotenv').config(); let messageChannel; // 客户端登录完成、缓存就绪后再获取频道 client.on('ready', () => { console.log("I am ready"); const cheese = client.guilds.cache.get("796750832305307716"); // 修正channels拼写 messageChannel = cheese.channels.cache.get("796750832305307719"); }); const app = express(); // 修正cron表达式,示例为每天18点整触发 cron.schedule('0 0 18 * * *', function() { if (messageChannel) { messageChannel.send("TEST"); } }); app.listen(3000); // 全局只登录一次 client.login(process.env.DISCORD_TOKEN); // 你可以把token写到.env文件的DISCORD_TOKEN字段中,避免硬编码泄露
主要修改点:
- 新增
ready事件监听,所有需要用到Discord侧数据的操作都要等到客户端就绪后再执行,确保缓存已经加载完成 - 修正
channel拼写错误为channels - 调整登录逻辑为全局执行一次,不要在定时任务中重复登录
- 修正dotenv调用和cron表达式
- 增加频道存在性判断,避免偶发的空值报错
内容的提问来源于stack exchange,提问作者John Urquhart
相关产品推荐
相关产品推荐

