WeChat

August 22, 2026 · View on GitHub

English | 中文

@deepseek-ai/dsh-weixin owns one QR-linked WeChat account over the iLink Bot wire protocol: linking, the durable credential, the receive loop that dispatches weixin/message, and outbound text. The service is dormant until an account is linked through the settings page's QR panel; dsh-weixin-agent bridges inbound messages to a dedicated agent whose closing text answers the chat. Record shapes live with the service (packages/weixin/weixin).

Cordis API

Generated from source by scripts/gen-cordis-catalog.ts (verified fresh by pnpm run verify-cordis-catalog in doc-sync; regenerate with pnpm run gen-cordis-catalog) — the language sides differ only in locale-specific paired document paths. Signature blocks use a ts cordis-catalog fence and keep the original source JSDoc; dispatch modes are defined in the primer, and the framework-inherited ctx API lives in cordis-api/inherited.md.

ctx.weixinWeixinRuntime

The WeChat connection. One linked account per harness home; linking, receiving, and sending all run through this service.

/**
 * The panel's view of the connection.
 * @returns whether an account is linked, plus any pending challenge.
 */
status(): WeixinStatus

/**
 * Begin linking: fetch a QR and poll it until the user confirms in
 * WeChat. Calling it while a challenge is pending returns that one.
 * @returns the payload to render as a QR image.
 * @throws WeixinError when the API refuses a challenge.
 */
async startLink(): Promise<string>

/** Drop the stored credential and stop receiving. */
unlink(): void

/**
 * Send one text message to a WeChat user.
 * @param toUserId - the recipient, normally an inbound message's sender.
 * @param text - the reply body.
 * @param contextToken - the conversation token from that user's message.
 * @throws WeixinError when no account is linked.
 */
async send(toUserId: string, text: string, contextToken?: string): Promise<void>

/**
 * Show or clear the typing indicator in one chat. Failures are swallowed:
 * the indicator is a courtesy, and losing it must never cost the reply.
 * @param toUserId - the chat to indicate in.
 * @param typing - true while composing, false to clear.
 */
async setTyping(toUserId: string, typing: boolean): Promise<void>

Source: packages/weixin/weixin/src/index.ts

weixin/* events

The link state changed: a scan completed, or the credential was dropped or rejected.

/**
 * The link state changed: a scan completed, or the credential was
 * dropped or rejected.
 * @mode emit
 * @param linked - whether an account is now linked.
 */
'weixin/link'(linked: boolean): void

Source: packages/weixin/weixin/src/index.ts

weixin/message — emit

One inbound WeChat message, after the receive loop accepted it.

/**
 * One inbound WeChat message, after the receive loop accepted it.
 * @mode emit
 * @param message - the sender, text, and conversation token.
 */
'weixin/message'(message: InboundText): void

Source: packages/weixin/weixin/src/index.ts