feat(qqbot): QR scan-to-configure setup + package split (salvage of #11582)#11831
Merged
Conversation
…re onboard flow - Refactor gateway/platforms/qqbot.py into gateway/platforms/qqbot/ package: - adapter.py: core QQAdapter (unchanged logic, constants from shared module) - constants.py: shared constants (API URLs, timeouts, message types) - crypto.py: AES-256-GCM key generation and secret decryption - onboard.py: QR-code scan-to-configure API (create_bind_task, poll_bind_result) - utils.py: User-Agent builder, HTTP headers, config helpers - __init__.py: re-exports all public symbols for backward compatibility - Add interactive QR-code setup flow in hermes_cli/gateway.py: - Terminal QR rendering via qrcode package (graceful fallback to URL) - Auto-refresh on QR expiry (up to 3 times) - AES-256-GCM encrypted credential exchange - DM security policy selection (pairing/allowlist/open) - Update hermes_cli/setup.py to delegate to gateway's _setup_qqbot() - Add qrcode>=7.4 dependency to pyproject.toml and requirements.txt
…ti-instance disambiguation
…just STT log levels - Remove @staticmethod from _detect_message_type, _convert_silk_to_wav, _convert_raw_to_wav, _convert_ffmpeg_to_wav so they can use self._log_tag - Replace all remaining hardcoded "QQBot" log args with self._log_tag - Downgrade STT routine flow logs (download, convert, success) from info to debug - Keep warning level for actual failures (STT failed, ffmpeg error, empty transcript)
- Re-export _ssrf_redirect_guard from __init__.py - Fix _parse_json @staticmethod using self._log_tag - Update test_detect_message_type to call as instance method - Fix mock.patch path for httpx.AsyncClient in adapter submodule
Follow-up to WideLee's salvaged PR #11582. Back-compat for QQ_HOME_CHANNEL → QQBOT_HOME_CHANNEL rename: - gateway/config.py reads QQBOT_HOME_CHANNEL, falls back to QQ_HOME_CHANNEL with a one-shot deprecation warning so users on the old name aren't silently broken. - cron/scheduler.py: _HOME_TARGET_ENV_VARS['qqbot'] now maps to the new name; _get_home_target_chat_id falls back to the legacy name via a _LEGACY_HOME_TARGET_ENV_VARS table. - hermes_cli/status.py + hermes_cli/setup.py: honor both names when displaying or checking for missing home channels. - hermes_cli/config.py: keep legacy QQ_HOME_CHANNEL[_NAME] in _EXTRA_ENV_KEYS so .env sanitization still recognizes them. Scope cleanup: - Drop qrcode from core dependencies and requirements.txt (remains in messaging/dingtalk/feishu extras). _qqbot_render_qr already degrades gracefully when qrcode is missing, printing a 'pip install qrcode' tip and falling back to URL-only display. - Restore @staticmethod on QQAdapter._detect_message_type (it doesn't use self). Revert the test change that was only needed when it was converted to an instance method. - Reset uv.lock to origin/main; the PR's stale lock also included unrelated changes (atroposlib source URL, hermes-agent version bump, fastapi additions) that don't belong. Verified E2E: - Existing user (QQ_HOME_CHANNEL set): gateway + cron both pick up the legacy name; deprecation warning logs once. - Fresh user (QQBOT_HOME_CHANNEL set): gateway + cron use new name, no warning. - Both set: new name wins on both surfaces. Targeted tests: 296 passed, 4 skipped (qqbot + cron + hermes_cli).
Contributor
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
QR-code scan-to-configure flow for QQBot setup, plus a clean package split of the 1960-line
gateway/platforms/qqbot.pyinto submodules. Salvaged from @WideLee's #11582 onto currentmain, with back-compat added for theQQ_HOME_CHANNEL→QQBOT_HOME_CHANNELrename so existing users don't silently lose their home channel.Closes #11582.
Changes
Feature (WideLee's commits, cherry-picked with authorship preserved)
gateway/platforms/qqbot.py→gateway/platforms/qqbot/package:adapter.py,constants.py,utils.py,crypto.py,onboard.py,__init__.py(old import paths preserved via re-exports)_setup_qqbot, terminal renders a QR viaqrcode.print_ascii, backend pollsq.qq.comfor scan completion, server-returnedclient_secretis AES-256-GCM decrypted locally with a key the CLI generatedQQ_HOME_CHANNEL[_NAME]→QQBOT_HOME_CHANNEL[_NAME]for consistency with theqqbotplatform keyself._log_tag(formatQQBot:<app_id>) replaces hardcoded"QQBot"in all 79 logger calls for multi-instance disambiguationFollow-up fixes (our commit on top)
gateway/config.pyreads the new name, falls back to the legacy one with a one-shot deprecation warning.cron/scheduler.pygains a_LEGACY_HOME_TARGET_ENV_VARStable so cron deliveries don't silently drop for existing users.hermes_cli/status.pyandhermes_cli/setup.pyhonor both names._EXTRA_ENV_KEYSkeeps the legacy entries so .env sanitizer recognizes them.[project.dependencies]andrequirements.txt. It remains in themessaging/dingtalk/feishuextras where it already lived._qqbot_render_qralready handled the missing-dep case gracefully with a "pip install qrcode" tip._detect_message_typeas@staticmethod— it doesn't useself; the PR converted it to instance method purely to force a test change. Reverted both.uv.lockto currentorigin/main— the PR's stale lock also included unrelated atroposlib source-URL and version bumps.Validation
QQ_HOME_CHANNELsethome_channel=Nonedeliver=originfallbackQQBOT_HOME_CHANNELsetE2E scenarios exercised live against real
gateway.config._apply_env_overridesandcron.scheduler._resolve_delivery_target:create_bind_task→ poll-pending → poll-completed → decrypt loop verified against mockedq.qq.com; crypto roundtrip correct, wrong key / tampered tag rejected; QR code decodes back to exact URLCredits
Substantive work by @WideLee (commits
39ff62a5through552fc844, authorship preserved). Closes the original #11582.