Coding

Calendar Hold Sync

Mirror Google Calendar events as private Busy holds to reduce double-booking across calendars.

What it does

Mirrors events from one or more source Google calendars into one or more target calendars as private Busy holds with no reminders. A JSON config defines mappings, lookahead windows, overlap handling, exclusions, and safety limits; reconciliation creates, updates, or deletes SYNCV1-managed holds idempotently through a preconfigured `gog` CLI.

When to use it

  • Blocking work events on a personal calendar
  • Mirroring availability across multiple Google accounts
  • Running a scheduled reconciliation fallback
  • Upgrading legacy holds with source metadata

The skill document

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.
  2. Run gog auth add you@gmail.com --services calendar.
  3. Verify with gog auth list.

Only add additional Google services if you explicitly need them for another workflow.

Official gog references:

Config Contract

Use a user-provided JSON config file with this shape:

  • mappings[]
  • mappings[].name
  • mappings[].targetAccount
  • mappings[].targetCalendarId (default primary)
  • mappings[].sources[] with { account, calendarId }
  • mappings[].lookaheadDays (default 30)
  • mappings[].allDayMode: ignore|mirror
  • mappings[].overlapPolicy: skip|allow
  • hold.summary (default 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 (optional)
  • scheduling.driftWindowDays (optional)
  • scheduling.watchIntervalSeconds (optional, default 20)
  • safety.dryRun
  • safety.maxChangesPerRun
  • safety.excludeIfSummaryMatches[]
  • safety.excludeIfDescriptionPrefix[]
  • gog.listEventsCmd|createEventCmd|updateEventCmd|deleteEventCmd (optional template overrides)
  • gog.allowCustomCommands (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:

  • SYNCV1:

JSON fields:

  • srcAccount
  • srcCalendar
  • eventId
  • start
  • end
  • title

Behavior

For each mapping:

  1. Read source events in the active window.
  2. Build desired hold events (private, busy, no reminders).
  3. Detect existing managed holds by SYNCV1: prefix.
  4. Reconcile idempotently:
  • Create missing holds.
  • Update drifted holds.
  • Delete stale holds.
  1. If overlap policy is skip, do not create a hold when a non-managed target event overlaps.
  2. Enforce maxChangesPerRun.
  3. 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

  • 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 ]

Watch Cadence

Require watch cadence to be configurable from user config:

  • scheduling.watchIntervalSeconds controls watch poll frequency.
  • mappings[].lookaheadDays controls rolling watch/reconcile window.

Recommend baseline values:

  • watchIntervalSeconds: 900 (15 minutes)
  • lookaheadDays: 1 (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:

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.

Questions people ask

What setup is required before running it?
The `gog` CLI must be in `PATH`, and OAuth must already be configured for every Google account referenced by the mappings. Configuration is supplied in JSON; account emails and calendar or event IDs should not be hardcoded.
How does it avoid duplicate or stale holds?
Each managed hold stores base64url-encoded source linkage under a `SYNCV1:` description prefix. Reconciliation uses that metadata to create missing holds, update drifted ones, and delete stale ones idempotently.
Does it provide real-time calendar updates?
No webhook or push subscription is assumed. Watch mode polls at the configured `watchIntervalSeconds`, so expected latency is roughly the polling interval, and periodic scheduled reconciliation should remain enabled as a fallback.

Related skills

Read availability and manage Google Calendar events through managed OAuth.

345 installs21 stars

Check calendars, find open times, and manage Google Calendar events with confirmation before every change.

by Jay81 installs33 stars

Extract email dates, links, and deadlines for review, then create or update tracked Google Calendar events.

236 installs5 stars

Automate and troubleshoot Google Workspace operations from the terminal with gws.

by Iván68 installs

Manage Nextcloud notes, tasks, calendars, files, contacts, shares, and Deck boards from one JSON CLI.

187 installs9 stars

Generate repo-aware `.gitignore` rules while preserving custom sections outside a managed block.

50 installs