Discord机器人定时发送消息求助:指定时间调用函数
实现Discord机器人在CET时区特定时间自动发送消息
从你的描述来看,用固定延迟的方式确实不太适合每天固定时间触发的场景——毕竟夏令时、服务器时间波动都会影响间隔时长,更靠谱的方式是用定时任务调度或者计算到目标时间的差值循环触发。下面给你两种可行的方案,结合你已有的代码逻辑来调整:
方案一:用node-schedule库(推荐,简单可靠)
这个库专门处理Node.js的定时任务,支持时区配置,能自动处理CET/CEST的夏令时切换,不用自己手动算时间差。
步骤1:安装依赖
在项目根目录运行:
npm install node-schedule
步骤2:编写定时任务逻辑
先把你已有的发送消息逻辑抽成独立函数,再用定时任务每天CET 00:00调用它:
const schedule = require('node-schedule'); const { Client, GatewayIntentBits } = require('discord.js'); // 假设你用v14+版本的Discord.js const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages] }); const midnightMessages = ["今日KOTH播报1", "播报内容2", "播报内容3"]; // 你的文本数组 const targetChannelId = "你的目标频道ID"; // 填写要发消息的频道ID // 提取发送消息的核心函数 async function sendMidnightMessage() { const channel = await client.channels.fetch(targetChannelId); if (!channel || !channel.isTextBased()) return; // 按需求发送:遍历数组逐条发,或者拼接成一条发送 midnightMessages.forEach(msg => { channel.send(msg); }); // 也可以用拼接方式:channel.send(midnightMessages.join('\n')); } // 设置CET时区每天00:00的定时任务 // 用'Europe/Paris'时区自动适配CET/CEST夏令时 const midnightJob = schedule.scheduleJob({ hour: 0, minute: 0, tz: 'Europe/Paris' }, () => { console.log("触发午夜播报任务"); sendMidnightMessage().catch(err => console.error("发送消息出错:", err)); }); // 机器人登录逻辑 client.login('你的机器人Token');
如果需要添加其他特定时间的任务,复制上面的scheduleJob代码,修改hour和minute参数即可。
方案二:手动计算时间差(无额外依赖)
如果不想引入第三方库,可以手动计算当前时间到下一个CET午夜的差值,用setTimeout触发,触发后再计算下一天的时间,循环执行:
const { Client, GatewayIntentBits } = require('discord.js'); const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages] }); const midnightMessages = ["你的播报内容数组"]; const targetChannelId = "目标频道ID"; async function sendMidnightMessage() { const channel = await client.channels.fetch(targetChannelId); if (!channel || !channel.isTextBased()) return; midnightMessages.forEach(msg => channel.send(msg)); } // 计算到下一个CET午夜的时间差(毫秒) function getNextMidnightDelay() { const now = new Date(); // 转换为CET时间,自动处理夏令时 const cetNow = new Date(now.toLocaleString('en-US', { timeZone: 'Europe/Paris' })); const nextMidnight = new Date(cetNow); nextMidnight.setHours(24, 0, 0, 0); // 设为明天00:00 return nextMidnight.getTime() - cetNow.getTime(); } // 启动定时循环 function startMidnightScheduler() { const delay = getNextMidnightDelay(); setTimeout(() => { sendMidnightMessage().catch(err => console.error("发送失败:", err)); // 发送完成后,启动下一次的定时器 startMidnightScheduler(); }, delay); } // 机器人就绪后启动调度 client.on('ready', () => { console.log(`Logged in as ${client.user.tag}!`); startMidnightScheduler(); }); client.login('你的机器人Token');
注意事项
- 确保机器人拥有发送消息的权限,并且开启了对应的Intent(比如
GuildMessages、MessageContent,如果需要处理消息内容的话)。 - 如果你的文本数组需要动态更新,记得定时从存储中读取最新内容,不要一直用初始化时的静态数组。
- 方案二中每次触发后都会重新计算下一次的时间,能自动适配夏令时的时间变化。
内容的提问来源于stack exchange,提问作者vakacjus
相关产品推荐
相关产品推荐

