You need to enable JavaScript to run this app. Discord bot定时更新embed倒计时功能无报错无响应问题排查求助
优惠活动
大模型
产品
解决方案
定价
更多

Discord bot定时更新embed倒计时功能无报错无响应问题排查求助

问题定位

  • 1 错误使用filter方法遍历消息
    你对channel.messages.cache调用filter方法执行逻辑是错误的:filter是集合筛选方法,回调需要返回布尔值来标记是否保留当前项,你没有返回值的情况下filter会返回空集合,所有更新逻辑不会实际执行。应该先筛选符合条件的消息,再用forEach遍历执行更新逻辑。
  • 2 未主动拉取频道历史消息
    Discord.js 默认不会缓存频道内的全部历史消息,只会保留客户端启动后新接收的、或主动拉取过的消息。你直接读取channel.messages.cache大概率找不到历史发布的活动embed消息,需要先主动fetch频道历史消息再处理。
  • 3 变量未定义报错
    新版本你已经去掉了数据库查询逻辑,不再有row对象,但活动开始的提示分支还在使用row.hostID,该变量未定义会触发运行时错误,你没有添加错误捕获逻辑,所以看不到报错、执行直接中断。
  • 4 日期时间解析风险
    你直接读取embed字段的value作为日期时间输入,这些值可能携带Discord markdown格式符(比如斜体、反引号、换行等),和原数据库的干净格式不一致,会导致new Date()解析失败生成无效日期,后续倒计时计算全部失效。

修正后代码

cron.schedule('* * * * *', async function () {
    // 遍历所有后缀为events的频道
    const eventChannels = bot.channels.cache.filter(channel => channel.name.endsWith('events'));
    for (const channel of eventChannels.values()) {
        try {
            // 主动拉取频道最近100条消息,可根据实际情况调整拉取数量
            const fetchedMessages = await channel.messages.fetch({ limit: 100 });
            // 筛选符合条件的活动消息
            const eventMessages = fetchedMessages.filter(message => {
                const embed = message.embeds[0];
                return embed && embed.color === 65280;
            });
            // 遍历处理每条活动消息
            for (const message of eventMessages.values()) {
                const embed = message.embeds[0];
                // 清理字段值里的markdown格式
                const event_date = embed.fields[0].value.replace(/[*`\n]/g, '').trim();
                const event_time = embed.fields[1].value.replace(/[*`\n]/g, '').trim();
                // 这里根据你实际embed的字段结构调整索引,获取hostID
                const hostID = embed.fields[2].value.replace(/[^0-9]/g, '').trim();

                const now = Date.now();
                const targetDate = new Date(`${event_date} ${event_time}:00`);
                // 增加日期有效性校验,避免解析失败中断逻辑
                if (isNaN(targetDate.getTime())) continue;

                const difference = (targetDate - now) / 1000;
                const days = Math.floor(difference / (3600 * 24));
                const hours = Math.floor((difference - (days * 3600 * 24)) / 3600);
                const minutes = Math.floor((difference - (days * 3600 * 24) - (hours * 3600)) / 60);

                let timeTill;
                if (difference <= 0) {
                    timeTill = `Event Started - get with <@!${hostID}> to join up in-game.`;
                } else if (days > 0) {
                    timeTill = `${days} Days ${hours} Hours ${minutes} Min`;
                } else if (hours > 0) {
                    timeTill = `${hours} Hours ${minutes} Min`;
                } else {
                    timeTill = `${minutes} Min`;
                }

                embed.fields[9] = {
                    name: 'Starts in:',
                    value: timeTill,
                    inline: false
                };
                // 单条消息更新错误捕获,不影响其他消息处理
                await message.edit(new Discord.MessageEmbed(embed)).catch(err => console.log('消息更新失败', err));
            }
        } catch (err) {
            console.log('频道处理失败', channel.id, err);
        }
    }
})

注意:代码中默认hostID存放在embed第3个字段(索引为2),你需要根据自己实际的embed字段结构调整hostID的取值索引;如果需要拉取更早的历史活动消息,可以调整messages.fetch的limit参数或者实现分页拉取逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 13:09:03