Skip to content

feat(drive): changes serve — receive Drive push notifications and trigger callbacks #689

Description

@sebsnyk

Motivation

gog drive changes watch already registers an HTTPS webhook channel against the Drive Changes API. The receiving side — the HTTPS endpoint Google posts to — is left as an exercise for the user. Meanwhile, the Gmail side ships a complete push handler at gog gmail watch serve (see internal/cmd/gmail_watch_server.go). The Drive equivalent is missing, which means anyone wanting real-time change events has to roll their own HTTPS receiver, deal with cert/tunnel setup, parse X-Goog-Channel-* headers, persist the pageToken between events, and renew the channel before its TTL expires.

This is the missing half of drive changes watch. With it, end-to-end automation ("fire a script every time something changes on this doc") works out of the box.

Pairs with

Together these four close the comment-driven edit loop: serve (or poll) detects the change, comments list --since enumerates what is new, comments locate resolves the anchor, and an existing surgical command (delete / format / insert-person etc.) acts on the resolved range.

Repro

# Today:
gog drive changes watch --token=... --webhook-url=https://my-server.example.com/hook
# Now the user has to:
#   1. Run an HTTPS server on https://my-server.example.com/hook
#   2. Parse X-Goog-Channel-ID, X-Goog-Channel-Token, X-Goog-Resource-State
#   3. Call `gog drive changes list --token=<saved>` on each notification
#   4. Persist the next pageToken
#   5. Re-call `gog drive changes watch` before the channel expires (max 7d)

Proposed surface

gog drive changes serve [flags]
  --listen=:8443                Local listen address
  --cert=PATH --key=PATH        TLS cert + key (Google requires HTTPS)
  --channel-token=STRING        Expected channel token (rejects mismatched POSTs)
  --state-file=PATH             Where to persist the next pageToken between notifications
  --on-change="<cmd>"           Shell command invoked per notification; JSON payload on stdin
  --filter-file=<id>            Only fire on-change when the change touches this file id
  --auto-renew                  Re-call changes.watch before the channel expires
  --renew-before=10m            How long before expiration to renew (default 10m)
  --drive=STRING                Shared-drive ID for shared-drive change logs
  --foreground                  Stay in the terminal (default; pair with systemd / launchd otherwise)

Payload format for --on-change:

{
  "channelId": "...",
  "resourceState": "change",
  "messageNumber": 17,
  "resourceUri": "...",
  "changes": [{"fileId":"...","time":"...","removed":false}]
}

Mirrors gog gmail watch serve structure: ServeHTTP authenticates by X-Goog-Channel-Token, calls changes.list, optionally invokes the user callback, persists the new token.

Acceptance criteria

  • Validates X-Goog-Channel-Token; returns 401 on mismatch.
  • Returns 200 on success (Google docs accept 200, 201, 202, 204, 102).
  • Persists the next pageToken atomically (no half-writes on crash).
  • --on-change is invoked once per notification with the JSON payload on stdin.
  • --auto-renew re-issues changes.watch at least --renew-before ahead of expiration and rolls over the channel id cleanly.
  • --filter-file=<id> short-circuits before calling on-change when the changes list does not include the target file.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal priority bug or improvement with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.impact:securityThis issue is about security boundaries, credentials, authz, sandboxing, or sensitive data.issue-rating: 🌊 off-meta tidepoolIssue quality rating does not apply to this item.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions