You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助升级Discord机器人至Discord.js v12的TypeError报错修复

Discord.js v12 报错 TypeError: client.channels.fetch(...).send is not a function 修复方案

报错核心原因

Discord.js v12 中所有 fetch() 类方法均为异步方法,返回 Promise 而非直接返回目标对象。
原代码直接对 client.channels.fetch(logsChannel) 链式调用 .send(),本质是给 Promise 对象调用了不存在的 send 方法,因此触发报错。
另外还有几处 v12 适配遗漏的问题会导致后续运行异常,一并修复。


具体修复项

  • 所有异步 fetch 操作必须用 await 等待 Promise 解析,拿到有效的频道实例后再调用 send 方法
  • 事件回调中用到 await 的,必须声明为 async 异步函数
  • v12 中用户、服务器的头像 URL 是方法而非属性,必须加括号调用:avatarURL()、iconURL(),不能直接当属性读取
  • 补充错误捕获,防止日志频道 ID 无效、未缓存等情况导致机器人崩溃
  • 简化原有空集合判断逻辑,直接用 Discord.js Collection 自带的 size 属性判断,避免冗余循环

完整适配后的可运行代码

const Discord = require('discord.js');
// 补充 partials 配置,支持接收未缓存的消息事件,避免空值报错
const client = new Discord.Client({
    partials: ['MESSAGE', 'CHANNEL']
});
const { prefix, token, logsChannel } = require('./config.json');

client.once('ready', () => {
    console.log('I am alive!');
});

// 简化后的空集合判断函数
function isEmpty(collection) {
    return collection.size === 0;
}

// 消息发送日志模块
client.on('message', async message => {
    if(message.author.bot) return;
    const username = message.author.tag;
    const channel = message.channel.name;
    const serverAvatarURL = message.guild.iconURL();
    const attachment = message.attachments.array();
    const img = isEmpty(attachment) ? "" : attachment[0].url;

    const embed_send = new Discord.MessageEmbed()
        .setAuthor(username, message.author.avatarURL())
        .setColor('23c115')
        .setTitle("Message sent!")
        .setDescription(message.content + " " + img)
        .setImage(img)
        .setFooter("#" + channel)
        .setTimestamp();
    
    // 修复核心报错:await 等待 fetch 拿到频道实例,补充错误捕获
    try {
        const logChannel = await client.channels.fetch(logsChannel);
        await logChannel.send(embed_send);
    } catch (err) {
        console.error('日志频道发送失败:', err);
    }
});

// 消息编辑日志模块
client.on("messageUpdate", async(oldMessage, newMessage) => {
    // 兼容未缓存消息的空值场景
    if(!oldMessage.content || !newMessage.content) return;
    if (oldMessage.content === newMessage.content) return;

    const attachment = oldMessage.attachments.array();
    const img = isEmpty(attachment) ? "" : attachment[0].url;

    const embed_edit = new Discord.MessageEmbed()
        .setAuthor(oldMessage.author.tag, oldMessage.author.avatarURL())
        .setColor('2615c1')
        .setTitle("Message edited!")
        .addField("Old", oldMessage.content + " " + img, true)
        .addField("New", newMessage.content + " " + img, true)
        .setFooter("#" + oldMessage.channel.name)
        .setTimestamp();
    
    try {
        const logChannel = await client.channels.fetch(logsChannel);
        await logChannel.send(embed_edit);
    } catch (err) {
        console.error('日志频道发送失败:', err);
    }
});

// 消息删除日志模块
client.on("messageDelete", async message => {
    const attachment = message.attachments.array();
    const img = isEmpty(attachment) ? "" : attachment[0].url;

    const embed_delete = new Discord.MessageEmbed()
        .setAuthor(message.author.tag, message.author.avatarURL())
        .setColor('c11515')
        .setTitle("Message deleted!")
        .setDescription(message.content + " " + img)
        .setImage(img)
        .setFooter("#" + message.channel.name)
        .setTimestamp();
    
    try {
        const logChannel = await client.channels.fetch(logsChannel);
        await logChannel.send(embed_delete);
    } catch (err) {
        console.error('日志频道发送失败:', err);
    }
});

client.login(token);

注意事项

请确保 config.json 中的 logsChannel 是合法的频道 ID 字符串,且机器人对该日志频道拥有「发送消息」「嵌入链接」权限。
若机器人仍无法正常接收消息事件,可在 Client 初始化时补充 intents 配置,显式开启消息读取、频道读取权限。

内容的提问来源于stack exchange,提问作者Random

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.27 17:45:04