Calendar Hold Sync
Implement hold mirroring from source Google calendars into target calendars to prevent double-booking.
Dependency
- - Require
gog CLI in PATH. - Require user OAuth already configured for each account used in
mappings. - Do not hardcode account emails, calendar IDs, or event IDs in code.
If gog is not configured, use this setup flow:
- 1. Run
gog auth credentials /path/to/client_secret.json. - Run
gog auth add you@gmail.com --services calendar. - Verify with
gog auth list.
Only add additional Google services if you explicitly need them for another workflow.
Official gog references:
- - Homepage: https://gogcli.sh/
- Source: https://github.com/steipete/gogcli
Config Contract
Use a user-provided JSON config file with this shape:
- - INLINECODE8
- INLINECODE9
- INLINECODE10
- INLINECODE11 (default
primary) - INLINECODE13 with INLINECODE14
- INLINECODE15 (default
30) - INLINECODE17 : INLINECODE18
- INLINECODE19 : INLINECODE20
- INLINECODE21 (default
Busy) - INLINECODE23 (
private) - INLINECODE25 (
busy) - INLINECODE27 (
none) - INLINECODE29 (
none) - INLINECODE31 (
SYNCV1) - INLINECODE33 (
base64url(json)) - INLINECODE35 : INLINECODE36
- INLINECODE37
- INLINECODE38 (optional)
- INLINECODE39 (optional)
- INLINECODE40 (optional, default
20) - INLINECODE42
- INLINECODE43
- INLINECODE44
- INLINECODE45
- INLINECODE46 (optional template overrides)
- INLINECODE47 (must be
true to enable any gog.*Cmd override)
Custom Command Template Safety
When custom commands are enabled:
- - Only
gog command templates are accepted. - Templates are rendered by replacing placeholders like
{account} and {calendarId}. - Rendered commands are executed as argv tokens (no shell interpolation).
- Keep
gog.allowCustomCommands=false unless you fully trust and audit the config file.
Metadata Encoding
Store source linkage in hold description as:
JSON fields:
- - INLINECODE56
- INLINECODE57
- INLINECODE58
- INLINECODE59
- INLINECODE60
- INLINECODE61
Behavior
For each mapping:
- 1. Read source events in the active window.
- Build desired hold events (
private, busy, no reminders). - Detect existing managed holds by
SYNCV1: prefix. - Reconcile idempotently:
- - Create missing holds.
- Update drifted holds.
- Delete stale holds.
- 5. If overlap policy is
skip, do not create a hold when a non-managed target event overlaps. - Enforce
maxChangesPerRun. - Respect
dryRun.
Backfill
Backfill mode upgrades legacy hold events (matching expected hold signature but lacking SYNCV1) by attaching encoded metadata when a unique source match exists.
Command Surface
- - INLINECODE69
- INLINECODE70
- INLINECODE71
- INLINECODE72
- INLINECODE73
- INLINECODE74
Watch Cadence
Require watch cadence to be configurable from user config:
- -
scheduling.watchIntervalSeconds controls watch poll frequency. - INLINECODE76 controls rolling watch/reconcile window.
Recommend baseline values:
- -
watchIntervalSeconds: 900 (15 minutes) - INLINECODE78 (24 hours)
Working Model
- - Use polling-based watch mode (
hold-sync watch) for fast updates. - Expect update latency approximately equal to
watchIntervalSeconds. - Treat this as self-hosted/operator-run automation.
Known Limits
- - Do not assume webhook/push subscriptions are present; current fast sync path is polling.
- Keep periodic scheduled reconcile as fallback even when watch mode is enabled.
Required Tests
- - metadata encode/decode round-trip
- overlap detection correctness
- idempotent reconcile upsert/delete behavior
Attribution: gog setup flow adapted from:
- - https://clawhub.ai/steipete/gog
- https://github.com/steipete/gogcli
- https://gogcli.sh/
Provider Notes (openclaw)
Use this variant when publishing to ClawHub/OpenClaw.
- - Keep instructions implementation-focused and command-oriented.
- Keep dependency explicit:
gog must be preconfigured by user. - Prefer deterministic script execution over speculative edits.
- Avoid provider-specific APIs; treat the CLI as the boundary.
日历占位同步
实现从源Google日历到目标日历的占位镜像,以防止重复预订。
依赖项
- - 需要在PATH中安装gog命令行工具。
- 需要为mappings中使用的每个账户预先配置用户OAuth。
- 不要在代码中硬编码账户邮箱、日历ID或事件ID。
如果gog未配置,请使用以下设置流程:
- 1. 运行gog auth credentials /path/to/client_secret.json。
- 运行gog auth add you@gmail.com --services calendar。
- 使用gog auth list验证。
仅当您明确需要其他工作流程时,才添加额外的Google服务。
官方gog参考:
- - 主页:https://gogcli.sh/
- 源码:https://github.com/steipete/gogcli
配置契约
使用用户提供的JSON配置文件,结构如下:
- - mappings[]
- mappings[].name
- mappings[].targetAccount
- mappings[].targetCalendarId(默认primary)
- mappings[].sources[],包含{ account, calendarId }
- mappings[].lookaheadDays(默认30)
- mappings[].allDayMode:ignore|mirror
- mappings[].overlapPolicy:skip|allow
- hold.summary(默认Busy)
- hold.visibility(private)
- hold.transparency(busy)
- hold.notifications(none)
- hold.reminders(none)
- metadata.format(SYNCV1)
- metadata.encoding(base64url(json))
- metadata.fields:srcAccount,srcCalendar,eventId,start,end,title
- scheduling.reconcileCron
- scheduling.daytimeCron(可选)
- scheduling.driftWindowDays(可选)
- scheduling.watchIntervalSeconds(可选,默认20)
- safety.dryRun
- safety.maxChangesPerRun
- safety.excludeIfSummaryMatches[]
- safety.excludeIfDescriptionPrefix[]
- gog.listEventsCmd|createEventCmd|updateEventCmd|deleteEventCmd(可选模板覆盖)
- gog.allowCustomCommands(必须为true才能启用任何gog.*Cmd覆盖)
自定义命令模板安全
启用自定义命令时:
- - 仅接受gog命令模板。
- 模板通过替换{account}和{calendarId}等占位符进行渲染。
- 渲染后的命令作为argv令牌执行(无shell插值)。
- 除非您完全信任并审计配置文件,否则保持gog.allowCustomCommands=false。
元数据编码
在占位事件的description中存储源链接,格式为:
JSON字段:
- - srcAccount
- srcCalendar
- eventId
- start
- end
- title
行为
对于每个映射:
- 1. 读取活动窗口中的源事件。
- 构建所需的占位事件(private、busy、无提醒)。
- 通过SYNCV1:前缀检测现有管理的占位事件。
- 幂等地进行协调:
- 创建缺失的占位事件。
- 更新偏移的占位事件。
- 删除过时的占位事件。
- 5. 如果重叠策略为skip,则在非管理的目标事件重叠时不创建占位事件。
- 强制执行maxChangesPerRun。
- 尊重dryRun。
回填
回填模式通过附加编码的元数据(当存在唯一源匹配时)升级遗留的占位事件(匹配预期的占位签名但缺少SYNCV1)。
命令接口
- - hold-sync validate-config
- hold-sync reconcile --mapping |--all [--dry-run]
- hold-sync backfill --mapping |--all [--dry-run]
- hold-sync status --mapping |--all
- hold-sync install-cron --mapping |--all
- hold-sync watch --mapping |--all [--dry-run] [--interval-seconds ]
监控节奏
要求监控节奏可从用户配置中调整:
- - scheduling.watchIntervalSeconds控制监控轮询频率。
- mappings[].lookaheadDays控制滚动监控/协调窗口。
建议基准值:
- - watchIntervalSeconds: 900(15分钟)
- lookaheadDays: 1(24小时)
工作模型
- - 使用基于轮询的监控模式(hold-sync watch)实现快速更新。
- 预期更新延迟大约等于watchIntervalSeconds。
- 将其视为自托管/操作员运行的自动化。
已知限制
- - 不要假设存在webhook/推送订阅;当前快速同步路径为轮询。
- 即使启用了监控模式,也要保留定期计划的协调作为后备方案。
必需测试
- - 元数据编码/解码往返测试
- 重叠检测正确性测试
- 幂等协调插入/删除行为测试
归属:gog设置流程改编自:
- - https://clawhub.ai/steipete/gog
- https://github.com/steipete/gogcli
- https://gogcli.sh/
提供商说明(openclaw)
在发布到ClawHub/OpenClaw时使用此变体。
- - 保持说明以实现为重点、以命令为导向。
- 保持依赖项明确:gog必须由用户预先配置。
- 优先选择确定性脚本执行而非推测性编辑。
- 避免提供商特定的API;将CLI视为边界。