多人日程冲突时,Town 先动谁的时间,通常由两个变量共同决定:共享日历权限决定某位参会人的日程能不能被自动改写,任务优先级决定在可改写的范围内先动谁。比较稳妥的判断顺序是先用权限筛出可自动改期的候选集合,再在这个集合里按优先级从低到高调整;只读或需审批的参会人不在候选集合内,只能走询问或审批流程。把两个变量混在一起看,容易出现程序动了不该动的人,或把本该自动处理的小冲突推给人工。
建议的判断顺序是权限在前、优先级在后:权限是硬约束,优先级是排序依据。先用共享日历的共享权限把参会人分成可自动改期、需审批、只读三类,只有前两类进入自动调整范围;再对范围内的会议按发起人、截止时间、是否涉及外部客户排优先级,先动最低优先级的对象。若候选集合里全是高优先级会议,或权限状态读不到,应转为人工确认而不是强行改期。权限一旦变化,动谁的结果也会变,所以每次处理冲突前都应重新读取一次权限状态。
给每位参会人标注日历权限
先把参会人按日历权限分成三类,并记录在共享日历设置里的实际状态,而不是凭印象判断。可自动改期、需审批、只读这三种状态,决定了 Town 在遇到冲突时能直接改、先问再改,还是只能发询问。
- 可写(可管理):Town 可以直接移动该参会人的日程,事后通知即可。适用于本人已授权、日程以内部会议为主的账号。
- 可写但需审批:程序能改,但要先向日历所有者或会议发起人发起确认,确认通过后才落笔。
- 只读(仅可见忙闲):只能读到忙闲状态,不能改期。命中冲突时只能发询问,不能代替对方做决定。
这些状态通常在日历服务的共享设置页里能看到,例如 Google Calendar 或 Microsoft 365 的日历共享与委派设置,也可以在同步接口返回的参会人字段里读出来。下面的骨架用于把权限状态落到配置里,字段名按实际服务替换:
attendees:
- email: a@example.com
calendar_access: writer # 可写,可自动改期
auto_reschedule: true
- email: b@example.com
calendar_access: writer_pending # 可写但需审批
auto_reschedule: false
- email: c@example.com
calendar_access: reader # 只读,仅可询问
auto_reschedule: false记录时建议同时写下权限的来源:是本人共享设置、组织策略,还是同步接口返回。来源不同,权限被撤销时的表现也不同,这是后面判断是否需要暂停自动改期的依据。
给会议和参会人标优先级
优先级要写成可核对的规则,而不是主观印象。常用的可验证维度有三类:发起人身份、会议是否有明确截止时间、是否有外部客户参与。这三类信息一般都能在会议详情里读到,例如发起人字段、日历上的截止标签、参会人邮箱域名。
- 涉及外部客户域名的会议,默认列为不可自动改期,只能询问。
- 当天有明确截止时间或对外发布节点的会议,优先级高于无期限的内部例会。
- 由外部或更上级发起的会议,优先级高于同级内部同步会。
- 参会人里只有一两位能参加、其余可替补的会议,灵活度更高,可优先调整。
把权限和优先级交叉起来看,落到一张可执行的排序表:
| 日历权限 \ 优先级 | 高(外部客户、当日截止) | 中(内部评审、有明确议题) | 低(无议题例会) |
| 可写 | 不动该会议,改同场其他参会人 | 先询问再改 | 直接改期 |
| 需审批 | 不自动动,走审批 | 审批通过后再改 | 审批后改期 |
| 只读 | 不动,只发询问 | 只发询问 | 只发询问 |
这张表的作用是让每次冲突都有同一个判断入口:先看格子落在哪一列,再看权限允许的动作。
构造两个日程冲突做对照
验证方式是自己造冲突,而不是等真实冲突发生。做法是在同一个空闲时间段放两个会议,让参会人权限保持一致,只改优先级这一个变量。
- 选一个空闲时段,创建会议 A:无议题的内部例会,参会人 P1、P2,两人均为可写。
- 在同一时段创建会议 B:涉及外部客户的评审,参会人 P3,同样为可写。
- 触发热区协调,观察 Town 的输出:先询问谁、先动谁的日程、是否动了高优先级那场、是否有日志留痕。
把观察结果填进下面这张记录表,表格是空的验证模板,需要在自己的环境里跑完后再填,不要预先假定结果:
| 场景 | 权限配置 | 优先级配置 | Town 首个动作 | 是否动了高优先级会议 | 是否转人工确认 |
| 对照一 | P1/P2/P3 均可写 | A 低,B 高 |
记录时以系统实际输出为准,比如通知里出现的收件人、日历变更日志里的时间戳和操作对象。如果 Town 先询问低优先级会议的参会人、并且没有动高优先级那场,说明优先级在权限相同时确实起了排序作用。
交换权限变量再跑一次
保留上一次的优先级配置不变,只改一名参会人的权限:把 P1 从只读改为可写,或者反过来把原本可写的 P3 改成只读,然后重复上一步的时间段冲突,记录改期对象有没有变化。
观察的重点是两组对照:
- 如果之前 Town 询问的是高优先级会议的参会人,改权限后变成直接改低优先级那场,说明权限状态参与了对象选择。
- 如果把一名参会人改成只读后,Town 停止自动改期并转为询问,说明只读权限会覆盖原有的优先级排序。
- 如果权限怎么改,Town 动的人都一样,说明当前配置里优先级权重更高,需要回看规则文件确认哪一层在生效。
这一步也可以顺手验证权限读不到时的行为:把同步接口的权限字段临时置空,看系统是当作只读处理,还是直接跳过该参会人。两种处理都会影响结论,需要写进记录表。
把结果写回协调规则
两次对照跑完后,可以得到一个可人工审的判定:如果改权限后改期对象跟着变,就以权限优先作为默认策略;如果权限不变时优先级始终决定动谁,可以把权限当作准入条件、优先级当作排序条件,两层分开配置。多数团队更适合后一种:权限决定谁进入候选集合,优先级决定集合内先动谁。
把判定写成配置,便于下一个人复核:
reschedule_policy:
stage_1_permission:
auto_edit: [writer, writer_pending_approved]
ask_first: [reader, writer_pending]
stage_2_priority:
order: [low, medium, high]
never_move: [external_customer, same_day_deadline]
halt_auto_reschedule_when:
- all_candidates_priority_is_high
- permission_state_unreadable
- organizer_is_external
- attendee_count_over_threshold建议把这些情况列为暂停自动改期的条件:候选集合里全是高优先级会议、权限状态读取失败或字段缺失、发起人来自外部域名、参会人数明显偏多导致影响面过大。命中任意一条,就只发询问、不落笔改期,等人工确认后再执行。
规则写完后,每次冲突处理都留下一条记录:读了哪些权限、用了哪条优先级、动了谁的日程、是否转人工。下次出现相似冲突时,先比对这条记录,再决定要不要调整规则本身。