How to Integrate AstrBot with WeChat and QQ: Multi-platform Chatbot Setup
Problem
I wanted to deploy a single chatbot instance that works across QQ, WeChat Work, and WeChat Official Accounts. But when I tried to connect NapCatQQ to AstrBot, I got connection refused errors:
[ERROR] WebSocket connection failed: Connection refused[ERROR] Failed to connect to ws://localhost:6199/wsAnd when I configured WeChat Work webhooks, messages weren’t reaching AstrBot at all. The multi-platform setup seemed impossible.
Environment
- AstrBot (latest version via Docker)
- NapCatQQ for QQ integration
- WeChat Work (企业微信) enterprise account
- Docker and Docker Compose
- Ubuntu 22.04 server
What Happened?
I was building a customer service bot for a Chinese company. They needed the same bot to work on QQ groups, WeChat Work internal groups, and their WeChat Official Account.
Here’s what I tried first - running AstrBot and NapCatQQ separately:
# Started AstrBotdocker run -d -p 6185:6185 -p 6199:6199 --name astrbot soulter/astrbot:latest
# Started NapCatQQ separatelydocker run -d --name napcat mlikiowa/napcat-docker:latestThen I configured AstrBot’s OneBot v11 adapter in the WebUI:
id: "qq-bot-1"enabled: truereverse_ws_host: "0.0.0.0"reverse_ws_port: 6199reverse_ws_token: ""In NapCatQQ’s web UI, I set the reverse WebSocket URL to:
ws://localhost:6199/wsBut when I sent a message on QQ, nothing happened. No response from the bot.
Understanding the Architecture
AstrBot uses a modular adapter system. Each platform gets its own adapter type:
┌─────────────────┐ │ AstrBot Core │ │ (Event Bus + │ │ LLM Provider) │ └────────┬────────┘ │ ┌──────────────────┼──────────────────┐ │ │ │ ▼ ▼ ▼ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ AIOCQHTTP │ │ GEWECHAT │ │ QQOFFIC │ │ (QQ via │ │ (WeChat │ │ (WeChat │ │ NapCat) │ │ Work) │ │ Official)│ └───────────┘ └───────────┘ └───────────┘ │ │ │ ▼ ▼ ▼ QQ NT Client Webhook URL Server Config + NapCatQQ (HTTPS) (Token + Encoding)The key insight: all adapters can run simultaneously, sharing the same LLM provider and plugins.
How I Solved QQ Integration
The connection refused error had two causes:
- Docker networking:
localhostdoesn’t work between containers - Port binding: I needed the reverse WebSocket port exposed
Solution 1: Docker Compose (Recommended)
I found that NapCat provides a pre-configured compose file for AstrBot:
mkdir astrbot && cd astrbotwget https://raw.githubusercontent.com/NapNeko/NapCat-Docker/main/compose/astrbot.ymlsudo docker compose -f astrbot.yml up -dThis puts both containers on the same network automatically.
Solution 2: Manual Network Configuration
Since I already had containers running, I created a shared network:
sudo docker network create astrbot-netsudo docker network connect astrbot-net astrbotsudo docker network connect astrbot-net napcatsudo docker restart astrbotsudo docker restart napcatConfiguring the WebSocket URL
The URL depends on your deployment:
# Both AstrBot and NapCat in Docker (same network)ws://astrbot:6199/ws
# Only NapCat in Docker, AstrBot on hostws://host.docker.internal:6199/ws
# Both on host (no Docker)ws://localhost:6199/ws
# NapCat on host, AstrBot in Dockerws://<server-ip>:6199/wsIn NapCatQQ’s configuration, I set:
{ "Type": "ReverseWebSocket", "Host": "astrbot", "Port": 6199, "Suffix": "/ws", "ReconnectInterval": 5000, "HeartBeatInterval": 5000, "AccessToken": ""}Now when I restart NapCatQQ, I see the connection succeed:
[INFO] WebSocket connected to ws://astrbot:6199/ws[INFO] OneBot v11 adapter registered: qq-bot-1WeChat Work Integration
WeChat Work uses webhooks instead of WebSocket. This is simpler but has its own quirks.
Step 1: Create the Robot
In WeChat Work admin console:
- Go to Application Management > Robots
- Create a new robot in an internal group
- Copy the webhook URL
Step 2: Configure AstrBot Adapter
In AstrBot WebUI, I added a GEWECHAT adapter:
id: "wecom-bot"enabled: truewebhook_url: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR-KEY"But there’s a problem: WeChat Work robots can only send messages, not receive them through webhooks.
Step 3: Enable Webhook-Only Mode
For bidirectional communication, I needed to use AstrBot’s unified webhook mode:
{ "platform_specific": { "wecom_bot": { "enable": true, "streaming": true, "webhook_only": true } }}The webhook_only setting bypasses WeChat Work’s single-bubble limitation. The trade-off: no typing animation, but complex messages (cards, images) work.
Step 4: Set Up the Webhook Endpoint
AstrBot generates a webhook URL when you create a GEWECHAT adapter:
https://your-server.com/webhook/astrbot-uuid-hereI pointed my reverse proxy (nginx) to AstrBot’s port 6185:
location /webhook/ { proxy_pass http://127.0.0.1:6185; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr;}Important: WeChat requires HTTPS. I used Let’s Encrypt for the SSL certificate.
WeChat Official Account Setup
WeChat Official Accounts are more complex. They use a server configuration push/pull model.
Prerequisites
- Verified WeChat Official Account (not personal)
- Server with public IP and domain
- SSL certificate (HTTPS required)
Configuration in AstrBot
I added another adapter for the Official Account:
id: "wechat-official"enabled: trueadapter_type: "GEWECHAT"token: "my-secret-token"encoding_aes_key: "generated-43-char-key"Then in WeChat Official Account admin console:
- Go to Settings > Basic Configuration
- Set Server URL:
https://your-domain.com/webhook/wechat-official - Set Token:
my-secret-token - Set EncodingAESKey:
generated-43-char-key - Enable message encryption
The verification request from WeChat will hit your endpoint. AstrBot handles the signature validation automatically.
Managing Multiple Platforms
Now I had three adapters running. But I needed to handle platform-specific behavior.
Platform-Specific Settings
AstrBot stores platform settings in platform_specific:
{ "platform_specific": { "qq_bot_1": { "pre_ack_emoji": { "enable": true, "emoji": "👀" } }, "wecom_bot": { "streaming": true, "webhook_only": true }, "wechat_official": { "rate_limit": { "max_messages_per_minute": 5 } } }}The pre_ack_emoji sends a reaction before the LLM responds - useful for QQ where users expect immediate feedback.
Rate Limiting Differences
Each platform has different limits:
| Platform | Limit | Notes |
|---|---|---|
| QQ (NapCat) | ~20 msg/min | Per group |
| WeChat Work | ~30 msg/min | Per robot |
| WeChat Official | 5 msg/sec | Global |
I configured this in AstrBot’s main settings:
rate_limit: enabled: true default_limit: 20 platform_overrides: wechat_official: 5Event Filtering in Plugins
When writing plugins, I needed to filter by platform:
from astrbot.api.event import filter, AstrMessageEvent, PlatformAdapterTypefrom astrbot.api.star import Context, Star, register
@register("multi_platform_greeting", "author", "Greeting plugin", "1.0.0", "repo")class MultiPlatformGreeting(Star): def __init__(self, context: Context): super().__init__(context)
@filter.command("hello") async def hello(self, event: AstrMessageEvent): # Different response per platform if event.platform_meta.platform_name == "GEWECHAT": yield event.plain_result("您好!我是您的专属助手。") elif event.platform_meta.platform_name == "AIOCQHTTP": yield event.plain_result("你好!我是你的QQ机器人。") else: yield event.plain_result("Hello! I'm your chatbot.")
@filter.platform(PlatformAdapterType.GEWECHAT) @filter.command("wechat_help") async def wechat_help(self, event: AstrMessageEvent): # This only triggers on WeChat platforms yield event.plain_result("WeChat帮助信息...")The @filter.platform() decorator ensures the command only works on specific platforms.
Common Issues I Encountered
Issue 1: NapCat Connection Refused
Symptoms: AstrBot shows no incoming messages from QQ.
Causes:
- Wrong WebSocket URL (using
localhostin Docker) - Port not exposed
- Different Docker networks
Fix:
# Check if NapCat can reach AstrBotdocker exec napcat ping astrbot
# Verify port is listeningdocker exec astrbot netstat -tlnp | grep 6199Issue 2: WeChat Work Messages Not Received
Symptoms: Webhook tests work, but group messages don’t reach AstrBot.
Cause: WeChat Work robots don’t receive messages through webhooks by default.
Fix: Use the robot in “at” mode - users must @mention the robot for it to respond.
Issue 3: WeChat Official Account Verification Failed
Symptoms: WeChat admin console shows “Token verification failed”.
Cause: Signature mismatch or wrong endpoint.
Fix:
# Check AstrBot logsdocker logs astrbot | grep -i wechat
# Verify endpoint is accessiblecurl -v https://your-domain.com/webhook/wechat-officialThe endpoint should return the echostr parameter for GET requests.
Deployment Best Practices
Running as a Service
I created a systemd service for AstrBot:
[Unit]Description=AstrBot Multi-Platform ChatbotAfter=docker.serviceRequires=docker.service
[Service]Type=simpleUser=astrbotWorkingDirectory=/opt/astrbotExecStart=/usr/bin/docker compose -f astrbot.yml upExecStop=/usr/bin/docker compose -f astrbot.yml downRestart=alwaysRestartSec=10
[Install]WantedBy=multi-user.targetSecurity Considerations
- Access tokens: Never commit tokens to git. Use environment variables.
- HTTPS: Required for WeChat webhooks.
- IP whitelisting: WeChat allows IP restrictions for Official Accounts.
- Rate limiting: Prevents bot abuse.
# Create .env fileecho "NAPCAT_TOKEN=$(openssl rand -hex 16)" > .envecho "WECHAT_TOKEN=$(openssl rand -hex 16)" >> .envThe Reason for These Issues
The core problem is that each Chinese IM platform uses different protocols:
- QQ: OneBot v11 over WebSocket (community standard)
- WeChat Work: Proprietary webhooks with rate limits
- WeChat Official: Server configuration with signature validation
AstrBot abstracts these differences through adapter types. The AIOCQHTTP type handles OneBot v11 (QQ), while GEWECHAT handles WeChat variants.
The Docker networking issue is common: containers on different networks can’t communicate via localhost. Either use Docker Compose (automatic network) or manually connect containers.
Summary
In this post, I showed how to integrate AstrBot with QQ, WeChat Work, and WeChat Official Accounts simultaneously. The key points are:
- Use Docker Compose for QQ integration to avoid network issues
- WeChat Work requires webhook-only mode for bidirectional messaging
- WeChat Official Accounts need HTTPS and proper token configuration
- Platform-specific settings handle differences in rate limits and features
- Event filtering in plugins enables platform-aware behavior
The unified architecture means one LLM provider and one plugin system serves all platforms. This reduces maintenance overhead and ensures consistent behavior across channels.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
- 👨💻 AstrBot Official Documentation
- 👨💻 NapCat Documentation
- 👨💻 OneBot v11 Standard
- 👨💻 WeChat Work API Documentation
- 👨💻 AstrBot GitHub Repository
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments