Skip to content

feat(messaging): add Google Chat channel - #7317

Merged
prekshivyas merged 73 commits into
mainfrom
feat/messaging-channel-integration-googlechat
Aug 1, 2026
Merged

feat(messaging): add Google Chat channel#7317
prekshivyas merged 73 commits into
mainfrom
feat/messaging-channel-integration-googlechat

Conversation

@hunglp6d

@hunglp6d hunglp6d commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds Google Chat as an experimental OpenClaw messaging channel, served at /googlechat on the gateway through a dedicated Google-Chat-only cloudflared tunnel and a loopback webhook proxy. Outbound auth is minted gateway-side (OpenShell google-service-account-jwt provider) and injected by the L7 proxy, so the service-account private key never enters the sandbox. Inbound cert verification and outbound replies both route by hostname through the trusted L7 proxy (the SSRF guard's trusted-proxy modes), so the channel works in the DNS-less proxy-only sandbox — no local DNS resolve, no sentinel IP.

Scope: OpenClaw only. Hermes uses a different inbound model (Cloud Pub/Sub pull, no webhook) and a different credential path, so Hermes Google Chat is a planned follow-up rather than part of this PR.

Supersedes #6120: same change, recommitted as a single verified commit with clean history.

Documentation

https://docs.google.com/document/d/1x5NAXOvxNSPGEsDwDZrButB1Q92Vbc_Q20eAcu7ofxE/edit?tab=t.0

Architecture

Google Chat is the first bridge channel: inbound webhooks are verified inside the sandbox, but the outbound bot token is minted on the host and the service-account private key never enters the sandbox. Two JWTs run in opposite directions — Google signs one that the plugin verifies (inbound), and the gateway signs one to mint the outbound token (outbound).

INBOUND — Google → bot   (Google signs a JWT; the plugin VERIFIES it)

   [GOOGLE]   chat.googleapis.com — signs a JWT, POSTs the webhook
                  │
                  ▼
   [HOST]     cloudflared (dedicated tunnel)
                  │
                  ▼
   [HOST]     loopback webhook proxy — admits only POST /googlechat, 404s all else
                  │                    (the public URL is a webhook pinhole, not the dashboard)
                  ▼
   [HOST]     OpenClaw gateway :18789 — routes /googlechat into the sandbox
                  │
                  ▼
   [SANDBOX]  @openclaw/googlechat plugin
                  │  VERIFY the JWT — fetch Google's certs (GET www.googleapis.com, out through the
                  │  L7 proxy via trusted-proxy-fetch) → check signature + audience + appPrincipal
                  ▼
   [SANDBOX]  agent handles the message


OUTBOUND — bot → Google   (the gateway GENERATES the token; the L7 proxy swaps it in — key never in the sandbox)

   [SANDBOX]  @openclaw/googlechat plugin — builds the reply, stamps «Authorization: Bearer <placeholder>»
                  │  outbound-auth put the placeholder there → the sandbox holds no key, no real token;
                  │  trusted-proxy-fetch routes the send out through the L7 proxy (no local DNS)
                  ▼
   [HOST]     L7 egress proxy
                  │  ① swap «placeholder» → the real Bearer minted by the gateway:
                  │      GENERATE — sign an SA-JWT with private_key → Google OAuth → access token (cached ~1h)
                  │  ② policy-check — chat.googleapis.com, POST/PATCH/DELETE within /v1/spaces
                  ▼
   [GOOGLE]   chat.googleapis.com — user sees the reply

  Note — trusted-proxy-fetch is ROUTING (every plugin→Google call goes via the L7 proxy, no local DNS),
  so it appears in both flows: the inbound cert fetch and the outbound send. The token swap, the
  outbound-auth placeholder, and the JWT verify/generate are each one-directional.

OpenShell Requirement

The Google Chat service-account private key is configured through OpenShell's --secret-material-env (OpenShell#2178), which keeps it off process arguments. That flag ships in OpenShell v0.0.82+; current main pins OpenShell 0.0.85, so the requirement is already satisfied on main — no prerequisite PR.

Related Issue

Parts of #5492

Result

image

Changes

Channel

  • New googlechat manifest (inputs, enrollment notes, render) + built-in registration; served on the shared gateway dashboard port at /googlechat (no host forward — on its own dedicated tunnel, see below).
  • Enroll hooks: tunnel/audience gate (derives the public webhook URL from the cloudflared tunnel), token-paste for the SA JSON (validates the paste is parseable JSON and re-prompts before skip), config prompts (audience, appPrincipal, DM allowlist); channel template resolver + nemoclaw tunnel service wiring.
  • Dedicated webhook tunnel. A Google-Chat-only cloudflared tunnel (separate from nemoclaw tunnel start) fronts a loopback-only webhook proxy that forwards only POST /googlechat (1 MiB body cap) and returns 404 for every other method or path, so the public URL is a narrow webhook pinhole that never exposes the dashboard or control UI. NemoClaw tears down both the proxy and its cloudflared on skip, remove, and destroy.
  • Always skips in non-interactive mode (mirrors WeChat host-QR): enrollment needs manual, out-of-band Google Cloud Console + appPrincipal steps that no environment variable can satisfy, so the tunnel/audience gate skips rather than enroll a half-configured channel that silently 404s on inbound webhooks.
  • appPrincipal discovery sentinel: a blank appPrincipal renders an all-zeros placeholder so the first DM logs unexpected add-on principal: <N> (the real value to copy) instead of a numberless missing add-on principal binding; inert for Google Workspace accounts. Enrollment notes are rewritten into an always-printed capture guide with the exact logs --follow command and the persist-and-rebuild steps.

Gateway reliability

  • Renders gateway.reload.mode=off. OpenClaw rewrites its own config ~60s after boot (auto-enabling default provider plugins); with reactive hot-reload on, that self-write rebuilds the gateway's HTTP route table and drops the Google Chat inbound webhook route, so /googlechat starts returning 404 and the bot goes silent ~60s after every start. The sandbox's openclaw.json is sealed at build time (0600 + integrity hash), so disabling reactive reload is safe; NemoClaw still restarts the gateway explicitly on rebuild / gateway restart.

