feat(dingtalk): QR-code device-flow authorization for setup wizard#11574
Conversation
- feat: support one-click QR scan to create DingTalk bot and establish connection - fix(gateway): wrap blocking DingTalkStreamClient.start() with asyncio.to_thread() - fix(gateway): extract message fields from CallbackMessage payload instead of ChatbotMessage - fix(gateway): add oapi.dingtalk.com to allowed webhook URL domains
Adds 15 regression tests for hermes_cli/dingtalk_auth.py covering:
* _api_post — network error mapping, errcode-nonzero mapping, success path
* begin_registration — 2-step chain, missing-nonce/device_code/uri
error cases
* wait_for_registration_success — success path, missing-creds guard,
on_waiting callback invocation
* render_qr_to_terminal — returns False when qrcode missing, prints
when available
* Configuration — BASE_URL default + override, SOURCE default
Also adds a one-line disclosure in dingtalk_qr_auth() telling users
the scan page will be OpenClaw-branded. Interim measure: DingTalk's
registration portal is hardcoded to route all sources to /openapp/
registration/openClaw, so users see OpenClaw branding regardless of
what 'source' value we send. We keep 'openClaw' as the source token
until DingTalk-Real-AI registers a Hermes-specific template.
Also adds meng93 to scripts/release.py AUTHOR_MAP.
|
All three messaging platforms that render QR codes during setup (Weixin, DingTalk, Feishu) need the `qrcode` package. It wasn't declared anywhere, so users installing via `pip install hermes-agent[messaging]` had to manually `pip install qrcode` or hit a rendering error mid-wizard. Adds `qrcode>=7.0,<9` to: * `messaging` extra — used by Weixin (weixin.py:955) * `dingtalk` extra — used by the QR auth flow landed in #11574 * `feishu` extra — used by feishu.py:3962 The `all` extra inherits from all three, so it picks up qrcode transitively — no separate entry needed. Also updates website/docs/user-guide/messaging/weixin.md to stop telling users to `pip install qrcode` separately and instead point at `pip install 'hermes-agent[messaging]'`. The troubleshooting row for QR render failure keeps `pip install qrcode` as a minimal- install fallback. Closes #9431 — reported by zhangzhiqiangcs.
…aging) #4b1567f4 (anthhub) added qrcode to the messaging extra for Weixin's QR login. The same package is needed by: * hermes_cli/dingtalk_auth.py — QR device-flow auth shipped in #11574 * gateway/platforms/feishu.py:3962 — Feishu QR login These extras are independent of [messaging] (users can install hermes-agent[dingtalk] or hermes-agent[feishu] without [messaging]), so the dep needs to be declared on each. Pin matches anthhub's choice (>=7.0,<8) for consistency. The all extra inherits from all three, so it picks up qrcode transitively. Adds parallel tests to tests/test_project_metadata.py — same shape as test_messaging_extra_includes_qrcode_for_weixin_setup. Refs #9431.
…aging) (#11627) #4b1567f4 (anthhub) added qrcode to the messaging extra for Weixin's QR login. The same package is needed by: * hermes_cli/dingtalk_auth.py — QR device-flow auth shipped in #11574 * gateway/platforms/feishu.py:3962 — Feishu QR login These extras are independent of [messaging] (users can install hermes-agent[dingtalk] or hermes-agent[feishu] without [messaging]), so the dep needs to be declared on each. Pin matches anthhub's choice (>=7.0,<8) for consistency. The all extra inherits from all three, so it picks up qrcode transitively. Adds parallel tests to tests/test_project_metadata.py — same shape as test_messaging_extra_includes_qrcode_for_weixin_setup. Refs #9431.
Fills documentation gaps that accumulated as features merged ahead of their docs updates. All additions are verified against code and the originating PRs. Providers: - Ollama Cloud (#10782) — new provider section, env vars, quickstart/fallback rows - xAI Grok Responses API + TTS (#10783) — provider note, TTS table + config - Google Gemini CLI OAuth (#11270) — quickstart/fallback/cli-commands entries - NVIDIA NIM (#11774) — NVIDIA_API_KEY / NVIDIA_BASE_URL in env-vars reference - HERMES_INFERENCE_PROVIDER enum updated Messaging: - DISCORD_ALLOWED_ROLES (#11608) — env-vars, discord.md access control section - DingTalk QR device-flow (#11574) — wizard path in Option A + openClaw disclosure - Feishu document comment intelligent reply (#11898) — full section + 3-tier access control + CLI Skills / commands: - concept-diagrams skill (#11363) — optional-skills-catalog entry - /gquota (#11270) — slash-commands reference Build: docusaurus build passes, ascii-guard lint 0 errors.
Fills documentation gaps that accumulated as features merged ahead of their docs updates. All additions are verified against code and the originating PRs. Providers: - Ollama Cloud (#10782) — new provider section, env vars, quickstart/fallback rows - xAI Grok Responses API + TTS (#10783) — provider note, TTS table + config - Google Gemini CLI OAuth (#11270) — quickstart/fallback/cli-commands entries - NVIDIA NIM (#11774) — NVIDIA_API_KEY / NVIDIA_BASE_URL in env-vars reference - HERMES_INFERENCE_PROVIDER enum updated Messaging: - DISCORD_ALLOWED_ROLES (#11608) — env-vars, discord.md access control section - DingTalk QR device-flow (#11574) — wizard path in Option A + openClaw disclosure - Feishu document comment intelligent reply (#11898) — full section + 3-tier access control + CLI Skills / commands: - concept-diagrams skill (#11363) — optional-skills-catalog entry - /gquota (#11270) — slash-commands reference Build: docusaurus build passes, ascii-guard lint 0 errors.
|
@teknium1 Hi! The follow-up items you outlined in this PR have now been fully implemented. 1. Registration source switch → PR #12907 Now that the Hermes source token has been officially sanctioned by DingTalk-Real-AI, this PR flips the 2. New platform capabilities → PR #12769 Adds several missing capabilities to the DingTalk adapter:
Both PRs are tested and ready to go. Would love to get these merged soon so DingTalk users can benefit from the sanctioned Hermes identity and the full feature set as quickly as possible. 🚀 Again, really appreciate your original design on this PR — the clear follow-up checklist and the |
…aging) (NousResearch#11627) #30ab7d40 (anthhub) added qrcode to the messaging extra for Weixin's QR login. The same package is needed by: * hermes_cli/dingtalk_auth.py — QR device-flow auth shipped in NousResearch#11574 * gateway/platforms/feishu.py:3962 — Feishu QR login These extras are independent of [messaging] (users can install hermes-agent[dingtalk] or hermes-agent[feishu] without [messaging]), so the dep needs to be declared on each. Pin matches anthhub's choice (>=7.0,<8) for consistency. The all extra inherits from all three, so it picks up qrcode transitively. Adds parallel tests to tests/test_project_metadata.py — same shape as test_messaging_extra_includes_qrcode_for_weixin_setup. Refs NousResearch#9431.
) Fills documentation gaps that accumulated as features merged ahead of their docs updates. All additions are verified against code and the originating PRs. Providers: - Ollama Cloud (NousResearch#10782) — new provider section, env vars, quickstart/fallback rows - xAI Grok Responses API + TTS (NousResearch#10783) — provider note, TTS table + config - Google Gemini CLI OAuth (NousResearch#11270) — quickstart/fallback/cli-commands entries - NVIDIA NIM (NousResearch#11774) — NVIDIA_API_KEY / NVIDIA_BASE_URL in env-vars reference - HERMES_INFERENCE_PROVIDER enum updated Messaging: - DISCORD_ALLOWED_ROLES (NousResearch#11608) — env-vars, discord.md access control section - DingTalk QR device-flow (NousResearch#11574) — wizard path in Option A + openClaw disclosure - Feishu document comment intelligent reply (NousResearch#11898) — full section + 3-tier access control + CLI Skills / commands: - concept-diagrams skill (NousResearch#11363) — optional-skills-catalog entry - /gquota (NousResearch#11270) — slash-commands reference Build: docusaurus build passes, ascii-guard lint 0 errors.
…aging) (NousResearch#11627) #2e399644 (anthhub) added qrcode to the messaging extra for Weixin's QR login. The same package is needed by: * hermes_cli/dingtalk_auth.py — QR device-flow auth shipped in NousResearch#11574 * gateway/platforms/feishu.py:3962 — Feishu QR login These extras are independent of [messaging] (users can install hermes-agent[dingtalk] or hermes-agent[feishu] without [messaging]), so the dep needs to be declared on each. Pin matches anthhub's choice (>=7.0,<8) for consistency. The all extra inherits from all three, so it picks up qrcode transitively. Adds parallel tests to tests/test_project_metadata.py — same shape as test_messaging_extra_includes_qrcode_for_weixin_setup. Refs NousResearch#9431.
) Fills documentation gaps that accumulated as features merged ahead of their docs updates. All additions are verified against code and the originating PRs. Providers: - Ollama Cloud (NousResearch#10782) — new provider section, env vars, quickstart/fallback rows - xAI Grok Responses API + TTS (NousResearch#10783) — provider note, TTS table + config - Google Gemini CLI OAuth (NousResearch#11270) — quickstart/fallback/cli-commands entries - NVIDIA NIM (NousResearch#11774) — NVIDIA_API_KEY / NVIDIA_BASE_URL in env-vars reference - HERMES_INFERENCE_PROVIDER enum updated Messaging: - DISCORD_ALLOWED_ROLES (NousResearch#11608) — env-vars, discord.md access control section - DingTalk QR device-flow (NousResearch#11574) — wizard path in Option A + openClaw disclosure - Feishu document comment intelligent reply (NousResearch#11898) — full section + 3-tier access control + CLI Skills / commands: - concept-diagrams skill (NousResearch#11363) — optional-skills-catalog entry - /gquota (NousResearch#11270) — slash-commands reference Build: docusaurus build passes, ascii-guard lint 0 errors.
…aging) (NousResearch#11627) #4b1567f4 (anthhub) added qrcode to the messaging extra for Weixin's QR login. The same package is needed by: * hermes_cli/dingtalk_auth.py — QR device-flow auth shipped in NousResearch#11574 * gateway/platforms/feishu.py:3962 — Feishu QR login These extras are independent of [messaging] (users can install hermes-agent[dingtalk] or hermes-agent[feishu] without [messaging]), so the dep needs to be declared on each. Pin matches anthhub's choice (>=7.0,<8) for consistency. The all extra inherits from all three, so it picks up qrcode transitively. Adds parallel tests to tests/test_project_metadata.py — same shape as test_messaging_extra_includes_qrcode_for_weixin_setup. Refs NousResearch#9431.
) Fills documentation gaps that accumulated as features merged ahead of their docs updates. All additions are verified against code and the originating PRs. Providers: - Ollama Cloud (NousResearch#10782) — new provider section, env vars, quickstart/fallback rows - xAI Grok Responses API + TTS (NousResearch#10783) — provider note, TTS table + config - Google Gemini CLI OAuth (NousResearch#11270) — quickstart/fallback/cli-commands entries - NVIDIA NIM (NousResearch#11774) — NVIDIA_API_KEY / NVIDIA_BASE_URL in env-vars reference - HERMES_INFERENCE_PROVIDER enum updated Messaging: - DISCORD_ALLOWED_ROLES (NousResearch#11608) — env-vars, discord.md access control section - DingTalk QR device-flow (NousResearch#11574) — wizard path in Option A + openClaw disclosure - Feishu document comment intelligent reply (NousResearch#11898) — full section + 3-tier access control + CLI Skills / commands: - concept-diagrams skill (NousResearch#11363) — optional-skills-catalog entry - /gquota (NousResearch#11270) — slash-commands reference Build: docusaurus build passes, ascii-guard lint 0 errors.
…aging) (NousResearch#11627) #4b1567f4 (anthhub) added qrcode to the messaging extra for Weixin's QR login. The same package is needed by: * hermes_cli/dingtalk_auth.py — QR device-flow auth shipped in NousResearch#11574 * gateway/platforms/feishu.py:3962 — Feishu QR login These extras are independent of [messaging] (users can install hermes-agent[dingtalk] or hermes-agent[feishu] without [messaging]), so the dep needs to be declared on each. Pin matches anthhub's choice (>=7.0,<8) for consistency. The all extra inherits from all three, so it picks up qrcode transitively. Adds parallel tests to tests/test_project_metadata.py — same shape as test_messaging_extra_includes_qrcode_for_weixin_setup. Refs NousResearch#9431.
) Fills documentation gaps that accumulated as features merged ahead of their docs updates. All additions are verified against code and the originating PRs. Providers: - Ollama Cloud (NousResearch#10782) — new provider section, env vars, quickstart/fallback rows - xAI Grok Responses API + TTS (NousResearch#10783) — provider note, TTS table + config - Google Gemini CLI OAuth (NousResearch#11270) — quickstart/fallback/cli-commands entries - NVIDIA NIM (NousResearch#11774) — NVIDIA_API_KEY / NVIDIA_BASE_URL in env-vars reference - HERMES_INFERENCE_PROVIDER enum updated Messaging: - DISCORD_ALLOWED_ROLES (NousResearch#11608) — env-vars, discord.md access control section - DingTalk QR device-flow (NousResearch#11574) — wizard path in Option A + openClaw disclosure - Feishu document comment intelligent reply (NousResearch#11898) — full section + 3-tier access control + CLI Skills / commands: - concept-diagrams skill (NousResearch#11363) — optional-skills-catalog entry - /gquota (NousResearch#11270) — slash-commands reference Build: docusaurus build passes, ascii-guard lint 0 errors.
…aging) (NousResearch#11627) #367e9557 (anthhub) added qrcode to the messaging extra for Weixin's QR login. The same package is needed by: * hermes_cli/dingtalk_auth.py — QR device-flow auth shipped in NousResearch#11574 * gateway/platforms/feishu.py:3962 — Feishu QR login These extras are independent of [messaging] (users can install hermes-agent[dingtalk] or hermes-agent[feishu] without [messaging]), so the dep needs to be declared on each. Pin matches anthhub's choice (>=7.0,<8) for consistency. The all extra inherits from all three, so it picks up qrcode transitively. Adds parallel tests to tests/test_project_metadata.py — same shape as test_messaging_extra_includes_qrcode_for_weixin_setup. Refs NousResearch#9431.
) Fills documentation gaps that accumulated as features merged ahead of their docs updates. All additions are verified against code and the originating PRs. Providers: - Ollama Cloud (NousResearch#10782) — new provider section, env vars, quickstart/fallback rows - xAI Grok Responses API + TTS (NousResearch#10783) — provider note, TTS table + config - Google Gemini CLI OAuth (NousResearch#11270) — quickstart/fallback/cli-commands entries - NVIDIA NIM (NousResearch#11774) — NVIDIA_API_KEY / NVIDIA_BASE_URL in env-vars reference - HERMES_INFERENCE_PROVIDER enum updated Messaging: - DISCORD_ALLOWED_ROLES (NousResearch#11608) — env-vars, discord.md access control section - DingTalk QR device-flow (NousResearch#11574) — wizard path in Option A + openClaw disclosure - Feishu document comment intelligent reply (NousResearch#11898) — full section + 3-tier access control + CLI Skills / commands: - concept-diagrams skill (NousResearch#11363) — optional-skills-catalog entry - /gquota (NousResearch#11270) — slash-commands reference Build: docusaurus build passes, ascii-guard lint 0 errors.
Summary
Salvages #8345 (meng93 — authorship preserved) + 15 new regression tests + an OpenClaw branding disclosure.
Adds QR-code device-flow authorization to
hermes gateway setupfor DingTalk, eliminating the manual developer-console workflow. Users scan a QR with the DingTalk mobile app and Client ID / Client Secret are returned automatically.Why this path
Per design discussion with @teknium1:
source="hermes"live (option B): DingTalk's/app/registration/beginaccepts any source at the API layer but the returnedverification_uri_completeis hardcoded tohttps://open-dev.dingtalk.com/openapp/registration/openClaw?user_code=.... Confirmed against the real endpoint — we cannot use our own source string until DingTalk-Real-AI registers a Hermes template server-side. Issue Feature: Switchable Agent Modes — Named Profiles with Tool Restrictions, Personas & Per-Project Config (inspired by Roo Code) #482 on their repo (filed today asking about Hermes support) has no official response yet.sourceso we can eventually swap the token. The disclosure below makes the interim UX honest with users.What's in
meng93's commit (0bbb6f0) — cherry-picked with authorship preserved:
hermes_cli/dingtalk_auth.py(new, 292 lines) — three-step device flow (init → begin → poll) + compact half-block QR renderer + auto-install ofqrcodepip dep.hermes_cli/gateway.py— rewrites_setup_dingtalk()to offer QR scan (default) or manual credential entry, plus dispatch wiring ingateway_setup().gateway/config.py— env-var →PlatformConfigbridge forDINGTALK_CLIENT_ID,DINGTALK_CLIENT_SECRET, and optionalDINGTALK_HOME_CHANNEL(matches the pattern used by other platforms).Intentionally dropped from meng93's PR:
gateway/platforms/dingtalk.pySDK-compat fixes — already on main via fix(dingtalk): support dingtalk-stream 0.24+ SDK (async process, CallbackMessage, oapi webhooks, TextContent) #11471. Resolved the cherry-pick conflict by keeping current main's version.My follow-up (b7ba865):
tests/hermes_cli/test_dingtalk_auth.pycovering_api_posterror paths,begin_registrationchaining + missing-field errors, polling loop success/failure/callback, QR renderer fallback, and env-var config overrides.dingtalk_qr_auth():meng93toscripts/release.pyAUTHOR_MAP.Tests
tests/hermes_cli/test_dingtalk_auth.py— 15 passed (new)tests/hermes_cli/test_dingtalk_auth.py + test_dingtalk.py + test_config.py— 85 passed combinedoapi.dingtalk.com— loaded module from worktree, calledbegin_registration()live, got a realdevice_code+verification_uri_completeback. Didn't complete the QR scan (requires a human + DingTalk mobile app) but the full protocol up to QR display works.Authorship
Commit
0bbb6f0apreservesmeng93 <yiweimeng.dlut@hotmail.com>as author. Merge with--rebaseto keep attribution.PRs #9610 and #10004 ship word-for-word identical
dingtalk_auth.pycode — they're copies of meng93's earlier submission (meng93: Apr 12, audanye-sudo: Apr 14, PeterGuy326: Apr 15). On merge they'll be closed with credit to all three, with primary credit to meng93 as the original author.Follow-ups (post-merge)
hermesas a sanctionedsourcetoken.REGISTRATION_SOURCEdefault fromopenClaw→hermesand remove the disclosure. TheDINGTALK_REGISTRATION_SOURCEenv var already exists as an escape hatch.Closes
Closes #8345, #9610, #10004 on merge.