Skip to content

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) ​

  1. Register on the QQ Open Platform and create a bot to obtain the AppID + AppSecret.
  2. 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 to PUBLIC_GUILD_MESSAGES (1<<30) and DIRECT_MESSAGE (1<<12) respectively.
  3. 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)

bash
# .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)

bash
# 查看当前配置(脱敏)
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/config

After 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)

bash
# 生成配对码(管理员,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 ​

CommandBehavior
Send a message directlySubmit 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
/unbindUnbind
/newCreate a new session and switch the binding
/statusView the current session status
/listSession list
/stopInterrupt the current task
/approve <once|always_tool|always_command|deny>Approval (you can also simply send "同意/全部同意/拒绝")
/answer <内容>Answer a question
/helpHelp

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 /stop or 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 ​

bash
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 pass are persisted encrypted with AES using SECRET_KEY.
  • events controls when notifications are triggered; the example above only sends email on "completed/error".
  • No interruption for short tasks: minDurationSeconds (default 60) — when a task completes successfully and its execution time does not exceed this threshold, no email is sent.