WeCom channel API research
Checked on 2026-10-25. The implementation is based on official developer documentation and the official CLI source, not guessed endpoints. Private credentials and real channel content were not inspected.
Authentication and reuse decision
The official CLI source at commit
55785fa0a5c922279533a5b5a836b44b56f65ce7
has these relevant boundaries:
| Component | Evidence | Implication |
|---|---|---|
| Authentication bootstrap | auth/bootstrap.rs | Uses /cgi-bin/aibot/cli/get_cli_config, returns a gateway Bearer token; signing is SHA-256 of Secret + bot ID + decimal seconds + nonce |
| Credential ownership | auth/types.rs, auth/store.rs | Bot credentials and token belong to the official CLI's private encrypted store |
| Binary vs libraries | wecom-cli/Cargo.toml | Auth is in the binary crate; wecom and wecom-transport are separate Rust libraries |
| Gateway envelopes | transport/catalog.rs | Gateway discovery/envelope behavior is not the channel HTTP schema |
| License | MIT license | Reuse is legally possible with attribution, but does not solve the protocol or privilege boundary |
The channel token API
uses /cgi-bin/aibot/get_token, the same signing formula, and a one-day
access_token passed in query parameters. There is no documented guarantee
that the gateway token is interchangeable. The broker obtains and caches the
channel token in memory, renewing before expiry; a rejected token is discarded
without replaying the failed operation. The next separately initiated request
can acquire a fresh one.
Decision: use the workspace's maintained Go agent-cli-kit for generic
transport, output, errors and argv handling. Implement the small documented
channel protocol in Go. Do not vendor private Rust auth modules, parse encrypted
official credential files, scrape an exported Secret, or shell out to the
official CLI on behalf of a channel message. Revisit supported credential
delegation if Tencent publishes a stable API for it.
Coexistence with an existing official CLI
Rechecked the official CLI's authentication source and
command reference
on 2026-10-26. Its supported login methods are QR binding and manual bot ID/Secret
entry. auth show displays authorization status and bot ID; it is not a supported
Secret export or channel-API credential delegation interface. A remembered login
method is not required to preserve the existing installation.
Keep the following checks separate:
| Check | What it establishes | What it does not establish |
|---|---|---|
| Existing official CLI login | The CLI has its own authorization configuration | Channel API access, callback configuration, or shared-token compatibility |
Broker auth check and bounded channel discovery |
Channel API access for the supplied bot at that time | Callback delivery, complete watch coverage, or production isolation |
| Authenticated callback challenge and observed test event | The configured callback route works for that bot/event | Isolation of the worker or delivery of every event |
The separate get_cli_config and get_token endpoints do not document a guarantee
that credential issuance or refresh for the same bot cannot affect another
consumer. Do not claim coexistence is verified from endpoint names alone.
For first live verification, use a dedicated API-enabled test bot in a designated
test channel with the required grayscale access. This avoids changing the bot
already used by the official CLI. Keep the test broker read-only initially.
For an intentional shared-bot deployment, inventory its existing integrations
and connection configuration first, obtain the existing Secret through the
operator's supported management path, and verify both consumers before and after
channel access. If the Secret is unavailable, do not decrypt the CLI store, reset
the bot, or rerun auth init as a recovery shortcut. Use a separate test bot or
wait for a supported delegation mechanism. Coordinate any callback setup with
the existing receiver; this connector does not automatically install callback
fan-out or take over an active connection. A read-only HTTP check does not test
event watch; the latter needs a complete polling baseline and later changes,
or verified callback delivery, depending on operator policy.
Polling feasibility
The all-content API was rechecked on 2026-10-26 (displayed update: 2026-10-19). It exposes paginated posts per channel and replies per post, plus exact-ID reads. Page size is at most 50. Ordering is by creation time; there is no documented channel-wide change cursor or modification-time feed. Replies therefore require visiting the posts, including old posts, to find recent replies.
is_modified, modify_time and is_recalled, together with curated content,
permit snapshot comparison. Creator identity does not establish the actor who
performed a later edit. Missing records and intermediate changes cannot be
reconstructed as authoritative deletion/change events. The connector exposes
these observations through the same watch interface, with explicit provenance,
bounded full snapshots, persistent deduplication and no callback requirement.
Connection mode and access
The overview
describes channel rollout from version 5.0.12 and still marks channel long
connections as in development. It distinguishes three bot permission levels:
read all and proactively send; read all and reply only when mentioned; and
read/reply only when mentioned. Do not confuse TopicInfo.permission
(public/private channel) with the bot's capabilities. The CLI enforces its own
narrower operator policy; WeCom remains the final authority on API access.
URL callbacks require a publicly reachable address. Connection modes are mutually exclusive; changing them invalidates the existing mode. The connector never changes this configuration itself. Existing group-channel compatibility can cause duplicate responses; the operator must coordinate it using the documented stop-sync operation, which this version deliberately does not expose.
Endpoint coverage
All implemented requests are fixed HTTPS POSTs on qyapi.weixin.qq.com, under
/cgi-bin/aibot/. There is no arbitrary URL, path, method or request-body command.
| Official documentation | Endpoint suffix | Support |
|---|---|---|
| Token | get_token |
Broker only; memory cache |
| Channel information | topic/get_topic_list, topic/get_topic_member_list |
Discovery, one bounded page; agent channel list is restricted to configured IDs |
| Mention content / all content | topic/get_post_list, topic/get_reply_list |
Exact reads and bounded listing; attachment credentials removed |
| Search | topic/search, topic/get_search_result |
Two-step search scoped to one allowed channel; job ID is discoverable from matching channels |
| Mention replies / proactive content | topic/send_post, topic/send_reply |
Reviewed text/Markdown only, up to 20480 UTF-8 bytes |
| Events | Callback JSON | Seven documented kinds recognized; mentions remain human-allowlisted, while explicit observe_all permits post/reply observations from humans and other bots; this bot is always excluded |
| Crypto / algorithm | GET verification and encrypted POST | SHA-1 sorted signature, AES-256-CBC, PKCS#7 block size 32, empty receive ID for self-built bots |
| Temporary media | Upload lifecycle | Deferred: filesystem access and content disclosure require a separate capability design |
| Forwarded chat records | Chat-record reads | Deferred; no automatic expansion |
| Mention reactions / proactive reactions | topic/post_emoji |
Operator-approved native add/remove on posts or replies; bounded reaction reads through content APIs |
The maximum exposed page size is deliberately smaller than the upstream maximum where useful: 50 for remote reads, 20 for search results, and 100 for local inbox or proposal pages. Agent channel discovery is bound to exactly one channel per context.
Documentation ambiguities handled conservatively
-
post_emojiappears in both the mention-response and proactive-content documentation, rechecked on 2026-10-26. The 24-hour mention rule is not a global prohibition on proactive reactions. The connector defaults to exact mention scope and exposes a separate explicit channel scope for operator-verified proactive permissions;read_allalone is not that permission. -
Native reaction success has
errcode: 0without a new resource ID. The proposal records the target/type/action and an acknowledged status; reconciliation reads the bot's membership from the target'semoji_list, never a fabricated ID. -
Mention-only content is available within 24 hours. The broker checks the triggering event age before context reads and reply approvals.
-
Examples use both
creatorandcreator_info, and bothaibotidandbotid. The curated model retains these variants without treating a display name as identity or authority. -
Channel time filtering does not clearly specify inclusive/exclusive edges. Post/reply listings apply
[from,to)locally as well as sending the bounds; this cannot recover records omitted upstream. Search summaries have no times, so their time restriction is server-native and cannot be independently checked without fetching the complete messages. Do not claim exact history coverage from search results. -
The official AES-key example is not canonical Base64. Ordinary key decoding is required for compatibility; ciphertext is strictly decoded. An independent known-answer test uses the official encrypted sample.
-
No remote idempotency key is documented for sending posts/replies. Local at-most-once attempt tracking prevents automatic replay in one retained broker ledger; it does not establish remote exactly-once delivery.
Grok Bot routine webhook review — 2026-11-12
Reviewed the official Cursor routine documentation,
xAI skills, routines and automations,
and Cursor work/computer guide.
The routine's Webhook panel supplies its URL and sender key. POST JSON with
Authorization: Bearer <sender key>; the JSON accompanies the routine instructions.
HTTP 200 means accepted and a run started, not completed. The documentation
says other responses mean no run started. It does not document a custom batch ACK,
Idempotency-Key deduplication, or a completion callback. Do not confuse routine
webhooks with Grok inference hooks, which are a different API.
The reviewed limits are 200 runs/hour per routine and 300/hour per account; other jobs share these allowances. A routine test starts real work and consumes usage. An idle routine consumes no usage. These are provider limits, not SLAs; verify the current account limits before deployment.
The account's Bots share a cloud computer. /workspace is the documented home
for durable project files, but updates/recovery can rebuild the environment and
lose recent state. Persistent filesystem access is not a guarantee that a manually
started background process survives. Use the host's supported supervisor and
private persistent paths, and back up state outside a replaceable runtime.
Screens are not credential isolation. Use the host's protected secret facility
for sender keys; never include them in routine instructions or webhook payloads.
Decision: retain explicit_ack for idempotent receivers and add opt-in
http_accepted for this exact host contract. Preserve metadata payloads and
existing atomic JSON state; no SQLite dependency or ACK-only HTTP receiver is
needed. A transport error cannot establish non-acceptance, so mark it unknown
and stop. Bounded retries alone cannot prevent repeated paid wakeups. An operator
must establish the outcome from host run history before retrying an unknown batch.
Worker claims can suppress duplicate business processing, not prior AI startup.
This review could not retrieve the WeCom pages linked above. The channel long-connection statement remains the earlier dated WeCom review, not a newly verified availability claim. Existing authenticated callback intake is the push backend; configured deployments otherwise use bounded polling and diff. This change adds no unverified channel WebSocket protocol. Local mocks validate the CLI contract; no production Grok routine was invoked for this review.