Skip to content

feat(gateway): add QQBot platform adapter (Official API v2)#9364

Merged
teknium1 merged 5 commits into
mainfrom
pr-8269
Apr 14, 2026
Merged

feat(gateway): add QQBot platform adapter (Official API v2)#9364
teknium1 merged 5 commits into
mainfrom
pr-8269

Conversation

@teknium1

@teknium1 teknium1 commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Salvage of PR #7616 by @topcheer and @xing8star — adds QQ Bot as a fully supported messaging platform in the Hermes gateway using the raw Official QQ Bot API v2 (no SDK dependency).

Replaces the earlier #8269 salvage (qq-botpy SDK) with the significantly better #7616 implementation (raw aiohttp + httpx). Cherry-picked contributor commits onto current main, then fixed 3 missing integration points and added ISO 8601 timestamp parsing.

Why #7616 over #8269

PR #8269 (qq-botpy SDK) PR #7616 (raw API v2)
Dependencies qq-botpy (new optional dep) aiohttp + httpx (already in our deps)
Voice STT None Full pipeline: QQ ASR → Whisper → SILK→WAV
WebSocket lifecycle Black-box SDK Explicit heartbeat, close codes, resume
ACL policies None dm_policy/group_policy (open/allowlist/disabled)
Media upload SDK file_image (limited) REST API v2 base64 upload with retry
Typing indicator No-op C2C input_notify
Markdown Strips everything Configurable markdown_support (msg_type 2)
Streaming fix None Non-editable platform handling
Lines ~690 ~1930 (all substance)
Tests 53 65
Docs None Full setup guide + env vars page

Changes from original PR #7616

3 missing integration points filled:

  • gateway/run.py: Platform.QQBOT added to _UPDATE_ALLOWED_PLATFORMS
  • gateway/platforms/webhook.py: "qqbot" added to cross-platform delivery routing
  • hermes_cli/dump.py: "qqbot" added to platform detection

