<!-- Source: https://ccr-cloud.uubright.com/docs/wechat/ -->
# Personal WeChat (experimental)

Control ccr-cloud using text commands through Tencent iLink. This is an optional
personal WeChat adapter, not WeCom, and does not require an LLM dispatcher.

> [!IMPORTANT]
> Experimental: automated tests use mocked Tencent responses. Live pairing and
> delivery have not been verified on a real account. Your account must support
> Tencent’s ClawBot integration; a recent app version does not guarantee access,
> including for US App Store accounts. If pairing is unavailable, use the PWA or
> [Discord](https://ccr-cloud.uubright.com/docs/discord/).

## Pair your server

First complete [Getting started](https://ccr-cloud.uubright.com/docs/getting-started/). On the server, as the same
user that runs ccr-cloud, stop the API before changing pairing:

```sh
tmux kill-session -t =ccr-cloud
npm run wechat -- login
npm run setup -- --start
npm run wechat -- status
```

The login command displays a Tencent pairing link, and a terminal QR if the
optional `qrencode` executable is installed. Scan with your own WeChat account and
complete Tencent’s confirmation. Treat the temporary link as a login credential;
never share it. Login saves private pairing credentials and appends
`WECHAT_ENABLED=1` to your data directory’s `server.env`.

Send `help` or `帮助` in the paired ClawBot conversation. No public callback,
Cloudflare configuration or phone VPN is required by this adapter. The server
must reach Tencent iLink over HTTPS.

## Commands

| Command | Action |
|---|---|
| `help` / `帮助` | List commands |
| `sessions` / `任务` | List tasks |
| `projects` / `项目` | List saved projects |
| `new Reply OK` | Create and select a scratch task; uses model access |
| `new --project PROJECT_ID PROMPT` | Create a repository task |
| `use SESSION_ID` | Select the task for ordinary text messages |
| `status SESSION_ID` | Latest reply and pending approvals |
| `say SESSION_ID MESSAGE` | Send a follow-up |
| `stop SESSION_ID` | Stop a task |
| `resume SESSION_ID` | Resume a task |
| `interrupt SESSION_ID` | Interrupt the current turn |
| `allow SESSION_ID REQUEST_ID` | Approve this exact request |
| `deny SESSION_ID REQUEST_ID` | Deny this exact request |

After selecting a task, ordinary text sends a follow-up to it, including sentences
that start with words such as Help, New or Stop. Prefix commands with `/` after
selecting a task (for example `/status` or `/allow SESSION_ID REQUEST_ID`). Use the full IDs
from status or approval messages to avoid ambiguity. There is no approve-all
command. New tasks use the server’s existing default permission behavior; use the
PWA to choose explicit permissions for a task. Groups, media and multi-user access
are not supported.

## Notifications and privacy

Only the paired owner can issue commands. Enabling the channel sends selected task
content through Tencent, including replies, repository/project names and approval
tool inputs. Keep using the PWA for content you do not want in chat. This is not an
end-to-end-encrypted relay operated blindly by ccr-cloud.

Set `WECHAT_NOTIFICATIONS=0` in `server.env` and restart to disable unsolicited
approval/completion notices; command replies still work. Notifications require a
recent incoming message context. `WECHAT_CONTEXT_TTL_SECONDS` controls the local
context lifetime (default 3600, range 1–86400); it is not a Tencent delivery
promise. Send a fresh message if notices are queued. Retries after a crash may
produce duplicate replies or notifications; uncertain commands are not
intentionally executed again.

Pairing and runtime files live under `DATA_DIR/wechat/`, with private permissions.
They contain credentials and task content; do not publish them or attach them to
issues. A worker lock prevents two APIs from consuming the same account.

## Recovery and disconnect

`status` checks local pairing and the worker lock, not live eligibility or token
validity. Dead-PID worker locks are recovered at startup. If a lock is corrupt or an
acquisition was interrupted, stop all API processes, then remove it with `npm run wechat -- unlock` before restarting.

To replace expired pairing, stop the API and run:

```sh
npm run wechat -- login --replace
npm run setup -- --start
```

To disconnect, stop the API and run `npm run wechat -- logout`, then restart.
Logout removes local channel credentials/state and disables the channel. Also
remove the binding in WeChat to revoke it on Tencent’s side. Coding tasks and
repositories are preserved.

`WECHAT_ILINK_VERSION` overrides the adapter’s wire compatibility version, not the
phone app version. Leave it unset unless investigating a protocol change.
