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

如何基于谷歌日历事件,用Discord.js实现定时消息推送?

解决方案:动态定时推送Discord日历提醒

核心思路

放弃固定cron任务,改用setTimeout为每个日历事件单独设置定时推送——根据事件开始时间计算提醒触发点(比如提前30分钟),同时维护定时任务的引用,方便日历数据更新时取消旧任务、创建新任务,避免重复或错误提醒。

实现代码

let upcomingEvents = [];
let scheduledReminders = new Map(); // 存储定时任务ID,键为事件ID,值为timeoutID

const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages] });

// 初始化/刷新提醒任务的函数
function setupEventReminders(events, channelId) {
  const channel = client.channels.cache.get(channelId);
  if (!channel) {
    console.error('目标频道不存在');
    return;
  }

  // 先取消所有旧的定时任务
  scheduledReminders.forEach(timeoutId => clearTimeout(timeoutId));
  scheduledReminders.clear();

  // 为每个事件创建新的提醒
  events.forEach(event => {
    // 计算提醒时间:比如提前30分钟发送,可自行调整
    const reminderTime = new Date(event.startTime) - 30 * 60 * 1000;
    const now = Date.now();

    // 如果提醒时间已经过去,跳过
    if (reminderTime <= now) return;

    // 设置定时任务
    const timeoutId = setTimeout(() => {
      channel.send(`⚠️ 即将开始:**${event.title}**,时间:${event.readabledate}`);
      scheduledReminders.delete(event.id); // 任务执行后移除引用
    }, reminderTime - now);

    // 保存任务ID到Map
    scheduledReminders.set(event.id, timeoutId);
    console.log(`已为事件「${event.title}」设置提醒,将在${new Date(reminderTime)}发送`);
  });
}

// 获取日历数据并更新提醒
async function fetchAndUpdateEvents() {
  try {
    const gcpClient = await authorize();
    upcomingEvents = await listEvents(gcpClient); // 假设listEvents返回带id、startTime、title、readabledate的事件数组
    // 调用提醒设置函数,传入目标频道ID
    setupEventReminders(upcomingEvents, '1049384497017266228');
  } catch (err) {
    console.error('获取日历数据失败:', err);
  }
}

client.once(Events.ClientReady, c => {
  console.log('Ready! Logged in as ', c.user.tag);
  // 机器人就绪后立即获取日历并设置提醒
  fetchAndUpdateEvents();
  
  // 定期刷新日历数据(比如每小时一次,避免事件变动后提醒失效)
  setInterval(fetchAndUpdateEvents, 60 * 60 * 1000);
});

client.login(TOKEN);

关键细节说明

  • 定时任务管理:用Map存储每个事件对应的timeoutID,刷新日历数据时先清空旧任务,避免重复提醒或已取消/修改的事件仍触发提醒。
  • 提醒时间计算:示例中设置为事件开始前30分钟,可根据需求调整(比如提前1小时、1天),注意要判断提醒时间是否在当前时间之后,避免发送过期提醒。
  • 日历数据刷新:用setInterval定期重新拉取日历数据,确保事件变动(新增、修改、删除)后能及时更新提醒任务。
  • 频道权限:确保机器人有目标频道的SendMessages权限,同时在客户端intents中加入GuildMessages(如果使用v14+的Discord.js)。

关于GuildScheduledEvent的说明

GuildScheduledEvent是Discord自带的服务器日程事件功能,用于在Discord内创建可订阅的事件,而非用来触发机器人的定时消息。如果需要让用户直接在Discord中看到事件并订阅,可以结合使用:在创建定时提醒的同时,调用guild.scheduledEvents.create()创建Discord原生事件,但这和你需要的定时消息推送是两个独立的功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 23:35:20