ISO 8601 timestamp fix (from PR #2411 finding):

  • Added _parse_qq_timestamp() — handles both ISO 8601 strings and integer milliseconds
  • QQ API changed timestamp format mid-flight; this handles both gracefully
  • Wired into all 4 message handlers (previously used datetime.now())

Test fix:

  • Fixed test_name_property casing: adapter returns "QQBot" not "QQBOT"

What this PR includes

Adapter (~1930 lines):

  • Raw WebSocket gateway with explicit heartbeat (80% of server interval)
  • Close code handling (4004 token refresh, 4006-4009 re-identify, 4008 rate limit, 4914/4915 fatal)
  • Session resume (op 6) with seq tracking, quick disconnect detection
  • Voice STT: QQ built-in ASR → external STT fallback (OpenAI/Whisper/Zhipu GLM-ASR) → SILK→WAV conversion
  • ACL: configurable dm_policy and group_policy (open/allowlist/disabled)
  • Native media upload via REST API v2 (base64, with 3-attempt retry + file_info cache)
  • C2C typing indicator (input_notify)
  • Configurable markdown support (msg_type 2 for guild channels)
  • Message dedup (300s window, 1000 max)
  • Exponential backoff reconnect [2,5,10,30,60] up to 100 attempts

Integration (20 files):
All 34 checklist points covered — config, run.py, cron, CLI setup/status/dump/platforms, send_message tool, toolsets, prompt hints, webhook routing, docs.

Tests: 65 tests covering init, ACL policies, heartbeat, dispatch routing, session management, JSON parsing, message types, STT config, close codes, message building.

Docs: Full setup guide at website/docs/user-guide/messaging/qqbot.md + env vars reference.

Test results

tests/gateway/test_qqbot.py  — 65 passed
tests/gateway/               — 2757 passed, 13 failed (all pre-existing)

Credit

Closes #8269, #7616, #7711, #7550, #7268, #2411

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Supply Chain Risk Detected

This PR contains patterns commonly associated with supply chain attacks. This does not mean the PR is malicious — but these patterns require careful human review before merging.

⚠️ WARNING: Install hook files modified

These files can execute code during package installation or interpreter startup.

Files:

hermes_cli/setup.py

Automated scan triggered by supply-chain-audit. If this is a false positive, a maintainer can approve after manual review.

1 similar comment
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Supply Chain Risk Detected

This PR contains patterns commonly associated with supply chain attacks. This does not mean the PR is malicious — but these patterns require careful human review before merging.

⚠️ WARNING: Install hook files modified

These files can execute code during package installation or interpreter startup.

Files:

hermes_cli/setup.py

Automated scan triggered by supply-chain-audit. If this is a false positive, a maintainer can approve after manual review.

Junjun Zhang and others added 3 commits April 13, 2026 22:42
Add full QQ Bot integration via the Official QQ Bot API (v2):
- WebSocket gateway for inbound events (C2C, group, guild, DM)
- REST API for outbound text/markdown/media messages
- Voice transcription (Tencent ASR + configurable STT provider)
- Attachment processing (images, voice, files)
- User authorization (allowlist + allow-all + DM pairing)

Integration points:
- gateway: Platform.QQ enum, adapter factory, allowlist maps
- CLI: setup wizard, gateway config, status display, tools config
- tools: send_message cross-platform routing, toolsets
- cron: delivery platform support
- docs: QQ Bot setup guide
…g, restore missing setup functions

- Rename platform from 'qq' to 'qqbot' across all integration points
  (Platform enum, toolset, config keys, import paths, file rename qq.py → qqbot.py)
- Add PLATFORM_HINTS for QQBot in prompt_builder (QQ supports markdown)
- Set SUPPORTS_MESSAGE_EDITING = False to skip streaming on QQ
  (prevents duplicate messages from non-editable partial + final sends)
- Add _send_qqbot() standalone send function for cron/send_message tool
- Add interactive _setup_qq() wizard in hermes_cli/setup.py
- Restore missing _setup_signal/email/sms/dingtalk/feishu/wecom/wecom_callback
  functions that were lost during the original merge
- Add Platform.QQBOT to _UPDATE_ALLOWED_PLATFORMS (enables /update command)
- Add 'qqbot' to webhook cross-platform delivery routing
- Add 'qqbot' to hermes dump platform detection
- Fix test_name_property casing: 'QQBot' not 'QQBOT'
- Add _parse_qq_timestamp() for ISO 8601 + integer ms compatibility
  (QQ API changed timestamp format — from PR #2411 finding)
- Wire timestamp parsing into all 4 message handlers
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Supply Chain Risk Detected

This PR contains patterns commonly associated with supply chain attacks. This does not mean the PR is malicious — but these patterns require careful human review before merging.

⚠️ WARNING: base64 encoding/decoding detected

Base64 has legitimate uses (images, JWT, etc.) but is also commonly used to obfuscate malicious payloads. Verify the usage is appropriate.

Matches (first 20):

1945:+        b64 = base64.b64encode(raw).decode("ascii")

⚠️ WARNING: exec() or eval() usage

Dynamic code execution can hide malicious behavior, especially when combined with base64 or network fetches.

Matches (first 20):

1435:+            proc = await asyncio.create_subprocess_exec(

⚠️ WARNING: Install hook files modified

These files can execute code during package installation or interpreter startup.

Files:

hermes_cli/setup.py

Automated scan triggered by supply-chain-audit. If this is a false positive, a maintainer can approve after manual review.

@teknium1 teknium1 changed the title feat(gateway): add QQBot platform adapter via qq-botpy SDK feat(gateway): add QQBot platform adapter (Official API v2) Apr 14, 2026
@WideLee

WideLee commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Would it make sense to rename the class names to match the platform key "qqbot" — e.g. QQAdapter → QQBotAdapter, check_qq_requirements → check_qqbot_requirements, QQCloseError → QQBotCloseError?

… shared strip_markdown

Improvements from our earlier #8269 salvage work applied to #7616:

- Platform token lock: acquire_scoped_lock/release_scoped_lock prevents
  two profiles from double-connecting the same QQ bot simultaneously
- Send retry with exponential backoff (3 attempts, 1s/2s/4s) with
  permanent vs transient error classification (matches Telegram pattern)
- Proper long-message splitting via truncate_message() instead of
  hard-truncating at MAX_MESSAGE_LENGTH (preserves code blocks, adds 1/N)
- REST-based one-shot send in send_message_tool — uses QQ Bot REST API
  directly with httpx instead of creating a full WebSocket adapter per
  message (fixes the connect→send race condition)
- Use shared strip_markdown() from helpers.py instead of 15 lines of
  inline regex with import-inside-method (DRY, same as BlueBubbles/SMS)
- format_message() now wired into send() pipeline
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Supply Chain Risk Detected

This PR contains patterns commonly associated with supply chain attacks. This does not mean the PR is malicious — but these patterns require careful human review before merging.

⚠️ WARNING: base64 encoding/decoding detected

Base64 has legitimate uses (images, JWT, etc.) but is also commonly used to obfuscate malicious payloads. Verify the usage is appropriate.

Matches (first 20):

1987:+        b64 = base64.b64encode(raw).decode("ascii")

⚠️ WARNING: exec() or eval() usage

Dynamic code execution can hide malicious behavior, especially when combined with base64 or network fetches.

Matches (first 20):

1444:+            proc = await asyncio.create_subprocess_exec(

⚠️ WARNING: Install hook files modified

These files can execute code during package installation or interpreter startup.

Files:

hermes_cli/setup.py

Automated scan triggered by supply-chain-audit. If this is a false positive, a maintainer can approve after manual review.

- sidebars.ts: sidebar navigation entry
- webhooks.md: deliver field routing table
- configuration.md: platform keys list
- sessions.md: platform identifiers table
- features/cron.md: delivery target table
- developer-guide/architecture.md: adapter listing
- developer-guide/cron-internals.md: delivery target table
- developer-guide/gateway-internals.md: file tree listing
- guides/cron-troubleshooting.md: supported platforms list
- integrations/index.md: platform links list
- reference/toolsets-reference.md: toolset table

(qqbot.md, environment-variables.md, and messaging/index.md were
already included in the contributor's original PR)
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Supply Chain Risk Detected

This PR contains patterns commonly associated with supply chain attacks. This does not mean the PR is malicious — but these patterns require careful human review before merging.

⚠️ WARNING: base64 encoding/decoding detected

Base64 has legitimate uses (images, JWT, etc.) but is also commonly used to obfuscate malicious payloads. Verify the usage is appropriate.

Matches (first 20):

1987:+        b64 = base64.b64encode(raw).decode("ascii")

⚠️ WARNING: exec() or eval() usage

Dynamic code execution can hide malicious behavior, especially when combined with base64 or network fetches.

Matches (first 20):

1444:+            proc = await asyncio.create_subprocess_exec(

⚠️ WARNING: Install hook files modified

These files can execute code during package installation or interpreter startup.

Files:

hermes_cli/setup.py

Automated scan triggered by supply-chain-audit. If this is a false positive, a maintainer can approve after manual review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants