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

基于Cloud Functions实现每日课程定时检测与重复触发方案咨询

基于Firebase Cloud Functions实现课程提醒方案

一、添加课程时启动5分钟延迟检查

当用户在Firestore中新增课程文档时,通过Firestore触发器创建Cloud Task,设置延迟执行时间为「课程开始时间+5分钟」,到点后自动触发课程完成状态检查,并向未标记完成的教师发送邮件提醒。

实现步骤

  1. 提前在Google Cloud控制台启用Cloud Tasks API,创建专属队列(例如course-check-queue),队列区域需与Cloud Functions部署区域保持一致。
  2. 编写Firestore onCreate触发器函数,调度延迟任务:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
const { CloudTasksClient } = require("@google-cloud/tasks");
admin.initializeApp();

const client = new CloudTasksClient();

exports.scheduleCourseCheck = functions.firestore.document('courses/{courseId}')
  .onCreate(async (snap, context) => {
    const courseData = snap.data();
    const courseStartTime = new Date(courseData.startTime); // 假设startTime为ISO格式字符串/时间戳
    const checkTime = new Date(courseStartTime.getTime() + 5 * 60 * 1000); // 课程开始后5分钟执行检查

    // 构建Cloud Task请求参数
    const project = process.env.GCP_PROJECT;
    const location = "us-central1"; // 替换为你的函数部署区域
    const queue = "course-check-queue"; // 提前创建的队列名称
    const handlerUrl = `https://${location}-${project}.cloudfunctions.net/checkCourseCompletion`;

    const taskPayload = {
      httpRequest: {
        httpMethod: "POST",
        url: handlerUrl,
        body: Buffer.from(JSON.stringify({ courseId: context.params.courseId })).toString("base64"),
        headers: { "Content-Type": "application/json" },
      },
      scheduleTime: { seconds: Math.floor(checkTime.getTime() / 1000) },
    };

    const queuePath = client.queuePath(project, location, queue);
    await client.createTask({ parent: queuePath, task: taskPayload });

    functions.logger.info(`已调度课程${context.params.courseId}的检查任务,执行时间:${checkTime}`);
  });
  1. 编写检查逻辑与邮件发送的HTTP函数:
exports.checkCourseCompletion = functions.https.onRequest(async (req, res) => {
  try {
    const { courseId } = req.body;
    const courseDoc = await admin.firestore().collection('courses').doc(courseId).get();

    if (!courseDoc.exists) {
      functions.logger.error(`课程${courseId}不存在`);
      return res.status(404).send("课程不存在");
    }

    const courseData = courseDoc.data();
    if (!courseData.isCompleted) {
      // 调用邮件发送逻辑
      await sendReminderEmail(courseData.teacherEmail, courseData.courseName);
      functions.logger.info(`已向教师${courseData.teacherEmail}发送课程${courseId}的完成提醒`);
    }

    res.status(200).send("检查完成");
  } catch (err) {
    functions.logger.error("检查任务执行失败:", err);
    res.status(500).send("执行失败");
  }
});

// 邮件发送示例(根据实际邮件服务实现)
async function sendReminderEmail(teacherEmail, courseName) {
  // 示例:使用Nodemailer或Firebase Email Extension
  // 替换为你的实际邮件发送代码
  // const transporter = nodemailer.createTransport({ /* 配置邮件服务 */ });
  // await transporter.sendMail({
  //   to: teacherEmail,
  //   subject: `未完成课程提醒:${courseName}`,
  //   text: `您的课程《${courseName}》已结束5分钟,但尚未标记完成,请及时处理。`
  // });
}

二、每日同一时间重复触发逻辑

针对每日重复的课程,通过Cloud Functions定时Cron任务,每天固定时间(例如凌晨1点)扫描所有有效重复课程,自动生成当日的检查任务。

实现代码

exports.scheduleDailyCourseChecks = functions.pubsub.schedule('0 1 * * *') // 每天凌晨1点执行
  .timeZone('Asia/Shanghai') // 替换为你的时区
  .onRun(async (context) => {
    const today = new Date();
    // 查询所有每日重复且未过期的课程
    const repeatCourses = await admin.firestore().collection('courses')
      .where('repeatType', '==', 'daily') // 假设repeatType标记为daily表示每日重复
      .where('endDate', '>=', today) // 课程未结束
      .get();

    const taskPromises = [];
    const project = process.env.GCP_PROJECT;
    const location = "us-central1";
    const queue = "course-check-queue";
    const handlerUrl = `https://${location}-${project}.cloudfunctions.net/checkCourseCompletion`;

    repeatCourses.forEach(doc => {
      const courseData = doc.data();
      // 计算当日课程开始时间
      const todayStartTime = new Date(today);
      todayStartTime.setHours(courseData.startHour, courseData.startMinute, 0, 0); // 假设存储了开始小时/分钟
      const checkTime = new Date(todayStartTime.getTime() + 5 * 60 * 1000);

      // 创建当日的检查任务
      const taskPayload = {
        httpRequest: {
          httpMethod: "POST",
          url: handlerUrl,
          body: Buffer.from(JSON.stringify({ courseId: doc.id })).toString("base64"),
          headers: { "Content-Type": "application/json" },
        },
        scheduleTime: { seconds: Math.floor(checkTime.getTime() / 1000) },
      };

      const queuePath = client.queuePath(project, location, queue);
      taskPromises.push(client.createTask({ parent: queuePath, task: taskPayload }));
    });

    await Promise.all(taskPromises);
    functions.logger.info(`已调度${taskPromises.length}个每日重复课程的检查任务`);
    return null;
  });

注意事项

  • 依赖安装:执行npm install @google-cloud/tasks firebase-admin firebase-functions安装所需依赖包
  • 权限配置:确保Cloud Functions服务账号拥有Cloud Tasks的任务创建权限
  • 幂等性处理:检查逻辑中需避免重复发送邮件(例如新增reminderSent标记字段)
  • 错误重试:Cloud Tasks默认会重试失败任务,可在队列配置中调整重试策略

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 18:40:32