Skip to content

feat(channel): add wecom_ws AI bot channel#3305

Closed
whtiehack wants to merge 3 commits intozeroclaw-labs:masterfrom
whtiehack:pr/wecom-upstream
Closed

feat(channel): add wecom_ws AI bot channel#3305
whtiehack wants to merge 3 commits intozeroclaw-labs:masterfrom
whtiehack:pr/wecom-upstream

Conversation

@whtiehack
Copy link
Copy Markdown
Contributor

@whtiehack whtiehack commented Mar 12, 2026

Summary

  • Base branch target (master for all contributions): master
  • Problem: after PR feat(channel): add WeCom Bot Webhook channel #3439 merged on March 13, 2026, channels_config.wecom is now the webhook-based WeCom bot on master, so the long-connection AI bot work in this PR needed a non-conflicting channel/config identity.
  • Why it matters: deployments that rely on the WeCom AI bot long connection still need native inbound chat handling, streaming replies, attachment handling, and proactive announcement delivery through the active WebSocket session.
  • What changed: retargeted the feature as a new optional wecom_ws channel with channels_config.wecom_ws, added the long-connection WebSocket channel/runtime implementation, allowlists, attachment download/decrypt handling, stream_mode, WeCom-specific conversation/history handling, and scheduler delivery through the active connected wecom_ws channel instance.
  • What did not change (scope boundary): no docs changes in this PR, no changes to the existing webhook-based channels_config.wecom channel, no pairing flow changes, and no intended behavior change for non-WeCom channels beyond the shared live-channel registry/runtime plumbing required for active-session announcement routing.

Label Snapshot (required)

  • Risk label (risk: low|medium|high): risk: medium
  • Size label (size: XS|S|M|L|XL, auto-managed/read-only): auto-managed/read-only (expected: L)
  • Scope labels (core|agent|channel|config|cron|daemon|doctor|gateway|health|heartbeat|integration|memory|observability|onboard|provider|runtime|security|service|skillforge|skills|tool|tunnel|docs|dependencies|ci|tests|scripts|dev, comma-separated): channel, config, cron, dependencies
  • Module labels (<module>: <component>, for example channel: telegram, provider: kimi, tool: shell): channel: wecom
  • Contributor tier label (trusted contributor|experienced contributor|principal contributor|distinguished contributor, auto-managed/read-only; author merged PRs >=5/10/20/50): auto-managed/read-only
  • If any auto-label is incorrect, note requested correction: None

Change Metadata

  • Change type (bug|feature|refactor|docs|security|chore): feature
  • Primary scope (runtime|provider|channel|memory|security|ci|docs|multi): channel

Linked Issue

