Foreword¶
To connect a chat entry for an agent, a common approach is to self-host an HTTP service and have the agent poll or receive webhooks. For an environment like WeChat with a closed entry point and requiring persistent login, building the service is only half the battle: account login, message sending and receiving, session isolation, rate limiting, and deduplication all need separate solutions. Below is an introduction to the plugin dsh-wechat-pad, which bridges the “WeChat entry point” and the “DSH agent”.
It is maintained by QIC-9821 and classified as a “Client” in the community directory. The plugin itself contains no WeChat protocol implementation; instead, it interfaces with a self-hosted iPad protocol endpoint (currently adapted for the WeChatPadPro interface): the endpoint is responsible for login and message sending/receiving, while the plugin is responsible for “who is speaking, whether to reply, which session to delegate to, and how to reply.”
What is it¶
One-sentence positioning: A Host plugin for DeepSeek Harness (DSH) that integrates personal WeChat, replying casually to DMs and speaking only when mentioned in groups.
It does three things:
- Receives messages from the endpoint’s webhook and decides whether to forward them to the agent based on rules.
- Builds context with a “one group, one independent session” rule, ensuring DMs and group chats don’t interfere with each other.
- Sends the agent’s replies back to WeChat, handling long messages by chunking, providing a timeout fallback, and rate-limiting to prevent spam.
It does not implement the protocol, does not provide the endpoint or accounts or means to bypass risk control. The project status is marked as experimental, License is MIT, npm package version is 0.2.1, and it requires Node.js >= 22.
Core Capabilities¶
Private Chat: Replies to messages as soon as they are received; can be disabled in configuration.
Group Chat: Only replies when mentioned; the reply includes the @user prefix; it does not speak in groups not on the whitelist by default.
Session Isolation: Chatting in groups and DMs each have their own context. Switching groups is equivalent to switching sessions; content from Group A will not be brought into Group B.
Control Panel: The /wechat-pad page allows for QR code login, checking connection status, toggling group whitelists, and viewing statistics (how many received, how many replied, why skipped).
Webhook Auto-Configuration: Once the callback URL is filled in, the plugin writes it back to the endpoint during startup; this can also be disabled manually (autoConfigureWebhook: false).
How it works¶
WeChat ←→ Protocol Endpoint (WeChatPadPro, running on your machine/cloud)
│ webhook (messages)
▼
dsh-wechat-pad (Host plugin, running inside DSH)
│ session/create · session/prompt · session/event
▼
DSH agent ←→ Your model, your tools, your memory
│ reply
▼
Protocol Endpoint SendText → WeChat
The plugin runs within the DSH process, directly invoking the host’s session service without HTTP intermediaries, so no launch token is needed. The panel and webhook are both served by DSH’s own webServer, without opening extra ports.
Prerequisites¶
Before installing, make sure you have these ready:
- A machine that can run the protocol endpoint: Linux (recommended, Docker is fine) or Windows, available 24/7. If the endpoint goes offline, WeChat messages will not be received.
- A WeChat account you are willing to accept consequences for; using a side account is recommended.
- A fixed external IP address and an address that allows the endpoint to callback to DSH. If the endpoint and DSH are on different machines, you need a public address or tunnel (cloudflared / frp / tailscale all work), and the webhook path must route directly to DSH.
- DSH 0.2.x (desktop bundle or
dshCLI).
Installation & Enablement¶
Install in DSH’s profile, choose one:
# npm (recommended)
dsh plugin add dsh-wechat-pad
# Direct from GitHub tag
dsh plugin add github:QIC-9821/dsh-wechat-pad#v0.1.0
# From local directory (for development)
dsh plugin add /path/to/dsh-wechat-pad
The commands above are from the project README. After installation, enable dsh-wechat-pad in “Settings → Plugins” or write it directly into the bundles in the profile. After enabling on the desktop version, refresh the page to see the panel; changes to configuration require restarting DSH to take effect. After enabling, open:
http://127.0.0.1:<DSH Port>/wechat-pad
Configuration¶
Configuration is written in the plugin config (config in cordis.patch.yml, or the settings page form). Only two items are required: padUrl and token.
| Key | Default | Description |
|---|---|---|
padUrl |
— | Protocol endpoint address, e.g., http://127.0.0.1:8080 |
padToken |
— | Protocol endpoint AuthKey (plaintext, not recommended for long-term use) |
padTokenRef |
DSH_WECHAT_PAD_TOKEN |
Key name to retrieve token from credential store / environment variable (recommended) |
hookPath |
/wechat-pad/hook |
Path to receive protocol endpoint callbacks |
webhookSecret |
Auto-generated | Callback secret; leave blank to generate during startup and save to state file |
autoConfigureWebhook |
true |
Write callback URL back to protocol endpoint during startup |
selfWxid |
Auto-detected | The bot’s own wxid |
botNames |
[] |
Aliases, used to identify formats like @assistant |
answerDirectMessages |
true |
Whether to reply to DMs |
defaultTrigger |
mention |
Default group trigger method: mention (mentioned) or all |
groups |
[] |
Group whitelist, see below |
allowUnknownGroups |
false |
Whether to reply to groups not on the whitelist (not recommended) |
timeoutSec |
120 |
Upper limit for waiting for agent response |
timeoutReply |
I'm thinking for a bit, let me answer you later |
Fallback message on timeout |
maxReplyChars |
4000 |
Maximum characters for a single reply |
chunkChars |
1500 |
Split into chunks if exceeding this limit |
chunkDelayMs |
1500 |
Delay between chunks |
ratePerMinPerGroup |
5 |
Max replies per group per minute |
ratePerMinGlobal |
10 |
Global limit per minute |
queueLimit |
5 |
Per-group queue limit; drops and logs if exceeded |
dedupeTtlSec |
3600 |
Time window to prevent reprocessing the same message |
stateDir |
~/.dsh/wechat-pad |
State file directory (session binding, deduplication, whitelist) |
workspaceDir |
~/.dsh/wechat-pad/workspace |
Working directory for sessions |
systemHint |
Empty | Fixed hint prepended to every prompt |
Format of the group whitelist:
groups:
- id: 12345678@chatroom # Group id (ending with @chatroom)
name: Tech Discussion Group # Optional, only for display
enabled: true
trigger: mention # mention | all
ratePerMin: 3
You can find the group ID in the raw payload of the endpoint’s webhook: the “Statistics” in the panel shows recent messages, or open logRawPayloads and check stateDir/raw/.
It is recommended to use padTokenRef to retrieve the token from environment variables or the credential store; do not put the plaintext token in the config file and commit to git.
Typical Usage¶
After installation, run through these steps:
- Open
http://127.0.0.1:<Port>/wechat-pad, click “Scan to Login”, and scan with your phone’s WeChat. - Wait for the panel to show “Online”.
- Add the bot to a group; it will only speak when mentioned; DMs are replied to directly.
- To make the bot speak only in certain groups, fill in the
groupswhitelist.
Besides the config file, DSH’s “Settings → WeChat” page has runtime switches. Save after changing, and the next message will follow the new rules without restarting DSH. Useful items in this page:
| Setting | Default | Effect |
|---|---|---|
| Enable Auto Reply | On | When off, messages are received but not forwarded to the model |
| How to speak in group | Reply only when @ me | “Reply only on @”/”Reply every sentence”/”Ignore group” |
| DM Auto Reply | On | When off, only records without replying |
| Auto join new groups | Off | When on, groups not on the whitelist will also reply |
| Consecutive Message Merge Window | 800 ms | Merge multiple messages from the same person into one prompt to save context |
| Single Reply Limit | 4000 chars | Truncates if exceeded |
| Long Reply Chunk Length | 1500 chars | Splits long replies into multiple messages |
| Wait Model Timeout | 120 seconds | Fallback message on timeout |
| Limit per minute (Single/Global) | 5 / 10 | Prevent spam |
| Style Prompt | Two or three sentences | Added before every prompt to limit tone and length |
Runtime settings are saved to <stateDir>/settings.json, overriding the same items in the config file. The panel also has two buttons: “Scan Now” and “Reopen Session”.
Applicable Scenarios & Notes¶
Suitable for those already running their own agent in DSH, want to use it to respond in WeChat groups, and are willing to maintain the protocol endpoint themselves. The endpoint needs to be online 24/7, suitable for placing on a cloud host or a machine that stays on.
Points to know in advance:
- Ban Risk: Logging in to personal WeChat via a non-official protocol violates the WeChat software license and service agreement. The documentation explicitly states that accounts may be banned, ranging from 1 day to permanent. Frequent disconnections on first login; re-scan according to the endpoint documentation and ensure a stable device. Please only use this on your own account, and accept the consequences.
- Permissions: The plugin creates sessions with the host’s owner identity; the tools the agent can use are exactly those you give it in DSH. If this account speaks to strangers, do not enable dangerous tools for it.
- Privacy: Messages pass through your protocol endpoint → your DSH → your model provider. Do not send things that shouldn’t be seen by the model.
- Secrets: Use
padTokenRefto retrieve the token from environment variables/credential store. - Compatibility: Currently tested only for WeChatPadPro (
/api/login/*,/api/v1/message/*,/v1/webhook/*). Switching to a different backend requires implementing the same endpoints or modifying the path table inlib/pad-client.js.
It is recommended to check the source code and license (MIT) before installing. The project comes with 11 tests covering parsing, strategy, deduplication, rate limiting, chunking, timeout, and e2e. The e2e runs successfully using test/mock-pad.mjs as a fake protocol endpoint (“webhook → session → reply”) and does not depend on real WeChat; you can run npm test first to see if behavior meets expectations.
Conclusion¶
The value of dsh-wechat-pad lies in solidifying the glue layer between the “WeChat entry point” and the “DSH agent”: session isolation, @ triggers, rate limiting, deduplication, and chunked replies are all handled. The only things left for you to build are the protocol endpoint and a machine that stays online. It is still experimental, and the protocol endpoint is not an official interface; think clearly about the risk of bans before using.
Directory: https://www.skillhub.cn/plugins/QIC-9821/dsh-wechat-pad
GitHub: https://github.com/QIC-9821/dsh-wechat-pad
npm: https://www.npmjs.com/package/dsh-wechat-pad