You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

关于WebUntis课程ID生成规则、变更行为及n8n排课变更检测工作流的技术咨询

WebUntis课程ID生成规则、变更行为及n8n排课变更检测工作流的技术咨询

嘿,刚好我之前做过几个WebUntis相关的自动化项目,对你的问题应该能给出实际经验层面的解答:

一、Lesson ID的生成时机与方式

Lesson ID是WebUntis在创建初始课程条目时自动生成的内部唯一标识符,大部分部署里是自增整数,少数用UUID格式——核心目的就是绑定初始创建的那节课程,不会随便变动。

二、课程变更时的ID行为(按场景分)

这部分是检测变更的关键,我整理了几种常见场景的实际表现:

  • 教师/教室更换、课程时间微调:这类属于课程属性修改,Lesson ID完全不会变,因为只是给原有课程条目更新关联信息,核心课程实体还是原来的那个。
  • 课程标记为取消:只要是通过系统的“取消”功能标记(不是彻底删除),ID会保留,只是课程状态字段会变成cancelled;如果是管理员直接删除课程(这种情况很少见,学校一般不会这么操作),ID会被系统回收,但不会复用给新创建的课程。
  • 课程拆分/合并、删除旧课重建新课:这类场景会生成全新的Lesson ID,因为本质是创建了新的课程条目,和原来的课程已经没有关联了。

三、用Lesson ID做变更检测是否可靠?

大部分场景下是可靠的,但要避开几个坑:

  • 只对比ID的存在与否是不够的:有些变更(比如换老师)不会改ID,但内容已经变了,必须同时对比课程的核心属性(教师、教室、时间、状态)才能识别这类变更。
  • 警惕管理员“删旧建新型”修改:有些学校管理员习惯直接删旧课再建新课来替代修改,这种情况旧ID消失、新ID出现,你需要把这种情况识别为“课程变更”而非“新增课程”,可以通过课程的时间、科目等信息做二次匹配。

四、n8n工作流示例设计(我实际用过的版本)

给你一个落地性强的工作流思路,你可以根据自己的需求调整:

  1. 定时触发节点:设置每天凌晨2点触发(学校一般会在夜间更新排课),或者每4小时轮询一次(如果需要更及时的通知)。
  2. WebUntis数据拉取节点:调用WebUntis API导出目标班级/课程的排课数据,整理成包含lessonIdsubjectteacherroomstartTimestatus的结构化JSON。
  3. 基准数据存储节点:用n8n的Local File节点(存JSON文件)或者外部数据库(比如PostgreSQL),存储上一次拉取到的基准数据。
  4. 变更对比Code节点:写一段简单的JS代码做对比:
    // 示例对比逻辑
    const oldData = $input.all()[0].json;
    const newData = $input.all()[1].json;
    const changes = [];
    
    // 检测新增/变更课程
    newData.forEach(newLesson => {
      const oldLesson = oldData.find(l => l.lessonId === newLesson.lessonId);
      if (!oldLesson) {
        changes.push({type: '新增', ...newLesson});
      } else {
        // 对比核心属性
        const hasChange = oldLesson.teacher !== newLesson.teacher || 
                          oldLesson.room !== newLesson.room || 
                          oldLesson.startTime !== newLesson.startTime ||
                          oldLesson.status !== newLesson.status;
        if (hasChange) {
          changes.push({type: '变更', old: oldLesson, new: newLesson});
        }
      }
    });
    
    // 检测删除/取消课程
    oldData.forEach(oldLesson => {
      const newLesson = newData.find(l => l.lessonId === oldLesson.lessonId);
      if (!newLesson) {
        changes.push({type: '删除/取消', ...oldLesson});
      }
    });
    
    return changes;
    
  5. 筛选节点:只保留changes数组非空的结果,过滤掉无变更的情况。
  6. 通知视频生成节点:用FFmpeg节点调用本地FFmpeg,基于提前做好的模板视频,把变更内容(比如“XX班周三数学课换老师为李老师”)嵌入视频画面;或者用第三方模板生成API快速生成。
  7. WhatsApp发送节点:用WhatsApp Business API节点或者Twilio的WhatsApp集成,把生成的视频发送给目标群组或用户。

五、一些最佳实践

  • 每次轮询后一定要覆盖存储的基准数据,确保下一次对比的是最新的参考值。
  • 给每个变更生成唯一的标识(比如lessonId + 变更时间戳),避免重复发送相同的变更通知。
  • 如果只关注近期课程,可以在WebUntis API调用时加上时间范围过滤(比如只拉取未来7天的课程),减少数据量提升工作流效率。

内容来源于stack exchange

火山引擎 最新活动