mirror of
https://github.com/NanmiCoder/claude-code-haha.git
synced 2026-10-10 03:43:11 +08:00
feat(im): add scan-to-create Feishu bots plus WeCom, QQ and Slack adapters
Connecting Feishu meant creating a bot by hand on the open platform and pasting an App ID and App Secret back. Feishu also exposes an RFC 8628 device-authorization flow, so the desktop can now render a QR code, and confirming it in the app creates the bot and stores its credentials directly. `adapters/feishu/registration.ts` implements that protocol rather than importing `registerApp` from `@larksuiteoapi/node-sdk@1.73`: the repository pins 1.60 for the chat client, and the SDK runs the whole poll inside one un-cancellable promise where the desktop needs the stateless begin/poll pair the DingTalk registration already uses. The scan is create-only, so it can never rewrite the configuration of a bot the user already runs, and it pre-fills exactly the scopes, events and callbacks this adapter calls. International tenants finish on Lark's domain, which is now persisted and honoured by the client. WeCom, QQ and Slack join the same session model. WeCom and QQ bind by scanning; Slack has no scan flow, so it uses an app manifest that pre-fills the scopes and Socket Mode. All three run over long connections, so no public callback URL is needed, and all three accept private chats only — pairing authorizes one person, and answering in a group would extend that authorization to everyone else in the room. They are built on a new `adapters/common/chat-runtime.ts` instead of a fourth copy of the loop the five existing adapters each carry. A platform supplies a `ChatPort` — how to say something, how to open a streaming reply, optionally how to send an image — and the runtime owns pairing, command routing, session restore, permission bookkeeping and the translation of the server's stream. The existing five are deliberately left on their own copies; migrating them is a separate change with its own regression surface. Attachments are downloaded through a deferred loader that runs after the pairing gate and inside the per-chat queue. Resolving them eagerly would let an unpaired stranger make the adapter fetch bytes and write them under ~/.claude/im-downloads — on Slack with the bot token attached — and would let a slow attachment overtake a text message sent after it. The sidecar launcher's per-adapter branches become one table. It is declared above the mode dispatch on purpose: `runAdapters` is hoisted and runs at module top level, so a table declared below it is still in its temporal dead zone when the adapters mode reads it — which type checks, lints and unit tests all miss, and only the compiled binary reveals. Verified with the checks `check:impact` selects: adapters, server, desktop, electron, policy, chat-contract, agent-flow, docs, native (sidecar compile, packaging and an adapters-mode smoke against the real binary) and coverage. The scan flows themselves are not verified against live platforms — that needs real WeCom, QQ and Slack accounts and would create real bots. Claude-Session: https://claude.ai/code/session_01CCGoP316AK7wdQG3Ms6Uwq
This commit is contained in:
+25
-8
@@ -1,19 +1,30 @@
|
||||
---
|
||||
title: Feishu Integration
|
||||
nav_title: Feishu
|
||||
description: Create a Feishu bot from the official template and drive Desktop sessions from a private chat with card-based approval.
|
||||
description: Scan a QR code in Settings to create a Feishu bot, then drive Desktop sessions from a private chat with card-based approval.
|
||||
order: 1
|
||||
---
|
||||
|
||||
# Feishu Integration
|
||||
|
||||
Best for teams already on Feishu: an official template creates a bot with every required permission preconfigured, and permission requests arrive as interactive cards you can tap. Common commands can be exposed as a bot menu. It handles private (`p2p`) chats only, and changing the bot configuration means publishing a new version in the developer console.
|
||||
Best for teams already on Feishu: select **Scan to Create** in Settings, scan with Feishu, and the bot is created with its App ID and App Secret stored locally. Permission requests arrive as interactive cards you can tap, and common commands can be exposed as a bot menu. It handles private (`p2p`) chats only, and changing the bot menu means publishing a new version in the developer console.
|
||||
|
||||
## Create the bot
|
||||
## Create the bot by scanning
|
||||
|
||||
Open [Create a Feishu bot](https://open.feishu.cn/page/openclaw?form=multiAgent). This is the official OpenClaw template, with messaging, event subscription, and card callback permissions already granted — no scopes to add by hand. The **Create Feishu bot** button under **Settings → IM Adapters → Feishu** opens the same page.
|
||||
1. Open **Settings → IM Adapters** and select the **Feishu** tab.
|
||||
2. Select **Scan to Create**. A QR code appears.
|
||||
3. Scan it with Feishu. The confirmation page arrives pre-filled with the bot's name, description, and exactly the scopes, event subscriptions, and card callback this adapter calls — nothing extra is requested.
|
||||
4. On confirmation the App ID and App Secret are written to `~/.claude/adapters.json` and the adapter restarts.
|
||||
|
||||
Choose a name, create the app, then keep its **App ID** and **App Secret** for the next step.
|
||||
The code is valid for 10 minutes; generate a new one if it lapses. Once bound, the button becomes **Scan Again** and an **Unbind Feishu bot** button appears next to it.
|
||||
|
||||
Scanning only ever **creates** a new bot; it never binds an existing one, which would let this flow quietly rewrite the callback configuration of a bot you already run.
|
||||
|
||||
Leave **Encrypt Key** and **Verification Token** empty: messages travel over the WebSocket connection, which does not use them.
|
||||
|
||||
::: tip Creating one by hand also works
|
||||
If you would rather not scan, or want to reuse an existing bot, create one from the [official OpenClaw template](https://open.feishu.cn/page/openclaw?form=multiAgent) and paste its App ID and App Secret into the fields below the QR panel. Desktop also shows that entry point while no credentials are stored.
|
||||
:::
|
||||
|
||||
## Configure the bot menu
|
||||
|
||||
@@ -27,11 +38,13 @@ In the [Feishu developer console](https://open.feishu.cn/app?lang=en-US), open y
|
||||
|
||||
Save the menu, then publish a new application version. Menu changes take effect only after publishing.
|
||||
|
||||
## Enter credentials in Desktop
|
||||
## Entering credentials by hand
|
||||
|
||||
A bot created by scanning needs none of this — its credentials are already stored. This is only for the template flow or for reusing an existing bot:
|
||||
|
||||
1. Open **Settings → IM Adapters** and select the **Feishu** tab.
|
||||
2. Paste the values into **App ID** and **App Secret**.
|
||||
3. Leave **Encrypt Key** and **Verification Token** empty; the template bot does not need them.
|
||||
3. Leave **Encrypt Key** and **Verification Token** empty; the long-connection mode does not need them.
|
||||
4. Enable **Streaming Card Mode** if you want long replies to update one card in place.
|
||||
5. Select **Save**.
|
||||
|
||||
@@ -82,6 +95,10 @@ export ADAPTER_SERVER_URL="ws://127.0.0.1:3456"
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Scanning does nothing.** The flow runs on `accounts.feishu.cn`; confirm your machine can reach it. International (Lark) tenants switch to `accounts.larksuite.com` automatically after confirmation — there is nothing to change by hand.
|
||||
|
||||
**The code reports as expired.** It is valid for 10 minutes; select **Scan Again** for a new one.
|
||||
|
||||
**No messages arrive.** Confirm the app is published — menu edits require a new version — and that the conversation is a private chat rather than a group.
|
||||
|
||||
**Card buttons do nothing.** The card action capability usually did not ship with the published version. Publish again from the developer console.
|
||||
@@ -92,4 +109,4 @@ export ADAPTER_SERVER_URL="ws://127.0.0.1:3456"
|
||||
|
||||
## Source
|
||||
|
||||
`adapters/feishu/index.ts`, plus `pairing.ts`, `session-store.ts`, `ws-bridge.ts`, and `http-client.ts` under `adapters/common/`.
|
||||
`adapters/feishu/index.ts` (runtime) and `adapters/feishu/registration.ts` (scan to create), plus `pairing.ts`, `session-store.ts`, `ws-bridge.ts`, and `http-client.ts` under `adapters/common/`.
|
||||
|
||||
+14
-8
@@ -1,13 +1,13 @@
|
||||
---
|
||||
title: IM Integrations
|
||||
nav_title: Overview
|
||||
description: Bridge Feishu, Telegram, WeChat, DingTalk, or WhatsApp private chats into the Desktop app and continue the same session from your phone.
|
||||
description: Bridge Feishu, Telegram, WeChat, DingTalk, WhatsApp, WeCom, QQ, or Slack private chats into the Desktop app and continue the same session from your phone.
|
||||
order: 0
|
||||
---
|
||||
|
||||
# IM Integrations
|
||||
|
||||
A session running in the Desktop app can be reached from a private chat on your phone. Once bound, a message in Feishu, Telegram, WeChat, DingTalk, or WhatsApp drives the Claude Code session on your own machine: start a long task before you leave, then follow the progress, approve permissions, and switch projects from the road.
|
||||
A session running in the Desktop app can be reached from a private chat on your phone. Once bound, a message in Feishu, Telegram, WeChat, DingTalk, WhatsApp, WeCom, QQ, or Slack drives the Claude Code session on your own machine: start a long task before you leave, then follow the progress, approve permissions, and switch projects from the road.
|
||||
|
||||
The chat partner is a bot or account you bound yourself. Messages reach your local Desktop app; no intermediate service holds your code.
|
||||
|
||||
@@ -17,22 +17,25 @@ The chat partner is a bot or account you bound yourself. Messages reach your loc
|
||||
|
||||
- **The same session, continued.** Messages sent from your phone enter the Claude Code session on your computer, where file edits, commands, and reads really happen.
|
||||
- **Project switching.** `/projects` lists recent projects and switches to the one you pick; `/new` starts a fresh session.
|
||||
- **Permission approval.** When Claude wants to write a file or run a risky command, the request is pushed to the chat. Feishu and DingTalk send interactive cards, Telegram sends buttons, WeChat and WhatsApp expect a text reply.
|
||||
- **Permission approval.** When Claude wants to write a file or run a risky command, the request is pushed to the chat. Feishu and DingTalk send interactive cards, Telegram sends buttons, and every other platform expects a text reply.
|
||||
- **Status and stop.** `/status` reports the current project, model, and run state; `/stop` interrupts the current turn.
|
||||
|
||||
The Desktop app has to stay running. The chat side is only a remote control.
|
||||
|
||||
## Choosing a platform
|
||||
|
||||
All five expose the same capabilities. They differ in setup cost and approval experience.
|
||||
All eight expose the same capabilities. They differ in setup cost and approval experience.
|
||||
|
||||
| Platform | How you connect | Best for | Known limits |
|
||||
|---|---|---|---|
|
||||
| Feishu | Create a bot from the official template, paste its App ID and App Secret | Teams that want one-tap permission approval | Private (`p2p`) chats only; menu changes require publishing a new app version |
|
||||
| Feishu | Scan a QR code in Settings; the bot is created and its credentials stored for you | Teams that want one-tap permission approval | Private (`p2p`) chats only; menu changes require publishing a new app version |
|
||||
| Telegram | Ask `@BotFather` for a Bot Token, paste it into Settings | Individuals who can reach Telegram; fastest setup | Private chats only |
|
||||
| WeChat | Scan a QR code in Settings to log in a bot account | People who only want WeChat | Private chats only; permission approval is text replies |
|
||||
| DingTalk | Scan a QR code in Settings; credentials are filled in for you | Organizations already on DingTalk | Private chats only; interactive approval cards need an extra template ID |
|
||||
| WhatsApp | Scan from **Linked devices** on your phone | Users outside mainland China | Personal linked-device login, not the official Cloud API; personal private chats only |
|
||||
| WeCom | Scan a QR code in Settings to create an AI bot | Organizations on Enterprise WeChat | Private chats only; permission approval is text replies |
|
||||
| QQ | Scan a QR code in Settings; credentials are filled in for you | Individuals on QQ | Private (C2C) chats only, no groups or guilds; text approval |
|
||||
| Slack | Create the app from a pre-filled manifest, paste two tokens | Teams on Slack | Direct messages only; no QR flow, tokens are pasted by hand |
|
||||
|
||||
If you have no preference, start with Telegram or Feishu — their approval flows are the most comfortable.
|
||||
|
||||
@@ -41,7 +44,7 @@ If you have no preference, start with Telegram or Feishu — their approval flow
|
||||
Binding happens in two layers: first the Desktop app gets platform credentials, then your personal account is authorized with a pairing code. The second layer is identical everywhere.
|
||||
|
||||
1. Open **Settings → IM Adapters**.
|
||||
2. Bind one platform in its tab: Feishu and Telegram take credentials, WeChat, DingTalk, and WhatsApp use a QR code.
|
||||
2. Bind one platform in its tab: Feishu, WeChat, DingTalk, WhatsApp, WeCom, and QQ use a QR code; Telegram and Slack take credentials.
|
||||
3. Pick a directory under **Default Project**.
|
||||
4. Select **Save**.
|
||||
5. Back at the top, in **Pairing**, select **Generate Code** to get a six-character code.
|
||||
@@ -71,7 +74,7 @@ Entry points differ slightly per platform — Feishu can expose commands as a bo
|
||||
- `/clear` — clear context, keep the project binding
|
||||
- `/stop` — stop the current generation
|
||||
|
||||
WeChat, DingTalk, and Feishu also accept Chinese aliases such as `帮助`, `状态`, `项目列表`, `新会话`, `清空`, and `停止`.
|
||||
Feishu, WeChat, DingTalk, WeCom, QQ, and Slack also accept Chinese aliases such as `帮助`, `状态`, `项目列表`, `新会话`, `清空`, and `停止`.
|
||||
|
||||
## Security
|
||||
|
||||
@@ -87,8 +90,11 @@ For a full mobile interface rather than a chat window, see [H5 access](../deskto
|
||||
|
||||
## Per-platform guides
|
||||
|
||||
- [Feishu](./feishu.md) — template bot, card approval
|
||||
- [Feishu](./feishu.md) — scan to create a bot, card approval
|
||||
- [Telegram](./telegram.md) — BotFather token, button approval
|
||||
- [WeChat](./wechat.md) — QR-bound account, text approval
|
||||
- [DingTalk](./dingtalk.md) — QR authorization, AI Card streaming
|
||||
- [WhatsApp](./whatsapp.md) — personal linked device, text approval
|
||||
- [WeCom](./wecom.md) — scan to create an AI bot, streaming replies
|
||||
- [QQ](./qq.md) — QR authorization, private-chat streaming
|
||||
- [Slack](./slack.md) — app manifest, Socket Mode connection
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
---
|
||||
title: QQ Integration
|
||||
nav_title: QQ
|
||||
description: Scan a QR code in Settings to authorize a QQ bot, then drive the Desktop app from a private chat with streaming replies.
|
||||
order: 7
|
||||
---
|
||||
|
||||
# QQ Integration
|
||||
|
||||
For individuals on QQ. Select **Scan to Bind** in Settings, scan with the QQ mobile app, and the AppID and AppSecret land in local configuration — no manual app creation on the QQ Open Platform. Messages travel over the official WebSocket gateway, so your machine needs no public address.
|
||||
|
||||
Limits: private (C2C) chats only, no groups or guilds; permission approval is a text reply.
|
||||
|
||||
## Authorize the bot by scanning
|
||||
|
||||
1. Open **Settings → IM Adapters** and switch to the **QQ** tab.
|
||||
2. Select **Scan to Bind**. A QR code appears.
|
||||
3. Scan it with the QQ mobile app and confirm the authorization.
|
||||
4. On success the AppID and AppSecret are written to `~/.claude/adapters.json` and the adapter restarts.
|
||||
|
||||
The code rotates on its own when it expires, and the image on screen refreshes with it. Once bound, the button becomes **Scan Again** and an **Unbind bot account** button appears next to it.
|
||||
|
||||
This step only gives the Desktop app the bot's credentials. It does **not** authorize anyone — that is what pairing below decides.
|
||||
|
||||
## Pairing
|
||||
|
||||
Back at the top of the page, under **Pairing**, select **Generate Code** to get a six-character code. This takes effect immediately; no **Save** is needed.
|
||||
|
||||
Send that code to the newly authorized bot in a private QQ chat. Once pairing is confirmed, anything you type goes to Claude Code.
|
||||
|
||||
A code is valid for 60 minutes, works once, and is invalidated the moment a new one is generated. Five failed attempts within five minutes trigger rate limiting.
|
||||
|
||||
**Allowed Users** can stay empty, in which case only paired accounts can use the bot. To allow known accounts directly, enter their QQ `openid` values separated by commas. A QQ `openid` is a per-bot identifier, not a QQ number.
|
||||
|
||||
## Supported commands
|
||||
|
||||
- `/help` or `帮助` — list the available commands
|
||||
- `/status` or `状态` — current project, model, and run state
|
||||
- `/projects` or `项目列表` — list recent projects and switch
|
||||
- `/new` or `新会话` — start a fresh session, optionally with an index, name, or absolute path
|
||||
- `/clear` or `清空` — clear the context, keep the project binding
|
||||
- `/stop` or `停止` — stop the current turn
|
||||
- Permission approval: reply `1` to allow once, `2` to allow for the session, `3` to deny; `/allow <id>`, `/always <id>`, and `/deny <id>` work too
|
||||
|
||||
## How messages look
|
||||
|
||||
Replies use QQ stream messages (`stream_messages`): one message refreshes as the answer is generated, then settles. That API is private-chat only; if a turn has no usable reply anchor, the adapter falls back to ordinary chunked messages instead of dropping content.
|
||||
|
||||
A typing indicator is sent while Claude is thinking or running tools. Inbound images and files are downloaded into `~/.claude/im-downloads/qq/` and forwarded as attachments; voice notes use QQ's own transcript rather than downloading the audio. Local images referenced in the Agent's output (restricted to the current session's working directory) are uploaded and sent as separate image messages.
|
||||
|
||||
## Agent capability and boundaries
|
||||
|
||||
QQ is not a separate question-and-answer model. Messages enter the same Claude Code Agent session as the current project, so they continue the multi-turn context and can use the files, terminal, Git, Skills, and MCP tools that session already has.
|
||||
|
||||
That means a paired account holds the full Agent capability of the current project. Permission confirmation is a gate on individual operations, not an OS sandbox. Do not hand the bot to people you do not trust, and do not install unreviewed Skills, plugins, or MCP servers from chat.
|
||||
|
||||
The adapter accepts only paired or allow-listed private chats, and project listing and name matching stay inside **Allowed project directories**.
|
||||
|
||||
## Running it locally
|
||||
|
||||
Release builds start the adapter as a sidecar automatically. Manual startup is only needed when running from source:
|
||||
|
||||
```bash
|
||||
cd adapters
|
||||
bun install
|
||||
bun run qq
|
||||
```
|
||||
|
||||
Optional environment overrides:
|
||||
|
||||
```bash
|
||||
export QQ_APP_ID="xxx"
|
||||
export QQ_APP_SECRET="xxx"
|
||||
export ADAPTER_SERVER_URL="ws://127.0.0.1:3456"
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**The QR code never appears.** Scanning goes through the QQ Open Platform; confirm your machine can reach it. The request times out after 20 seconds, so try again.
|
||||
|
||||
**Scanned successfully but the bot stays silent.** Confirm the Desktop app is still running and that the **QQ** tab shows an AppID. Credentials are written the moment the scan succeeds, and the adapter restarts on its own.
|
||||
|
||||
**Messages report "unauthorized".** Check that a pairing code was generated, that it is still inside its 60-minute window, and that you sent the current one.
|
||||
|
||||
**Mentioning the bot in a group does nothing.** That is intended: only private chats are handled. Pairing authorizes one person, and answering in a group would extend that authorization to everyone in it.
|
||||
|
||||
## Source entry points
|
||||
|
||||
`adapters/qq/index.ts` (runtime), `adapters/qq/qr-auth.ts` (scan authorization), `adapters/qq/extract-payload.ts` (inbound parsing), plus the shared session loop in `adapters/common/chat-runtime.ts`.
|
||||
@@ -0,0 +1,103 @@
|
||||
---
|
||||
title: Slack Integration
|
||||
nav_title: Slack
|
||||
description: Create a Slack app from a pre-filled manifest and drive the Desktop app from direct messages over Socket Mode.
|
||||
order: 8
|
||||
---
|
||||
|
||||
# Slack Integration
|
||||
|
||||
For teams already on Slack. Slack has no QR flow; the closest equivalent is an **app manifest**. The Desktop app pre-fills the scopes, event subscriptions, and Socket Mode setting — you open the link, confirm, and paste two tokens back.
|
||||
|
||||
Socket Mode is used for the same reason Feishu, WeCom, and QQ use long connections: your machine needs no public address, and Slack never calls back into your computer.
|
||||
|
||||
Limits: direct messages only, no channels; permission approval is a text reply.
|
||||
|
||||
## Create the Slack app
|
||||
|
||||
1. Open **Settings → IM Adapters** and switch to the **Slack** tab.
|
||||
2. Select **Create app from manifest**. Slack's create page opens with the manifest pre-filled; **Show the app manifest JSON** on the settings page reveals the same content if you would rather paste it by hand.
|
||||
3. Pick a workspace, review the manifest, and create the app.
|
||||
4. Under **Install App**, install it into the workspace and copy the **Bot User OAuth Token** (starts with `xoxb-`).
|
||||
5. Under **Basic Information → App-Level Tokens**, generate a token with the `connections:write` scope (starts with `xapp-`).
|
||||
6. Paste both into **Bot Token** and **App-Level Token** in Settings, then select **Save**.
|
||||
|
||||
The manifest requests exactly the scopes the adapter calls — nothing speculative:
|
||||
|
||||
| Scope | What it is for |
|
||||
|---|---|
|
||||
| `chat:write` | Post messages and update one in place |
|
||||
| `im:history` | Receive `message.im` direct-message events |
|
||||
| `files:read` | Download attachments you send |
|
||||
| `files:write` | Send images the Agent produces back to you |
|
||||
| `users:read` | Show a display name instead of a raw ID under **Paired Users** |
|
||||
|
||||
## Pairing
|
||||
|
||||
Back at the top of the page, under **Pairing**, select **Generate Code** to get a six-character code. This takes effect immediately; no **Save** is needed.
|
||||
|
||||
Send that code to the app as a direct message. Once pairing is confirmed, anything you type goes to Claude Code.
|
||||
|
||||
A code is valid for 60 minutes, works once, and is invalidated the moment a new one is generated. Five failed attempts within five minutes trigger rate limiting.
|
||||
|
||||
**Allowed Users** can stay empty, in which case only paired accounts can use the bot. To allow known colleagues directly, enter their Slack user IDs (starting with `U`) separated by commas.
|
||||
|
||||
## Supported commands
|
||||
|
||||
- `/help` or `帮助` — list the available commands
|
||||
- `/status` or `状态` — current project, model, and run state
|
||||
- `/projects` or `项目列表` — list recent projects and switch
|
||||
- `/new` or `新会话` — start a fresh session, optionally with an index, name, or absolute path
|
||||
- `/clear` or `清空` — clear the context, keep the project binding
|
||||
- `/stop` or `停止` — stop the current turn
|
||||
- Permission approval: reply `1` to allow once, `2` to allow for the session, `3` to deny; `/allow <id>`, `/always <id>`, and `/deny <id>` work too
|
||||
|
||||
These are ordinary message text, not Slack slash commands. The manifest requests no slash commands, so nothing here collides with what your workspace already defines.
|
||||
|
||||
## How messages look
|
||||
|
||||
A reply posts one message and then edits it in place, throttled to roughly one edit per second so it does not run into Slack's `chat.update` rate limit. When the answer outgrows a single message, the earlier part is sealed and the remainder continues in a new message that keeps updating.
|
||||
|
||||
Attachments you send are downloaded with the bot token from `files.slack.com` (only that host is accepted). Images go straight to the Agent; other files are staged in `~/.claude/im-downloads/slack/`. Local images referenced in the Agent's output (restricted to the current session's working directory) are sent back through Slack's external upload flow.
|
||||
|
||||
## Agent capability and boundaries
|
||||
|
||||
Slack is not a separate question-and-answer model. Messages enter the same Claude Code Agent session as the current project, so they continue the multi-turn context and can use the files, terminal, Git, Skills, and MCP tools that session already has.
|
||||
|
||||
That means a paired account holds the full Agent capability of the current project. Permission confirmation is a gate on individual operations, not an OS sandbox. Do not install the app into a workspace you do not trust, and do not install unreviewed Skills, plugins, or MCP servers from chat.
|
||||
|
||||
The adapter accepts only paired or allow-listed direct messages. Channel messages, edits, deletions, and the bot's own messages are discarded.
|
||||
|
||||
## Running it locally
|
||||
|
||||
Release builds start the adapter as a sidecar automatically. Manual startup is only needed when running from source:
|
||||
|
||||
```bash
|
||||
cd adapters
|
||||
bun install
|
||||
bun run slack
|
||||
```
|
||||
|
||||
Optional environment overrides:
|
||||
|
||||
```bash
|
||||
export SLACK_BOT_TOKEN="xoxb-..."
|
||||
export SLACK_APP_TOKEN="xapp-..."
|
||||
export ADAPTER_SERVER_URL="ws://127.0.0.1:3456"
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**The adapter exits with `invalid_auth`.** The bot token is wrong or the app is not installed into the workspace. Copy it again from **Install App**.
|
||||
|
||||
**Socket Mode reconnects in a loop.** The app-level token is missing the `connections:write` scope, or it has been revoked. Generate a new one.
|
||||
|
||||
**Direct messages get no response.** Confirm the `message.im` event subscription is still present and that the Messages Tab is enabled under **App Home**. If you edited the app configuration by hand, check it against the scope table above.
|
||||
|
||||
**Attachments never arrive.** `files:read` is missing; that scope only takes effect after reinstalling the app.
|
||||
|
||||
**Messages report "unauthorized".** Check that a pairing code was generated, that it is still inside its 60-minute window, and that you sent the current one.
|
||||
|
||||
## Source entry points
|
||||
|
||||
`adapters/slack/index.ts` (runtime), `adapters/slack/api.ts` (Web API wrapper), `adapters/slack/socket-mode.ts` (long connection), `adapters/slack/manifest.ts` (app manifest), `adapters/slack/extract-payload.ts` (inbound filtering), plus the shared session loop in `adapters/common/chat-runtime.ts`.
|
||||
@@ -0,0 +1,89 @@
|
||||
---
|
||||
title: WeCom Integration
|
||||
nav_title: WeCom
|
||||
description: Scan a QR code in Settings to create an Enterprise WeChat AI bot, then drive the Desktop app from a private chat with streaming replies.
|
||||
order: 6
|
||||
---
|
||||
|
||||
# WeCom Integration
|
||||
|
||||
For teams already on Enterprise WeChat. Select **Scan to Bind** in Settings, scan with the WeCom app, and the AI bot is created for you — its Bot ID and Secret land in local configuration without opening the admin console. Messages travel over the official WebSocket connection, so your machine needs no public address.
|
||||
|
||||
Limits: private chats only, no group chats; permission approval is a text reply, not a card.
|
||||
|
||||
## Create the bot by scanning
|
||||
|
||||
1. Open **Settings → IM Adapters** and switch to the **WeCom** tab.
|
||||
2. Select **Scan to Bind**. A QR code appears.
|
||||
3. Scan it with Enterprise WeChat and confirm creating the AI bot.
|
||||
4. On success the Bot ID and Secret are written to `~/.claude/adapters.json` and the adapter restarts.
|
||||
|
||||
The code expires after five minutes; **Scan Again** issues a new one. Once bound, the button becomes **Scan Again** and an **Unbind bot account** button appears next to it.
|
||||
|
||||
This step only gives the Desktop app the bot's credentials. It does **not** authorize your colleagues — that is what pairing below decides.
|
||||
|
||||
## Pairing
|
||||
|
||||
Back at the top of the page, under **Pairing**, select **Generate Code** to get a six-character code. This takes effect immediately; no **Save** is needed.
|
||||
|
||||
Send that code to the new bot in a private WeCom chat. Once pairing is confirmed, anything you type goes to Claude Code.
|
||||
|
||||
A code is valid for 60 minutes, works once, and is invalidated the moment a new one is generated. Five failed attempts within five minutes trigger rate limiting.
|
||||
|
||||
**Allowed Users** can stay empty, in which case only paired accounts can use the bot. To allow known colleagues directly, enter their WeCom `userid` values separated by commas and select **Save**.
|
||||
|
||||
## Supported commands
|
||||
|
||||
- `/help` or `帮助` — list the available commands
|
||||
- `/status` or `状态` — current project, model, and run state
|
||||
- `/projects` or `项目列表` — list recent projects and switch
|
||||
- `/new` or `新会话` — start a fresh session, optionally with an index, name, or absolute path
|
||||
- `/clear` or `清空` — clear the context, keep the project binding
|
||||
- `/stop` or `停止` — stop the current turn
|
||||
- Permission approval: reply `1` to allow once, `2` to allow for the session, `3` to deny; `/allow <id>`, `/always <id>`, and `/deny <id>` work too
|
||||
|
||||
## How messages look
|
||||
|
||||
Replies use WeCom stream messages: one bubble refreshes in place as the answer is generated, then settles. A single stream message caps at 20 KB, so anything beyond that continues as follow-up messages rather than being truncated.
|
||||
|
||||
Inbound images and files are decrypted into `~/.claude/im-downloads/wecom/` and forwarded to the Agent as attachments. Voice notes arrive already transcribed by WeCom and are handled as plain text. Local images referenced in the Agent's output (restricted to the current session's working directory) are uploaded and sent as separate image messages.
|
||||
|
||||
## Agent capability and boundaries
|
||||
|
||||
WeCom is not a separate question-and-answer model. Messages enter the same Claude Code Agent session as the current project, so they continue the multi-turn context and can use the files, terminal, Git, Skills, and MCP tools that session already has.
|
||||
|
||||
That means a paired account holds the full Agent capability of the current project. Permission confirmation is a gate on individual operations, not an OS sandbox. Do not hand the bot to people you do not trust, and do not install unreviewed Skills, plugins, or MCP servers from chat.
|
||||
|
||||
The adapter accepts only paired or allow-listed private chats, and project listing and name matching stay inside **Allowed project directories**.
|
||||
|
||||
## Running it locally
|
||||
|
||||
Release builds start the adapter as a sidecar automatically. Manual startup is only needed when running from source:
|
||||
|
||||
```bash
|
||||
cd adapters
|
||||
bun install
|
||||
bun run wecom
|
||||
```
|
||||
|
||||
Optional environment overrides:
|
||||
|
||||
```bash
|
||||
export WECOM_BOT_ID="xxx"
|
||||
export WECOM_BOT_SECRET="xxx"
|
||||
export ADAPTER_SERVER_URL="ws://127.0.0.1:3456"
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**No QR code appears.** The scan endpoint lives on `work.weixin.qq.com`; confirm your machine can reach it, and that a proxy is not blocking that host.
|
||||
|
||||
**Scanned successfully but the bot stays silent.** Confirm the Desktop app is still running and that the **WeCom** tab shows a Bot ID. Credentials are written the moment the scan succeeds, and the adapter restarts on its own.
|
||||
|
||||
**Messages report "unauthorized".** Check that a pairing code was generated, that it is still inside its 60-minute window, and that you sent the current one.
|
||||
|
||||
**Mentioning the bot in a group does nothing.** That is intended: only private chats are handled. Pairing authorizes one person, and answering in a group would extend that authorization to everyone in it.
|
||||
|
||||
## Source entry points
|
||||
|
||||
`adapters/wecom/index.ts` (runtime), `adapters/wecom/qr-auth.ts` (scan to create), `adapters/wecom/extract-payload.ts` (inbound parsing), plus the shared session loop in `adapters/common/chat-runtime.ts`.
|
||||
@@ -78,7 +78,7 @@ The server can bind a LAN-reachable address for H5, but the desktop renderer alw
|
||||
```text
|
||||
claude-sidecar server --app-root <path> --host <host> --port <port>
|
||||
claude-sidecar cli --app-root <path> [CLI arguments]
|
||||
claude-sidecar adapters --app-root <path> --telegram|--feishu|--wechat|--dingtalk|--whatsapp
|
||||
claude-sidecar adapters --app-root <path> --telegram|--feishu|--wechat|--dingtalk|--whatsapp|--wecom|--qq|--slack
|
||||
```
|
||||
|
||||
The sidecar sets `CLAUDE_APP_ROOT`, `CALLER_DIR`, and the launch arguments before importing any business module, because the top-level modules of the server, CLI, and adapters read those values at import time.
|
||||
|
||||
Reference in New Issue
Block a user