feat(cron): support Google Chat platform for scheduled messages - #1374
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment was marked as outdated.
This comment was marked as outdated.
This comment has been minimized.
This comment has been minimized.
The platform-configured check read only the GOOGLE_CHAT_ENABLED env var, so a deployment enabling the platform via `[googlechat] enabled = true` (first-class section, #1383) would have its cron jobs rejected at startup by validate_cronjobs. Use GoogleChatConfig::resolve() (config → env → default) — same semantics the adapter itself uses. Align the cronjob.md platform table and the schema note wording. Verified: all-features clippy clean, cron tests 74 pass, bin tests 15 pass, schema conformance green. (Single-feature --features googlechat clippy failure is pre-existing on main, unrelated.)
|
Note LGTM ✅ — Clean, narrow Google Chat cron dispatch wired through the established unified adapter pattern. What This PR DoesGoogle Chat was already supported for inbound messages via the unified gateway adapter, but How It Works
Findings
What's Good (🟢)
Baseline Check
5️⃣ Three Reasons We Might Not Need This PR
|
What problem does this solve?
OpenAB's Google Chat adapter already supports inbound messages and outbound replies through
UnifiedGatewayAdapter, but native cron rejectsplatform = "googlechat"and does not register the adapter with the scheduler.This affects both the latest published beta and current
main.Related to #866. This implements only the Google Chat scheduled-message portion and does not close the broader DM and gateway-target proposal.
This is the core transport prerequisite for cron-driven workflows such as Google Sheets reporting. Sheet reads/writes, meeting retrieval, deduplication, alert evaluation, private space IDs, schedules, and credentials remain agent/deployment configuration and are not added to OpenAB core.
Discord Discussion URL: N/A - maintainer-authored follow-up to #866 and merged PR #1315.
At a Glance — before vs after
Config sample
Prior Art & Industry Research
OpenClaw:
OpenClaw scheduled tasks separates scheduling from delivery and stores an explicit platform and destination using
delivery.channelanddelivery.to. It also treats scheduled delivery as an operator automation path rather than an inbound user event.Hermes Agent:
Hermes scheduled tasks automatically delivers an agent's final response to a configured platform target. Its continuation behavior is platform-specific: thread-capable targets may create threads, while flat surfaces remain top-level.
Other references:
Proposed Solution
googlechatto the scheduler's valid platforms.GoogleChatConfig::resolve().enabled([googlechat] enabled = true→GOOGLE_CHAT_ENABLEDenv → default), matching the first-class-platform-config ADR.googlechatcron key.thread_idat the top level of the configured space.Thread behavior
Google Chat currently ignores OpenAB's
create_topicgateway command. Calling the generic unifiedcreate_threadimplementation would therefore create no remote thread but return a synthetic local thread ID, which could then be used or persisted as though it were a real Google Chat resource.This change avoids that invalid state. Automatic thread creation remains unchanged for Discord, Slack, and Telegram.
Trust behavior
Cron dispatch intentionally does not pass through the inbound Google Chat trust gate because no external user event initiates the run. The authority comes from trusted baseline cron configuration or an enabled writable usercron file.
Consequently,
[googlechat].allowed_userscontrols inbound messages but does not restrict scheduled outbound delivery. Anyone authorized to modify cron configuration can select a space where the Chat app already has permission to post. This PR does not introduce a separate outbound target allowlist.Why this approach?
It follows the narrow registration pattern already merged for Telegram in #1315 and reuses Google Chat's existing outbound adapter instead of adding a second delivery implementation.
The Google Chat-specific thread decision is necessary because the platform adapter does not implement
create_topic. Remaining top-level is safer than manufacturing and persisting a nonexistent thread ID.Known limitations:
Alternatives Considered
Validation
cargo build --features googlechatcargo check --workspacecargo test -p openab-core cron::tests- 74 passedcargo test --workspace- 15 OpenAB, 667 core, and 254 gateway tests passedcargo test --workspace --features unified- 15 OpenAB, 667 core, and 254 gateway tests passedgit diff --checkcargo clippy --workspace -- -D warnings -A clippy::collapsible_else_ifcargo clippy --workspace --features unified -- -D warnings -A clippy::collapsible_else_ifLocal Rust 1.92 additionally reports a pre-existing
clippy::collapsible_else_iffinding atcrates/openab-core/src/pre_seed.rs:471; the repository's required GitHub Clippy jobs pass unchanged.Maintainer update (
4174a0f): merged currentmain(post #1381–#1385/#1387) and fixed the enablement check to be config-first — the original read only theGOOGLE_CHAT_ENABLEDenv var, so a[googlechat] enabled = trueconfig-only deployment would have its cron jobs rejected at startup. Re-verified on the updated branch: all-features clippy clean, cron tests 74 pass, bin tests 15 pass, schema conformance green.Manual integration testing used an every-minute usercron job against a private test Google Chat space. The equivalent scheduled delivery path and agent response were observed through the unified adapter. Private target IDs, credentials, meeting content, and Google Sheets data are intentionally excluded from this PR.
The deployed test build also contained deployment-specific workflow extensions; those are not part of this change.