Supersede Attribution (required when Supersedes # is used)

  • Superseded PRs + authors (#<pr> by @<author>, one per line): N.A.
  • Integrated scope by source PR (what was materially carried forward): N.A.
  • Co-authored-by trailers added for materially incorporated contributors? (Yes/No): No
  • If No, explain why (for example: inspiration-only, no direct code/design carry-over): This PR does not supersede or materially incorporate another contributor PR.
  • Trailer format check (separate lines, no escaped \n): (Pass/Fail): Pass

Validation Evidence (required)

Commands and result summary:

cargo fmt --all -- --check
cargo clippy --all-targets -- -D warnings
cargo test wecom_ws --lib
cargo test   # currently fails on unrelated upstream/master baseline tests in config/schema, security/policy, and web_search_tool
  • Evidence provided (test/log/trace/screenshot/perf): local fmt and clippy are clean; all wecom_ws-targeted unit tests pass, including the migrated non-blocking WebSocket callback tests from commit 1f9a3538fbe1218fe31a13b55c240b26f06f87b9.
  • If any command is intentionally skipped, explain why: Full cargo test was executed, but current upstream/master still has unrelated baseline failures (for example config::schema::* missing data_retention, security::policy::workspace_only_false_allows_resolved_outside_workspace, and tools::web_search_tool::* config-parse failures). Those failures are outside this PR's touched files.

Security Impact (required)

  • New permissions/capabilities? (Yes/No): Yes
  • New external network calls? (Yes/No): Yes
  • Secrets/tokens handling changed? (Yes/No): Yes
  • File system access scope changed? (Yes/No): Yes
  • If any Yes, describe risk and mitigation: This adds an optional inbound/outbound long-connection WeCom channel with a new encrypted secret, WebSocket traffic, and attachment download/decrypt/persist logic. Risk is bounded by opt-in configuration, explicit allowed_users / allowed_groups allowlists, attachment size limits, workspace-scoped file caching, and retention cleanup.

Privacy and Data Hygiene (required)

  • Data-hygiene status (pass|needs-follow-up): pass
  • Redaction/anonymization notes: Tests and messages use neutral placeholders such as zeroclaw_user and zeroclaw_group.
  • Neutral wording confirmation (use ZeroClaw/project-native labels if identity-like wording is needed): Confirmed.

Compatibility / Migration

  • Backward compatible? (Yes/No): Yes
  • Config/env changes? (Yes/No): Yes
  • Migration needed? (Yes/No): Only for previous PR reviewers/users of this branch
  • If yes, exact upgrade steps: rename [channels_config.wecom] from the old PR version to [channels_config.wecom_ws]; keep [channels_config.wecom] reserved for the upstream webhook channel introduced by PR feat(channel): add WeCom Bot Webhook channel #3439.

i18n Follow-Through (required when docs or user-facing wording changes)

  • i18n follow-through triggered? (Yes/No): No

Human Verification (required)

What was personally validated beyond CI:

  • Verified scenarios: channel registration, wecom_ws config serde/defaults, runtime command parsing, conversation-key routing, stream-mode behavior, access-control decisions, non-blocking WebSocket callback dispatch, and scheduler delivery wiring through the active live channel registry.
  • Edge cases checked: empty allowlists deny inbound messages, * wildcards allow access, group denials include chatid, stream_mode = "off" disables draft updates, and callback dispatch does not block when the framework queue is full or when access-denied replies are still waiting for WebSocket ack.
  • What was not verified: live tenant-level WeCom interoperability across multiple enterprise environments.

Side Effects / Blast Radius (required)

  • Affected subsystems/workflows: channel startup/registry, channel message routing/history handling, scheduler announcement delivery, config schema, and optional wecom_ws attachment caching.
  • Potential unintended effects: WeCom WS-specific conversation scoping or active-channel announcement routing could regress if shared channel abstractions change.
  • Guardrails/monitoring for early detection: optional channel config, explicit allowlists, deterministic unit tests for access control/dispatch behavior, and runtime logs for connection/send failures.

Agent Collaboration Notes (recommended)

  • Agent tools used (if any): Codex local CLI workflow.
  • Workflow/plan summary (if any): reset the branch onto current upstream/master, removed docs from scope, retargeted the long-connection implementation from wecom to wecom_ws, merged the later non-blocking callback fix from commit 1f9a3538fbe1218fe31a13b55c240b26f06f87b9, then revalidated the affected path.
  • Verification focus: wecom_ws config/runtime wiring, callback responsiveness, allowlists, streaming behavior, and proactive delivery through the live channel registry.
  • Confirmation: naming + architecture boundaries followed (AGENTS.md + CONTRIBUTING.md): Yes

Rollback Plan (required)

  • Fast rollback command/path: revert this PR commit, or remove [channels_config.wecom_ws] from deployments that should not start the long-connection channel.
  • Feature flags or config toggles (if any): wecom_ws support is fully opt-in via [channels_config.wecom_ws]; stream_mode can be set to off.
  • Observable failure symptoms: wecom_ws fails to connect, proactive sends report wecom_ws channel is not connected, or inbound messages are denied due to missing/misconfigured allowlists.

Risks and Mitigations

  • Risk: the WeCom AI bot long-connection/media payload contract may vary across tenants/runtime conditions.
    • Mitigation: defensive parsing, explicit response/error handling, retries for streaming conflicts, and bounded attachment processing.
  • Risk: retargeting from wecom to wecom_ws may surprise anyone testing older iterations of this PR.
  • Risk: proactive delivery depends on an active connected wecom_ws session.
    • Mitigation: scheduler delivery now checks the live-channel registry and returns a clear error when the WS channel is not connected.

@whtiehack
Copy link
Copy Markdown
Contributor Author

whtiehack commented Mar 16, 2026

Hey @theonlyhennygod — heads up regarding #3439.

I see that #3439 implements a WeCom outbound-only channel via the Bot Webhook API (/cgi-bin/webhook/send), which makes sense for push notifications and alerts.

Just wanted to flag that WeCom actually has two distinct API modes for its AI Bot (智能机器人), and they serve very different purposes:

Bot Webhook (outbound-only) WebSocket Long Connection (bidirectional)
Direction Send-only (push to group) Full duplex — receive & reply messages
Use case Notifications, alerts Interactive AI bot conversations
Server requirement None No public IP needed
Encryption N/A Not required (plaintext JSON)
Streaming Not supported Native stream-based reply
Status Basic utility Recommended for AI bot (per official docs, updated 2026/03/10)

This PR (#3305) implements the WebSocket long-connection mode for a full bidirectional AI Bot channel, including:

  • Inbound message receiving + outbound reply
  • Stream-based reply with stream.id flow control
  • Heartbeat keepalive + auto-reconnect
  • Media download & AES decryption
  • Proactive message push (aibot_send_msg)
  • Sender/group allowlists

This has been tested and verified against a live WeCom deployment.

Since #3439 covers outbound-only and this PR covers the full AI bot — how should we handle these? Should they coexist as separate channels, or should this PR supersede #3439 since it already includes outbound capabilities?

@whtiehack
Copy link
Copy Markdown
Contributor Author

whtiehack commented Mar 16, 2026

@theonlyhennygod — regarding the linked issues:

How would you like to proceed? Should this PR handle the bidirectional AI bot use case while #3439 stays as a lightweight outbound-only option, or would you prefer consolidating into one?

@whtiehack
Copy link
Copy Markdown
Contributor Author

If the team is open to adding the AI Bot channel, I'm happy to take on WeCom-related issues going forward. I'm based in China and my company uses WeCom daily, so I can understand the requirements and debug issues more easily.

@chengongpp
Copy link
Copy Markdown

If the team is open to adding the AI Bot channel, I'm happy to take on WeCom-related issues going forward. I'm based in China and my company uses WeCom daily, so I can understand the requirements and debug issues more easily.

Wecom daily user too, thanks a lot for your support. I'm gonna try wecom bot multiplexing considering multiple users (and their credentials) using one bot is a common scene. Yet no [multiple users] - [one bot] - [multiple claws] feature are implemented in any openclaw runtime.

@whtiehack
Copy link
Copy Markdown
Contributor Author

If the team is open to adding the AI Bot channel, I'm happy to take on WeCom-related issues going forward. I'm based in China and my company uses WeCom daily, so I can understand the requirements and debug issues more easily.

Wecom daily user too, thanks a lot for your support. I'm gonna try wecom bot multiplexing considering multiple users (and their credentials) using one bot is a common scene. Yet no [multiple users] - [one bot] - [multiple claws] feature are implemented in any openclaw runtime.

I encountered the same issue as you. Originally, I wanted to do isolation in zeroclaw, but later found it quite challenging. So now, I'm planning to achieve isolation by running multiple containers with multiple bots. One general bot, and other dedicated bots.

Because now bots can apply freely. No management permissions are needed anymore.

@whtiehack
Copy link
Copy Markdown
Contributor Author

@chengongpp If you have any good ideas, share them with me! thanks

@whtiehack
Copy link
Copy Markdown
Contributor Author

Since PR #3439 merged on March 13, 2026 and claimed channels_config.wecom for the webhook-based WeCom bot, I plan to retarget #3305 as wecom_ws (long-connection AI bot support) to avoid semantic and config-key conflicts.

@whtiehack whtiehack changed the title feat(wecom): add WeCom AI bot support feat(channel): add wecom_ws AI bot channel Mar 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants