QQ Bot
Use the official QQ bot to submit tasks to zqagent, and get notified by email (SMTP) when tasks complete. Supports direct messages, group chats (@bot), channels, and the full range of interactions such as approval / questions / interruption.
The official bot uses a long-lived connection, so no public inbound access is required; self-hosted/intranet servers can also receive messages.
Platform Preparation (One-Time)
- Register on the QQ Open Platform and create a bot to obtain the
AppID+AppSecret. - Apply for intents permissions such as
GROUP_AND_C2C_EVENT(1<<25) (direct message + group message events are special permissions that require an application; otherwise gateway authentication will reject them). Channel @ mentions and channel direct messages correspond toPUBLIC_GUILD_MESSAGES(1<<30) andDIRECT_MESSAGE(1<<12) respectively. - Use the sandbox environment during integration testing (only sandbox members can test); going live requires review.
Configuration
Option 1: .env environment variables (read at startup)
# .env
QQ_BOT_APP_ID=你的AppID
QQ_BOT_APP_SECRET=你的AppSecret
QQ_BOT_SANDBOX=1 # 沙箱=1;正式环境=0 或留空Option 2: Hot configuration (while the server is already running, no restart needed; takes effect immediately by reconnecting)
# 查看当前配置(脱敏)
curl -s -H "Authorization: Bearer <租户apiKey>" http://localhost:8787/api/v1/qq/config
# 配置 / 更新
curl -s -X POST -H "Authorization: Bearer <租户apiKey>" -H "Content-Type: application/json" \
-d '{"appId":"你的AppID","appSecret":"你的AppSecret","sandbox":true}' \
http://localhost:8787/api/v1/qq/config
# 删除配置(断开)
curl -s -X DELETE -H "Authorization: Bearer <租户apiKey>" http://localhost:8787/api/v1/qq/configAfter setup, QQ 机器人: 已启用 appears in the logs. Hot configuration is saved with the server and still takes effect after a restart (configuration source priority: environment variables > saved configuration).
Multi-Tenant Binding
Option 1: Single tenant, no binding required (recommended for personal use)
When the system has only one tenant (such as the default demo), no binding operation is needed — simply send a message and it is automatically bound to the single tenant and the task starts.
Option 2: Pairing code binding (multi-tenant)
# 生成配对码(管理员,REST API)
curl -X POST http://localhost:8787/api/v1/qq/pairing-code \
-H "Authorization: Bearer <租户apiKey>"
# → { "data": { "code": "AB3CD5K7", "expiresIn": 300 } }Binding by the user inside QQ:
/bind AB3CD5K7
→ 绑定成功 ✅ 租户:demo。现在直接发消息即可开始任务。- The pairing code is valid for 5 minutes and single-use (to avoid the plaintext apiKey ending up in chat logs).
- Each QQ conversation maps to one tenant + one zqagent session; the session is created automatically when the first task is sent.
- Binding mappings are persisted to
{DATA_DIR}/qq/bindings.json.
Command List
| Command | Behavior |
|---|---|
| Send a message directly | Submit a task (used as the answer while waiting for a question; used as steering while a task is running) |
/bind <配对码> | Bind the current QQ conversation to a tenant |
/unbind | Unbind |
/new | Create a new session and switch the binding |
/status | View the current session status |
/list | Session list |
/stop | Interrupt the current task |
/approve <once|always_tool|always_command|deny> | Approval (you can also simply send "同意/全部同意/拒绝") |
/answer <内容> | Answer a question |
/help | Help |
Sending a message directly while a task is running injects it into the current task as steering (supplemental input); to start a separate task, first run
/stopor wait for the task to finish.
Notification Callbacks and Approval
Key events during task execution are sent back to the corresponding QQ conversation. Approval requests include the tool name + tool parameters + reason:
需要审批:write_file
参数:
{
"path": "/tmp/a.txt",
"content": "hello"
}
原因:需要写文件
回复:同意(仅本次) / 全部同意(总是允许) / 拒绝同意/允许/y→ allow this time only (once)全部同意/总是允许→ always allow this tool within this session (always_tool)拒绝/n→ deny (deny)
⚠️ The official QQ bot has a strict quota for proactive messages; task completion usually falls outside the "5-minute passive reply window", so completion notifications use email as the reliable channel, while callbacks inside QQ are best-effort.
Configuring Email Notifications
curl -X POST http://localhost:8787/api/v1/notifications \
-H "Authorization: Bearer <租户apiKey>" -H "Content-Type: application/json" \
-d '{
"type": "email",
"enabled": true,
"config": {
"host": "smtp.qq.com",
"port": "465",
"secure": "true",
"user": "you@qq.com",
"pass": "<QQ邮箱授权码>",
"from": "you@qq.com",
"to": "you@qq.com"
},
"events": { "approval": false, "question": false, "completed": true, "error": true }
}'- QQ Mail:
smtp.qq.com:465(SSL) + authorization code (not your login password). - 163:
smtp.163.com:465; Gmail:smtp.gmail.com:587(secure:"false"). - Sensitive fields such as
passare persisted encrypted with AES usingSECRET_KEY. eventscontrols when notifications are triggered; the example above only sends email on "completed/error".- No interruption for short tasks:
minDurationSeconds(default60) — when a task completes successfully and its execution time does not exceed this threshold, no email is sent.
