fix(messaging): enable Telegram/Discord channels and verify bridge after rebuild#4403
Conversation
…ter rebuild OpenClaw 2026.5.22+ no longer auto-starts a messaging bridge from the account-level `enabled` flag alone — the channel must also be marked enabled at the top level for the bridge module to load. NemoClaw#4189 fixed this for Slack; the same gap silently produced "no Telegram process / no logs" for Telegram (NVIDIA#4314, NVIDIA#4390) and would silently break Discord too. Changes: - scripts/generate-openclaw-config.py: bake `channels.<name>.enabled: true` for every credential-backed messaging channel (telegram, discord, slack), not just Slack. - nemoclaw-blueprint/scripts/telegram-diagnostics.js: add a delayed startup-grace timer that emits one actionable breadcrumb when the bridge fails to log "starting provider" within ~15s. Gated to the OpenClaw gateway process flavors (mirrors sandbox-safety-net) so inherited NODE_OPTIONS don't false-positive in unrelated child Node processes. - src/lib/actions/sandbox/policy-channel.ts: after a successful `channels add <channel>` rebuild for telegram/discord/slack on an OpenClaw sandbox, probe the baked openclaw.json and /tmp/gateway.log to confirm the channel is enabled and the bridge logged a startup breadcrumb. Surfaces credential placeholder warnings, the no-start diagnostic, and the slack-channel-guard's "[channels] [<name>]" lines with actionable hints. Skips for Hermes sandboxes and WhatsApp/WeChat (different runtime layouts). - test/generate-openclaw-config.test.ts: assert channels.telegram.enabled and channels.discord.enabled. - test/telegram-diagnostics.test.ts: 4 new tests pinning the startup-grace timer (fires when configured + silent; no-op when bridge logs startup; no-op when channel disabled; no-op in non-gateway processes). - test/channels-add-preset.test.ts: 7 new tests for the post-rebuild bridge verifier (startup confirmation, missing enabled flag, missing breadcrumb, credential warning forwarded, no-start breadcrumb not counted as success, Hermes skip, WhatsApp skip). - test/e2e/test-messaging-providers.sh: M6a/M6b assertions that channels.{telegram,discord}.enabled is true when the block is present, mirroring M6's skip-on-absent pattern for the non-root sandbox path. Fixes NVIDIA#4314 Fixes NVIDIA#4390 Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughMarks messaging channels enabled in generated OpenClaw config, adds a gateway-only Telegram startup-grace watchdog, performs post-rebuild bridge verification, introduces a build-time messaging-plugin installer invoked during image build, and adds extensive E2E fake-provider servers, helpers, and tests validating activation and startup signals. ChangesBridge startup detection and verification
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Warning Review ran into problems🔥 ProblemsStopped waiting for pipeline failures after 30000ms. One of your pipelines takes longer than our 30000ms fetch window to run, so review may not consider pipeline-failure results for inline comments if any failures occurred after the fetch window. Increase the timeout if you want to wait longer or run a Comment |
…g-channel-activation
CI's codebase-growth-guardrails job rejects net-positive Python diffs. Inline the channels.<name>.enabled rationale into a single trailing comment so the change is one line for one line (net 0), and accept shfmt's normalization of case-statement spacing in the new M6a/M6b assertions. Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
…g-channel-activation
# Conflicts: # scripts/generate-openclaw-config.py
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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 `@test/e2e/test-messaging-providers.sh`:
- Around line 383-389: The current env var assignments (TELEGRAM_TOKEN,
DISCORD_TOKEN, SLACK_TOKEN, SLACK_APP) give precedence to *_REAL values which
then leak into CI logs where code prints the first 10 characters; fix by
preserving the precedence but introducing separate safe logging variables (e.g.,
TELEGRAM_TOKEN_LOG, DISCORD_TOKEN_LOG, SLACK_TOKEN_LOG, SLACK_APP_LOG) that are
derived from the same sources but mask or replace real secrets (when
TELEGRAM_BOT_TOKEN_REAL / DISCORD_BOT_TOKEN_REAL / SLACK_BOT_TOKEN_REAL are set
return a fixed placeholder like "<redacted-real>" or a minimal non-secret token
prefix, otherwise show the harmless fake/truncated value); update any logging to
use these *_LOG variables instead of TELEGRAM_TOKEN / DISCORD_TOKEN /
SLACK_TOKEN / SLACK_APP.
- Around line 1138-1141: The assertions calling
assert_openclaw_config_activation for "M6a"/"M6b"/"M6c"/"M6d" unconditionally
cause failures when channel blocks (channels.telegram, channels.discord,
channels.slack, channels.whatsapp) are absent in non-root sandboxes; change the
test to first detect whether each channel block exists and, if absent in
non-root mode, skip the call (or pass an explicit "skipped" expectation) instead
of calling assert_openclaw_config_activation; alternatively modify
assert_openclaw_config_activation to accept a nullable expected state and treat
missing channel blocks as expected skip so M6a/M6b/M6c/M6d do not produce false
negatives.
In `@test/validate-e2e-coverage.test.ts`:
- Around line 259-267: The validator assumes nested objects exist and can throw
TypeError; update the nested lookups around reusableRunner, reusableSecrets,
reusableSecretDefs, runnerJobs, runStepEnv (getStepEnv), workflow.jobs and
messagingJob to use defensive checks/optional chaining and sensible defaults
(e.g., {} or []), e.g., replace direct property accesses with optional chaining
and fallback assignments so missing nodes don’t throw and the test can collect
entries into the missing array; ensure getStepEnv(...) return is defaulted to {}
when undefined and any cast to Record<string, unknown> is only applied after
confirming the value exists.
🪄 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: 489bb9dd-980b-47ef-a02b-c672912f840a
📒 Files selected for processing (18)
.github/workflows/e2e-script.yaml.github/workflows/nightly-e2e.yamlDockerfilescripts/generate-openclaw-config.pyscripts/openclaw-build-messaging-plugins.pysrc/lib/sandbox/build-context.tstest/e2e-script-workflow.test.tstest/e2e/lib/discord-rest-policy-proof.shtest/e2e/lib/fake-discord-message-api.cjstest/e2e/lib/fake-telegram-api.cjstest/e2e/lib/slack-api-proof.shtest/e2e/lib/telegram-api-proof.shtest/e2e/test-messaging-providers.shtest/generate-openclaw-config.test.tstest/openclaw-build-messaging-plugins.test.tstest/sandbox-build-context.test.tstest/sandbox-provisioning.test.tstest/validate-e2e-coverage.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- test/generate-openclaw-config.test.ts
|
Actionable comments posted: 0 |
|
Actionable comments posted: 0 |
|
Actionable comments posted: 0 |
Selective E2E Results — ❌ Some jobs failedRun: 26587189571
|
Selective E2E Results — ❌ Some jobs failedRun: 26587189571
|
Selective E2E Results — ❌ Some jobs failedRun: 26587189571
|
## Summary Refreshes the NemoClaw documentation for the v0.0.54 release and regenerates user skills from the Fern MDX source. Also keeps the Fern CLI pin current so local docs checks use the upgraded Fern version. ## Related Issue <!-- No single related issue. This is release-prep documentation catch-up. --> ## Changes - #4403 -> `docs/manage-sandboxes/messaging-channels.mdx`, `docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Document Telegram, Discord, and Slack post-rebuild bridge verification and summarize channel activation fixes. - #4222 -> `docs/about/release-notes.mdx`: Include Slack generated channel enablement in the v0.0.54 messaging summary. - #4346 -> `docs/get-started/windows-preparation.mdx`, `docs/about/release-notes.mdx`: Document safer Windows bootstrap behavior for Ubuntu first-run and Docker Desktop WSL integration. - #4416 -> `docs/inference/use-local-inference.mdx`, `docs/about/release-notes.mdx`: Document the Docker Desktop WSL requirement for Windows-host Ollama. - #4442 -> `docs/about/release-notes.mdx`: Summarize the optional NemoHermes native web dashboard and related environment variables. - #4426 -> `docs/about/release-notes.mdx`: Summarize copy-paste recovery hints for invalid sandbox names and missing NVIDIA API keys. - #4459 -> `docs/about/release-notes.mdx`: Summarize the Linuxbrew prefix fix for sandbox Homebrew usage. - #4450 -> `docs/about/release-notes.mdx`: Summarize `/nemoclaw` slash command startup activation. - #4468 -> `docs/about/release-notes.mdx`: Summarize scope-upgrade approval recovery. - #4325 -> `docs/about/release-notes.mdx`: Summarize the narrowed `web_fetch` host-gateway allowance. - #4474 -> `docs/about/release-notes.mdx`: Summarize Hermes Provider smoke-check behavior for OAuth versus Nous API key setup. - Refresh generated `.agents/skills/nemoclaw-user-*` references from `docs/` and update `fern/fern.config.json` to Fern `5.41.2`. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [x] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Verification <!-- Check each item you ran and confirmed. Leave unchecked items you skipped. Doc-only changes do not require npm test unless you ran it. --> - [ ] `npx prek run --all-files` passes - [ ] `npm test` passes - [ ] Tests added or updated for new or changed behavior - [x] No secrets, API keys, or credentials committed - [x] Docs updated for user-facing behavior changes - [ ] `npm run docs` builds without warnings (doc changes only) - [x] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) --- <!-- DCO sign-off required by CI. Run: git config user.name && git config user.email --> Signed-off-by: Miyoung Choi <miyoungc@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Optional NemoHermes native web dashboard (configurable port and TUI) * GPU memory cleanup now unloads Ollama models when switching providers or stopping services * **Bug Fixes** * Improved sandbox name validation with suggested slug recovery * Windows-host Ollama now requires Docker Desktop WSL integration and exits with remediation guidance when unsupported * **Documentation** * Clarified quickstart/onboard flow, installer TTY/non‑TTY guidance, Hermes Docker prerequisites, sandbox hardening, and channels add rebuild checks <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/NVIDIA/NemoClaw/pull/4539?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Summary
Fixes #4314
Fixes #4390
This is now the unified messaging-channel PR: it keeps the original #4403 runtime verification path and folds in the full #4400 OpenClaw channel activation / plugin-build / E2E coverage set.
OpenClaw 2026.5.22+ no longer auto-starts a messaging bridge from the account-level
enabledflag alone — the channel must also be marked enabled at the top level for the bridge module to load. NemoClaw#4189 fixed this for Slack (PR #4222); the same gap silently produced "no Telegram process / no logs" for Telegram (#4314, #4390) and would silently break Discord too.This PR:
channels.<name>.enabled: truefor Telegram, Discord, Slack, and WhatsApp in generatedopenclaw.json.plugins.entries.<channel>records so OpenClaw discovers selected messaging providers through its real channel/plugin path.scripts/openclaw-build-messaging-plugins.pyinstead of relying on unversionedopenclaw doctor --fixcatalog drift.nemoclaw <sandbox> channels add <channel>for verifiable OpenClaw channels (telegram/discord/slack), surfacing missing enabled flags, missing startup breadcrumbs, and credential/startup warnings.openclaw channels list --all --jsonruntime discovery checks, pinned plugin build coverage, fake provider APIs, and optional live Telegram/Discord/Slackopenclaw message sendpaths when repository secrets are configured.Reproduction (issue #4390 + #4314)
Before the fix, generated config with Telegram selected during onboarding:
No top-level
enabled: truemeant OpenClaw skipped loading the bridge. No Telegram process spawned,/sandbox/.openclaw/telegram/stayed empty, and no startup/error breadcrumb appeared.After the fix:
The bridge module is loadable, diagnostics can report silent startup failure, and
channels add telegramprobes the rebuilt runtime instead of leaving users with radio silence.Test plan
Local validation on the unified branch:
python3 -m py_compile scripts/generate-openclaw-config.py scripts/openclaw-build-messaging-plugins.pyNEMOCLAW_MESSAGING_CHANNELS_B64=$(printf '%s' '["telegram","discord","slack","whatsapp"]' | base64 | tr -d '\n') OPENCLAW_VERSION=2026.5.22 python3 scripts/openclaw-build-messaging-plugins.py --dry-runbash -n test/e2e/test-messaging-providers.sh test/e2e/lib/discord-rest-policy-proof.sh test/e2e/lib/slack-api-proof.sh test/e2e/lib/telegram-api-proof.shgit diff --check HEAD~1..HEADnpm ci --ignore-scriptsnpm run build:clinpx vitest run test/generate-openclaw-config.test.ts test/openclaw-build-messaging-plugins.test.ts test/sandbox-build-context.test.ts test/sandbox-provisioning.test.ts test/channels-add-preset.test.ts test/telegram-diagnostics.test.ts test/e2e-script-workflow.test.ts test/validate-e2e-coverage.test.ts— 160 passedLive Telegram bot E2E was not run from the local triage worktree because no Telegram bot credential is available locally; the PR wires optional live repository secrets through the nightly reusable workflow and keeps hermetic fake-provider proofs for CI.
DCO
Summary by CodeRabbit
New Features
Bug Fixes
Tests