Prerequisites
- A WeCom organization account
- An AI Bot created in the WeCom Admin Console
- The Bot ID and Secret from the bot’s credentials page
- Python packages:
aiohttpandhttpx
Setup
Step 1: Create an AI Bot
Recommended: Scan-to-Create (one command)
- Display a QR code in your terminal
- Wait for you to scan it with the WeCom mobile app
- Automatically retrieve the Bot ID and Secret
- Guide you through access control configuration
Alternative: Manual Setup
If scan-to-create is not available, the wizard falls back to manual input:- Log in to the WeCom Admin Console
- Navigate to Applications → Create Application → AI Bot
- Configure the bot name and description
- Copy the Bot ID and Secret from the credentials page
- Run
mibyan gateway setup, select WeCom, and enter the credentials when prompted
Step 2: Configure Mibyan
Option A: Interactive Setup (Recommended)
- Bot credentials (via QR scan or manual entry)
- Access control settings (allowlist, pairing mode, or open access)
- Home channel for notifications
Option B: Manual Configuration
Add the following to~/.mibyan/.env:
Step 3: Start the gateway
Features
- WebSocket transport — persistent connection, no public endpoint needed
- DM and group messaging — configurable access policies
- Per-group sender allowlists — fine-grained control over who can interact in each group
- Media support — images, files, voice, video upload and download
- AES-encrypted media — automatic decryption for inbound attachments
- Quote context — preserves reply threading
- Markdown rendering — rich text responses
- Reply correlation — responses are correlated to the inbound message context
- Auto-reconnect — exponential backoff on connection drops
Streaming and typing indicatorsThe WeCom adapter streams responses natively over WeCom’s
msgtype: "stream"
protocol: the client shows a thinking/typing bubble as soon as a turn starts,
and the reply renders token-by-token in a single bubble as the model
generates it. Tool-call progress is folded into the same bubble. Native
streaming follows the global streaming switch, which is off by default: turn it
on with streaming.enabled: true in config.yaml. WeCom’s per-platform
display.platforms.wecom.streaming (default true) only applies while the
global switch is on; set it to false to keep single-shot delivery on WeCom.Configuration Options
Set these inconfig.yaml under platforms.wecom.extra:
Access Policies
DM Policy
Controls who can send direct messages to the bot:Group Policy
Controls which groups the bot responds in:Per-Group Sender Allowlists
For fine-grained control, you can restrict which users are allowed to interact with the bot within specific groups. This is configured inconfig.yaml:
- The
group_policyandgroup_allow_fromcontrols determine whether a group is allowed at all. - If a group passes the top-level check, the
groups.<group_id>.allow_fromlist (if present) further restricts which senders within that group can interact with the bot. - A wildcard
"*"group entry serves as a default for groups not explicitly listed. - Allowlist entries support the
*wildcard to allow all users, and entries are case-insensitive. - Entries can optionally use the
wecom:user:orwecom:group:prefix format — the prefix is stripped automatically.
allow_from is configured for a group, all users in that group are allowed (assuming the group itself passes the top-level policy check).
Media Support
Inbound (receiving)
The adapter receives media attachments from users and caches them locally for agent processing:
Quoted messages: Media from quoted (replied-to) messages is also extracted, so the agent has context about what the user is replying to.
AES-Encrypted Media Decryption
WeCom encrypts some inbound media attachments with AES-256-CBC. The adapter handles this automatically:- When an inbound media item includes an
aeskeyfield, the adapter downloads the encrypted bytes and decrypts them using AES-256-CBC with PKCS#7 padding. - The AES key is the base64-decoded value of the
aeskeyfield (must be exactly 32 bytes). - The IV is derived from the first 16 bytes of the key.
- This requires the
cryptographyPython package (mibyan pm repair).
Outbound (sending)
Chunked upload: Files are uploaded in 512 KB chunks through a three-step protocol (init → chunks → finish). The adapter handles this automatically.
Automatic downgrade: When media exceeds the native type’s size limit but is under the absolute 20 MB file limit, it is automatically sent as a generic file attachment instead:
- Images > 10 MB → sent as file
- Videos > 10 MB → sent as file
- Voice > 2 MB → sent as file
- Non-AMR audio → sent as file (WeCom only supports AMR for native voice)
Reply-Mode Responses
When the bot receives a message via the WeCom callback, the adapter remembers the inbound request ID. If a response is sent while the request context is still active, the adapter uses WeCom’s reply-mode (aibot_respond_msg) to correlate the response directly to the inbound message. This provides a more natural conversation experience in the WeCom client.
When a native reply stream is active, the response streams incrementally through reply-mode msgtype: "stream" frames. If the inbound request context has expired or is unavailable (or a stream frame fails), the adapter falls back to proactive message sending via aibot_send_msg.
Reply-mode also works for media: uploaded media can be sent as a reply to the originating message.
Connection and Reconnection
The adapter maintains a persistent WebSocket connection to WeCom’s gateway atwss://openws.work.weixin.qq.com.
Connection Lifecycle
- Connect: Opens a WebSocket connection and sends an
aibot_subscribeauthentication frame with the bot_id and secret. - Heartbeat: Sends application-level ping frames every 30 seconds to keep the connection alive.
- Listen: Continuously reads inbound frames and dispatches message callbacks.
Reconnection Behavior
On connection loss, the adapter uses exponential backoff to reconnect:
After each successful reconnection, the backoff counter resets to zero. All pending request futures are failed on disconnect so callers don’t hang indefinitely.