Inbound + outbound routing (proxy-only sandbox)

  • googlechat-trusted-proxy-fetch boot preload: rewrites the plugin's three googleapis fetch sites (inbound cert verify + all outbound sends/edits) to the SSRF guard's trusted_env_proxy/trusted_explicit_proxy modes, so they skip the local getaddrinfo and route by hostname through the L7 proxy — fixes EAI_AGAIN in the DNS-less netns, no sentinel IP. Interim; clean fix is upstream in OpenClaw (like web_fetch #50650).
  • googlechat network-policy preset scoped to the Chat spaces tree, including PATCH for streaming message edits.

Outbound auth (key out of sandbox)

  • google-chat-bridge OpenShell provider profile + googlechat-bridge-provider onboard wiring: import the profile pre-create, run provider refresh configure --strategy google-service-account-jwt post-create from the pasted SA JSON — the gateway mints/rotates the token and the L7 proxy injects Authorization: Bearer on chat.googleapis.com. The private key is supplied through --secret-material-env, so it never reaches argv; the profile authorizes only the Node runtime for the injected bearer.
  • googlechat-outbound-auth boot preload: load-time rewrite of the plugin's single token producer to emit the OpenShell credential placeholder (revision-less alias, so it resolves to the latest re-minted token and survives rotation) instead of signing in-process.
  • Drops in-sandbox SA-key file delivery for outbound; serviceAccountFile is kept only as a channel-start-gate marker (never delivered or read); keeps the BEGIN PRIVATE KEY secret scan.

Documentation

  • Adds OpenClaw-only setup, onboarding, lifecycle, and security guidance. The docs build completed with zero errors; two pre-existing warnings remain (redirect authentication and light-accent contrast).

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • Doc only (includes code sample changes)

Quality Gates

  • Tests added or updated for changed behavior — unit tests for the two boot preloads (anchor rewrite, idempotency, drift-throw, runtime short-circuit), the bridge provider (env resolution, fail-closed refresh, Node-only credential boundary), the tunnel/audience gate (unconditional non-interactive skip, audience does not bypass), the template resolver (appPrincipal discovery sentinel when blank), and a manifest runtime-security-contract test (both boot preloads present and non-optional, gateway.reload.mode=off rendered, the non-existent serviceAccountFile sentinel, and no credentials delivered into the sandbox)
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification:
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed or maintainer-approved waiver recorded — nine-category review on the predecessor #6120; exact current-main delta review PASS at 8897acb3fbbffcfba59eb8ad27238e566d6292ad, feature diff fingerprint 2badf49554a0bc79fbd104eb88d1f4dfba26ba6f9c52a0b848c0d191653e1e8b. The sync changes no Google Chat feature behavior.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: docs-updated
  • Evidence: Reviewed the complete Google Chat implementation and six documentation paths at current head. The docs accurately cover experimental/OpenClaw-only scope, interactive enrollment, restricted public ingress, service-account handling, access controls, policy, verification, rotation, lifecycle, removal, and destruction. All 33 changed deterministic test files pass 385/385, CLI/plugin builds and typechecks pass, npm run checks:repository passes, and npm run docs passes with 0 errors and two existing warnings.
  • Agent: Codex Desktop

Verification

  • PR description includes a Signed-off-by: line and every commit appears as Verified in GitHub
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run check:diff passed when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Hung Le hple@nvidia.com
Signed-off-by: Carlos Villela cvillela@nvidia.com

Summary by CodeRabbit

  • New Features
    • Added experimental Google Chat messaging for OpenClaw sandboxes.
    • Added interactive setup with service-account credentials, public HTTPS webhooks, audience controls, and user allowlists.
    • Added lifecycle controls for the dedicated webhook endpoint.
  • Bug Fixes
    • Improved cleanup reliability when webhook shutdown fails, preserving channel state for retry.
    • Improved fail-closed behavior for incomplete or invalid configuration.
  • Documentation
    • Added Google Chat setup and onboarding guidance.
  • Security
    • Added credential validation, masked secret entry, protected token handling, and restricted webhook routing.

Adds a manifest-first Google Chat channel: inbound webhook via the public tunnel, and
outbound replies authenticated by a gateway-minted service-account token. The private key
is configured through OpenShell's --secret-material-env, so it never appears in argv and
never enters the sandbox. Includes the network policy preset, appPrincipal capture flow
for personal/standalone accounts, DM allowlist, and tests.

Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Hung Le <hple@nvidia.com>
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds experimental Google Chat messaging support for OpenClaw sandboxes. It adds channel configuration, webhook enrollment, bridge-provider token minting, runtime patches, lifecycle handling, documentation, CI updates, and E2E coverage.

Changes

Google Chat Channel Integration

Layer / File(s) Summary
Channel contracts and registry wiring
src/lib/messaging/channels/googlechat/*, src/lib/messaging/channels/built-ins.ts, src/lib/messaging/hooks/builtins.ts, src/lib/messaging/applier/build/*
Defines the Google Chat manifest, policy, provider profile, configuration resolvers, hooks, package trust, and built-in registry integration.
Secret masking and token enrollment
src/lib/credentials/store.ts, src/lib/messaging/hooks/common/*, src/lib/messaging/manifest/types.ts
Adds capped secret masking, token validation and retry controls, and service-account JSON enrollment validation.
Webhook tunnel and audience enrollment
src/lib/messaging/channels/googlechat/hooks/*, src/lib/messaging/channels/googlechat/tunnel/*, src/lib/tunnel/services.ts
Implements interactive and capability-gated enrollment, a sandbox-scoped tunnel, and a route-restricted /googlechat proxy.
Gateway bridge-provider provisioning
src/lib/onboard/messaging-bridge-provider.ts, src/lib/onboard/messaging-prep.ts, src/lib/onboard/providers.ts
Discovers provider profiles, creates pending token definitions, imports profiles, and configures gateway-side refresh material through environment injection.
Runtime auth and trusted-proxy patches
src/lib/messaging/channels/googlechat/runtime/*
Rewrites bundled Google Chat authentication and fetch behavior at load time, with idempotency, drift detection, and composition tests.
Channel and sandbox lifecycle wiring
src/lib/actions/sandbox/*, src/lib/onboard.ts, src/lib/onboard/messaging-channel-setup.ts
Connects tunnel and bridge dependencies to channel add/remove, onboarding, sandbox destruction, provider cleanup, and fail-closed teardown.
Documentation, CI, and live E2E coverage
docs/manage-sandboxes/*, docs/index.yml, ci/*, test/e2e/live/*, test/e2e/support/*
Documents Google Chat setup and lifecycle behavior, updates CI policy, and adds live stop/start composition and progress coverage.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Onboarding
  participant AudienceGateHook
  participant TunnelRuntime
  participant Cloudflared
  participant WebhookProxy
  Onboarding->>AudienceGateHook: enroll googlechat
  AudienceGateHook->>TunnelRuntime: start sandbox-scoped tunnel
  TunnelRuntime->>Cloudflared: start public endpoint
  TunnelRuntime->>WebhookProxy: start /googlechat proxy
  WebhookProxy-->>TunnelRuntime: report readiness
  TunnelRuntime-->>AudienceGateHook: return audience URL
  AudienceGateHook-->>Onboarding: persist googlechat audience
Loading
sequenceDiagram
  participant MessagingPrep
  participant BridgeProvider
  participant OpenShell
  participant Gateway
  MessagingPrep->>BridgeProvider: collect bridge token definitions
  BridgeProvider-->>MessagingPrep: return pending token definitions
  BridgeProvider->>OpenShell: import provider profile
  BridgeProvider->>OpenShell: configure refresh material through env
  OpenShell->>Gateway: mint Google Chat access token
Loading

Possibly related PRs

Suggested labels: area: onboarding, area: security, area: e2e

Suggested reviewers: cjagwani, cv

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.85% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the main change: adding Google Chat as a messaging channel.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/messaging-channel-integration-googlechat

Comment @coderabbitai help to get the list of available commands.

@github-code-quality

github-code-quality Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit a5ac963 in the feat/messaging-chann... branch remains at 96%, unchanged from commit b5aaa27 in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit a5ac963 in the feat/messaging-chann... branch remains at 81%, unchanged from commit b5aaa27 in the main branch.

Show a code coverage summary of the most impacted files.
File main b5aaa27 feat/messaging-chann... a5ac963 +/-
src/lib/credentials/store.ts 61% 55% -6%
src/lib/onboard/docker-cdi.ts 70% 80% +10%
src/lib/messagi...-proxy-fetch.ts 0% 71% +71%
src/lib/messagi...nnel-runtime.ts 0% 71% +71%
src/lib/messagi...utbound-auth.ts 0% 75% +75%
src/lib/messagi...tunnel/proxy.ts 0% 88% +88%
src/lib/messagi...udience-gate.ts 0% 90% +90%
src/lib/onboard...dge-provider.ts 0% 99% +99%
src/lib/messagi...-token-paste.ts 0% 100% +100%
src/lib/messagi...ate-resolver.ts 0% 100% +100%

Updated August 01, 2026 12:01 UTC

Comment thread src/lib/tunnel/googlechat-webhook-proxy.ts Fixed
Comment thread src/lib/tunnel/googlechat-webhook-proxy.ts Fixed
@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: Review the warnings below.
Findings: 0 blockers · 1 warning · 0 suggestions

Model lanes

  • GPT-5.6 Terra (primary): Completed · medium confidence · 0 blockers · 1 warning · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Completed · high confidence · 0 blockers · 1 warning · 0 suggestions
  • Model comparison: normalized findings differ; normalized E2E selections differ; severity counts match.
3 additional E2E selections from the second opinion

Advisory only. The primary lane did not select these E2E jobs or targets.

  • openclaw-slack-pairing: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • openclaw-discord-pairing: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • rebuild-openclaw: The completed second-opinion lane identified E2E coverage that the primary lane omitted.

Second-opinion E2E selections are advisory. They do not change the primary assessment or E2E / PR Gate.

E2E guidance

Advisory only. E2E / PR Gate selects and runs jobs independently.

Recommended E2E: cloud-inference, cloud-onboard, security-posture, channels-add-remove, channels-stop-start, inference-routing, network-policy, onboard-repair, onboard-resume

4 optional E2E recommendations
  • ubuntu-repo-cloud-openclaw
  • tunnel-lifecycle
  • messaging-providers
  • openshell-credential-generation-window
1 warning · 0 suggestions

Warnings

Warnings do not block.

PRA-1 Warning — Cover orphaned Google Chat endpoint removal

  • Location: src/lib/actions/sandbox/policy-channel.ts:1659
  • Category: tests
  • Problem: Google Chat removal stops its dedicated endpoint even when registry, policy, session, and messaging-plan residue is absent, but checked-in tests cover only teardown failure after a configured channel. The orphan-recovery path can regress without a test.
  • Impact: An interrupted enrollment can leave a public endpoint running. A later refactor could skip its teardown when no durable channel record exists, leaving the endpoint orphaned.
  • Recommendation: Add a remove-channel regression test with no Google Chat registry, policy, session, or plan residue. Assert tunnel teardown runs and the command completes through the existing generic cleanup path without creating or persisting channel state.
  • Verification: Inspect test/channels-add-bridge-lifecycle.test.ts and add a case adjacent to the existing teardown-failure test.
  • Test coverage: Call removeSandboxChannel for googlechat with no channel residue. Assert stopGooglechatWebhookTunnel is called, no policy or registry write creates channel state, and generic provider cleanup follows its current behavior.
  • Evidence: src/lib/actions/sandbox/policy-channel.ts:1652-1676 invokes stopGooglechatWebhookTunnel before checking downstream channel state and says it applies when registry residue is absent. test/channels-add-bridge-lifecycle.test.ts covers configured-channel teardown and teardown failure, but contains no no-residue orphan-recovery case. src/lib/actions/sandbox/policy-channel.ts:1678-1701 clears tokens and calls applyChannelRemoveToGatewayAndRegistry after successful Google Chat tunnel teardown. src/lib/actions/sandbox/policy-channel.ts:1652-1676 establishes that the tunnel teardown also runs without registry residue.

Workflow run details

This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/lib/messaging/channels/googlechat/runtime/googlechat-outbound-auth.ts (1)

225-255: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the shared CommonJS/ESM source-rewrite loader infrastructure into one module.

isOpenClawGooglechatFile, errorMessage, fileNameFromModuleUrl, sourceToText, createComposableJsLoader, and the installXPatch shape are duplicated near-verbatim between these two files (and reportedly a third, slack-channel-guard.ts, per the in-file comments). Only patchSource/the anchor regexes actually differ per patch.

  • src/lib/messaging/channels/googlechat/runtime/googlechat-outbound-auth.ts#L225-L255: keep only patchGooglechatOutboundAuthSource here; delegate createComposableJsLoader, sourceToText, fileNameFromModuleUrl, errorMessage, and the file-matcher to a shared helper module (parameterized by channel name/path fragment).
  • src/lib/messaging/channels/googlechat/runtime/googlechat-trusted-proxy-fetch.ts#L245-L275: same — keep only patchTrustedProxyFetchSource and delegate the rest to the shared helper.

This keeps the two channel-specific files focused on their actual patch logic and avoids a third drifted copy the next time a channel needs this pattern.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/messaging/channels/googlechat/runtime/googlechat-outbound-auth.ts`
around lines 225 - 255, Extract the duplicated CommonJS/ESM rewrite
infrastructure into a shared helper module, parameterized by channel name/path
fragment and preserving the existing installXPatch shape. In
src/lib/messaging/channels/googlechat/runtime/googlechat-outbound-auth.ts lines
225-255, retain only patchGooglechatOutboundAuthSource and delegate
createComposableJsLoader, sourceToText, fileNameFromModuleUrl, errorMessage, and
isOpenClawGooglechatFile; apply the same change in
src/lib/messaging/channels/googlechat/runtime/googlechat-trusted-proxy-fetch.ts
lines 245-275, retaining only patchTrustedProxyFetchSource and delegating the
shared helpers.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/manage-sandboxes/enable-channels-during-onboarding.mdx`:
- Line 12: Remove the runtime AgentOnly import from the onboarding documentation
while preserving any build-time AgentOnly directive usage.

In `@src/lib/messaging/channels/googlechat/manifest.ts`:
- Around line 106-117: Update the explanatory comment above credentials in the
manifest to reference the actual messaging bridge provider implementation at
src/lib/onboard/messaging-bridge-provider.ts instead of the nonexistent
googlechat-bridge-provider.ts path; leave the surrounding authentication
description unchanged.

In `@src/lib/messaging/channels/googlechat/runtime/googlechat-outbound-auth.ts`:
- Around line 264-281: Gate both Module.registerHooks loaders in
src/lib/messaging/channels/googlechat/runtime/googlechat-outbound-auth.ts:264-281
and
src/lib/messaging/channels/googlechat/runtime/googlechat-trusted-proxy-fetch.ts:284-301
on a Node version known to support synchronous hooks, skipping them for Node
22.19.0 through 22.22.2, or raise the repository minimum to a fixed release.
Ensure affected versions never invoke nextLoad for unrelated module loads.

---

Nitpick comments:
In `@src/lib/messaging/channels/googlechat/runtime/googlechat-outbound-auth.ts`:
- Around line 225-255: Extract the duplicated CommonJS/ESM rewrite
infrastructure into a shared helper module, parameterized by channel name/path
fragment and preserving the existing installXPatch shape. In
src/lib/messaging/channels/googlechat/runtime/googlechat-outbound-auth.ts lines
225-255, retain only patchGooglechatOutboundAuthSource and delegate
createComposableJsLoader, sourceToText, fileNameFromModuleUrl, errorMessage, and
isOpenClawGooglechatFile; apply the same change in
src/lib/messaging/channels/googlechat/runtime/googlechat-trusted-proxy-fetch.ts
lines 245-275, retaining only patchTrustedProxyFetchSource and delegating the
shared helpers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 22d36853-0225-44c0-84fd-db82510b6b78

📥 Commits

Reviewing files that changed from the base of the PR and between d5fa194 and 0345f3b.

📒 Files selected for processing (56)
  • ci/reviewed-npm-lifecycle-allowlist.json
  • docs/index.yml
  • docs/manage-sandboxes/add-channels-after-onboarding.mdx
  • docs/manage-sandboxes/enable-channels-during-onboarding.mdx
  • docs/manage-sandboxes/manage-messaging-channels.mdx
  • docs/manage-sandboxes/messaging-channels.mdx
  • docs/manage-sandboxes/set-up-google-chat.mdx
  • src/lib/actions/sandbox/destroy.ts
  • src/lib/actions/sandbox/policy-channel-dependencies.ts
  • src/lib/actions/sandbox/policy-channel.ts
  • src/lib/messaging-channel-config.test.ts
  • src/lib/messaging/applier/build/messaging-build-applier.mts
  • src/lib/messaging/channels/built-ins.ts
  • src/lib/messaging/channels/googlechat/hooks/index.ts
  • src/lib/messaging/channels/googlechat/hooks/tunnel-audience-gate.test.ts
  • src/lib/messaging/channels/googlechat/hooks/tunnel-audience-gate.ts
  • src/lib/messaging/channels/googlechat/hooks/tunnel-runtime.test.ts
  • src/lib/messaging/channels/googlechat/hooks/tunnel-runtime.ts
  • src/lib/messaging/channels/googlechat/manifest.ts
  • src/lib/messaging/channels/googlechat/policy/openclaw.yaml
  • src/lib/messaging/channels/googlechat/provider-profile/openclaw.yaml
  • src/lib/messaging/channels/googlechat/rendered-config-parser.ts
  • src/lib/messaging/channels/googlechat/runtime/googlechat-outbound-auth.test.ts
  • src/lib/messaging/channels/googlechat/runtime/googlechat-outbound-auth.ts
  • src/lib/messaging/channels/googlechat/runtime/googlechat-trusted-proxy-fetch.test.ts
  • src/lib/messaging/channels/googlechat/runtime/googlechat-trusted-proxy-fetch.ts
  • src/lib/messaging/channels/googlechat/template-resolver.test.ts
  • src/lib/messaging/channels/googlechat/template-resolver.ts
  • src/lib/messaging/channels/manifests.test.ts
  • src/lib/messaging/channels/metadata.test.ts
  • src/lib/messaging/channels/rendered-config-parser.ts
  • src/lib/messaging/channels/template-resolver.ts
  • src/lib/messaging/diagnostics.test.ts
  • src/lib/messaging/hooks/builtins.ts
  • src/lib/messaging/hooks/hook-runner.test.ts
  • src/lib/messaging/utils.test.ts
  • src/lib/onboard/messaging-bridge-provider.test.ts
  • src/lib/onboard/messaging-bridge-provider.ts
  • src/lib/onboard/messaging-prep.test.ts
  • src/lib/onboard/messaging-prep.ts
  • src/lib/onboard/providers.ts
  • src/lib/sandbox/channels.test.ts
  • src/lib/state/openclaw-managed-extensions.test.ts
  • src/lib/tunnel/googlechat-webhook-lifecycle.test.ts
  • src/lib/tunnel/googlechat-webhook-lifecycle.ts
  • src/lib/tunnel/googlechat-webhook-proxy.test.ts
  • src/lib/tunnel/googlechat-webhook-proxy.ts
  • src/lib/tunnel/services.ts
  • test/channels-add-bridge-lifecycle.test.ts
  • test/channels-add-preset.test.ts
  • test/destroy-cleanup-sandbox-services.test.ts
  • test/e2e/live/channels-stop-start-helpers.ts
  • test/e2e/live/channels-stop-start-progress.ts
  • test/e2e/support/channels-stop-start-progress.test.ts
  • test/messaging-build-applier-integrity.test.ts
  • test/onboard-readiness.test.ts

Comment thread docs/manage-sandboxes/enable-channels-during-onboarding.mdx Outdated
Comment thread src/lib/messaging/channels/googlechat/manifest.ts
hunglp6d added 2 commits July 21, 2026 17:18
Signed-off-by: Hung Le <hple@nvidia.com>
@sandl99
sandl99 marked this pull request as draft July 21, 2026 13:42
@copy-pr-bot

copy-pr-bot Bot commented Jul 21, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@github-actions

Copy link
Copy Markdown
Contributor

@NVIDIA NVIDIA deleted a comment from coderabbitai Bot Jul 21, 2026
@wscurran wscurran added area: messaging Messaging channels, bridges, manifests, or channel lifecycle feature PR adds or expands user-visible functionality integration: openclaw OpenClaw integration behavior labels Jul 21, 2026
hunglp6d and others added 13 commits July 22, 2026 11:49
…plyPreset

Signed-off-by: Hung Le <hple@nvidia.com>
… import

Signed-off-by: Hung Le <hple@nvidia.com>
Signed-off-by: Hung Le <hple@nvidia.com>
- Group the webhook, appPrincipal, and service-account guidance into aligned
  left-rail blocks, color the webhook URL, and add blank-line spacing before
  configuration prompts.
- Cap the masked echo for a long pasted secret (the service-account JSON) with
  an "(and N more characters)" tail and support word-delete in the masked prompt.
- Add opt-in re-prompts (maxTokenAttempts) and a Google Chat-owned token-paste
  hook that rejects an unparseable service-account JSON at the prompt instead of
  aborting onboarding later at token minting.
- Make the tunnel/audience gate the single source of the webhook audience.
- Suppress the harmless "profile not found" probe output when registering the
  bridge provider profile, and surface only an unexpected probe error.
- Rename the e2e stop/start heartbeat local to avoid colliding with the merged
  progress fixture.

Signed-off-by: Hung Le <hple@nvidia.com>
…ract test

Signed-off-by: Hung Le <hple@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@cjagwani

Copy link
Copy Markdown
Collaborator

Exact-head babysitter update for 58ab1b404 after the one-hour quiet window:

The earlier sandbox-scoped PID-directory, teardown ordering, stored-credential validation, proxy-header filtering, and architecture-cycle findings are fixed on this head. I am not requesting additional changes through review state, and I am not approving while the current exact-head gates are red.

Remaining blockers:

  • codebase-growth-guardrails fails because src/lib/messaging/channels/googlechat/hooks/service-account-token-paste.test.ts adds an if statement; the repository test-conditional budget requires linear test bodies or a named helper.
  • Trusted channels-stop-start (openclaw) E2E reached the Google Chat capability path and failed because test/e2e/live/channels-stop-start-googlechat-entry.ts imports named export addSandboxChannel, but src/lib/actions/sandbox/policy-channel.ts does not expose that named ESM export in the live Node invocation.
  • The current-head CodeRabbit thread in src/lib/onboard/messaging-channel-setup.test.ts is valid: raw Object.assign(process.env, ...) mutations are not restored by vi.unstubAllEnvs(), so those six variables can leak into later tests. Use tracked env stubs or explicit restoration.
  • The visible stale review decision still needs the original reviewer to clear it once the exact-head CI and E2E evidence are green.

No workflow rerun is useful before the deterministic failures above are addressed. I will re-enter the one-hour quiet hold on the next contributor commit and re-review that exact head.

@hunglp6d

hunglp6d commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator Author

Status update

CI is green on 36584b6, including E2E / PR Gate — the channels-stop-start (openclaw) path that was failing on the Google Chat import now passes end-to-end. B1/B2 fixed by @apurvvkumaria (27c209593, 682f6c41a); the CodeRabbit env-leak fixed in 6acc24866 (tracked vi.stubEnv).

The one red check — PR review advisor (Nemotron 3 Ultra) — is a non-deterministic flake, not a finding: the failing lane alternates run-to-run (Terra on fa63aa2, Nemotron on 36584b6), only the post-analysis Verify advisor analysis outcome step fails, and the advisor's own verdict is 0 blockers · 0 warnings · 0 suggestions. Advisory / non-blocking; a re-run clears it.

@cjagwani — the exact-head deterministic gates are green on 36584b6 (E2E / PR Gate passed; the only red is the advisor-lane flake above). Per your note the E2E evidence is green, so this head should be ready for re-review after the hold.
@cv — per @cjagwani's note the stale CHANGES_REQUESTED needs the original reviewer to clear it; the Google Chat wiring was reworked substantially since July 26 and CI + E2E are now green.
@laitingsheng — thanks for the thorough review; every one is addressed on this head. Thanks @apurvvkumaria for the guardrail and composition fixes.

@prekshivyas
prekshivyas enabled auto-merge (squash) August 1, 2026 10:16
@prekshivyas
prekshivyas merged commit 77ebb5b into main Aug 1, 2026
45 checks passed
@prekshivyas
prekshivyas deleted the feat/messaging-channel-integration-googlechat branch August 1, 2026 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: messaging Messaging channels, bridges, manifests, or channel lifecycle feature PR adds or expands user-visible functionality integration: openclaw OpenClaw integration behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants