DingTalk channel adapter for bub.
- Channel implementation:
DingTalkChannel(name = "dingtalk") - Inbound message adaptation from DingTalk Stream Mode to Bub
ChannelMessage - Outbound sending through the packaged DingTalk script helper
- Supports private (1:1) and group chats with group mapping via
group:<openConversationId>
uv pip install "git+https://github.com/bubbuild/bub-contrib.git#subdirectory=packages/bub-dingtalk"You can also install it with Bub:
bub install bub-dingtalk@mainDingTalkChannel reads settings from environment variables with the BUB_DINGTALK_ prefix.
BUB_DINGTALK_CLIENT_ID(required): AppKey from DingTalk Open PlatformBUB_DINGTALK_CLIENT_SECRET(required): AppSecretBUB_DINGTALK_ALLOW_USERS(optional): Comma-separated allowlist of sender staff IDs, or*for all
- Session ID format:
dingtalk:<chat_id> - Inbound messages:
- ignores senders outside
BUB_DINGTALK_ALLOW_USERS - ignores empty or unsupported inbound message bodies
- maps group conversations to
group:<openConversationId>
- ignores senders outside
- Message activation (
is_active = true) is always enabled for allowed inbound messages - Command detection:
- if content starts with
,, message kind becomescommand
- if content starts with
Inbound messages keep the original DingTalk text as plain string content.
session_id:dingtalk:<chat_id>channel:dingtalkchat_id: sender staff ID for 1:1, orgroup:<openConversationId>for groupskind:commandwhen content starts with,, otherwisenormalis_active: alwaystruefor allowed inbound messages
- Uses
chat_iddirectly when present, otherwise falls back to thesession_idsuffix. - Delegates outbound delivery to
skills.dingtalk.scripts.dingtalk_send.send_message(). - Uses standard TLS verification; there is no global SSL monkey patching or per-request verification bypass.
The packaged skill resources live under src/skills/dingtalk.
To simulate the inbound path (DingTalk -> agent loop):
# From workspace root
uv run --isolated --no-project --with-editable ./packages/bub-dingtalk python packages/bub-dingtalk/tests/test_inbound_flow.pyOr run the pytest:
uv run --isolated --no-project --with-editable ./packages/bub-dingtalk --with pytest python -m pytest packages/bub-dingtalk/tests/test_inbound_flow.py -v