Connect any Claude Code agent to DingTalk group chat in 60 seconds.
Quick Start • Features • Commands • Configuration • Architecture • FAQ
DingTalk Bridge is a Claude Code skill that bridges your AI coding agent with DingTalk (Alibaba's enterprise messaging platform). Once installed, your Claude Code agent can:
- Send rich Markdown or plain text messages to any DingTalk group
- Receive @mentions and auto-execute them via
claude -p - Run 24/7 as a Stream bot with crash recovery and keepalive
Think of it as giving your Claude Code agent a DingTalk phone number.
| Feature | Description |
|---|---|
| Send Messages | Markdown and plain text via DingTalk OpenAPI |
| Stream Bot | Persistent WebSocket listener for real-time @mention handling |
| Auto-Execute | Incoming messages run as Claude Code prompts, results posted back |
| Crash Recovery | Exponential backoff (5s to 60s) on disconnect, auto-restart via LaunchAgent |
| 20s Keepalive | Custom WebSocket ping prevents DingTalk's 30-min timeout |
| Zero Hardcoded Secrets | Config via env vars or config.json, never in source code |
| One-Command Install | bash install.sh handles deps, credentials, and optional LaunchAgent |
| 27 Regression Tests | Full test coverage with mocked API calls, no network required |
# Clone into your Claude Code skills directory
git clone https://github.com/mguozhen/dingtalk-bridge.git ~/.claude/skills/dingtalk-bridge
# Run the installer
bash ~/.claude/skills/dingtalk-bridge/scripts/install.shThe installer will:
- Install Python dependencies (
dingtalk_stream,websockets) - Prompt for your DingTalk App Key & Secret
- Generate
config.json(chmod 600) - Optionally create a macOS LaunchAgent for 24/7 operation
- Go to DingTalk Open Platform
- Create an Enterprise Internal App (企业内部应用)
- Enable Robot capability (机器人)
- Set message receive mode to Stream (Stream 模式)
- Copy the App Key and App Secret
- Add the bot to a group chat
python3 ~/.claude/skills/dingtalk-bridge/src/stream_bot.py@mention the bot in your group. It will auto-save the conversation ID and start responding.
Once the skill is installed, Claude Code auto-discovers it. Just say:
"Send a DingTalk message: today's build passed all tests"
Or use it programmatically:
python3 ~/.claude/skills/dingtalk-bridge/src/send.py "**Build Status**: All 142 tests passed"# Send markdown message (default)
python3 src/send.py "**Bold** message with _markdown_"
# Send with custom title
python3 src/send.py --title "Deploy Alert" "Production deploy complete"
# Send plain text
python3 src/send.py --text "Simple notification"
# Start the Stream bot
python3 src/stream_bot.pyfrom dingtalk_bridge.src.send import send_markdown, send_text
# Rich markdown
send_markdown("Daily Report", """
**Sent:** 50
**Opened:** 18 (36%)
**Clicked:** 7 (14%)
""")
# Plain text
send_text("Deployment complete.")Config priority: Environment Variables > config.json > Defaults
| Config Key | Env Var | Default | Description |
|---|---|---|---|
app_key |
DINGTALK_APP_KEY |
(required) | DingTalk App Key |
app_secret |
DINGTALK_APP_SECRET |
(required) | DingTalk App Secret |
conv_file |
DINGTALK_CONV_FILE |
data/conv.json |
Conversation metadata path |
workdir |
DINGTALK_WORKDIR |
cwd | Working directory for claude CLI |
claude_bin |
DINGTALK_CLAUDE_BIN |
claude |
Path to Claude binary |
max_reply |
DINGTALK_MAX_REPLY |
3000 |
Max reply length (chars) |
keepalive |
DINGTALK_KEEPALIVE |
20 |
WebSocket keepalive interval (sec) |
export DINGTALK_APP_KEY="your_key_here"
export DINGTALK_APP_SECRET="your_secret_here"
export DINGTALK_WORKDIR="$HOME/my-project"{
"app_key": "your_key_here",
"app_secret": "your_secret_here",
"workdir": "/home/user/my-project"
}dingtalk-bridge/
├── SKILL.md # Claude Code skill definition
├── README.md # This file
├── LICENSE # MIT License
├── config.example.json # Config template
├── marketplace.json # Skill registry metadata
├── data/
│ └── conv.json # Auto-saved conversation state
├── src/
│ ├── __init__.py
│ ├── config.py # Config loader (env > file > defaults)
│ ├── send.py # DingTalk OpenAPI messaging
│ └── stream_bot.py # Stream bot (listen + execute + reply)
├── scripts/
│ └── install.sh # One-command setup
└── tests/
└── test_dingtalk.py # 27 regression tests
You (@mention bot in DingTalk group)
|
v
DingTalk Stream API (WebSocket)
|
v
stream_bot.py: BridgeHandler.process()
|
+-- save_conv_info() --> data/conv.json
|
+-- threading.Thread(execute_prompt)
|
+-- reply("Processing...") via webhook
|
+-- subprocess: claude -p "<your message>" --continue
|
+-- send_markdown("Done", result) via OpenAPI
|
v
DingTalk Group (result displayed)
python3 tests/test_dingtalk.pytest_env_var_takes_priority ... ok
test_file_config_fallback ... ok
test_require_raises_on_missing ... ok
test_send_markdown_payload ... ok
test_reply_via_webhook ... ok
test_execute_prompt_success ... ok
test_execute_prompt_timeout ... ok
test_handler_process_spawns_thread ... ok
test_no_hardcoded_credentials ... ok
...
----------------------------------------------------------------------
Ran 27 tests in 0.15s
OK
All tests run offline with mocked API calls. No DingTalk credentials required.
How do I get the conversation ID?
Start the Stream bot, then @mention it in any DingTalk group. The conversation ID is automatically saved to data/conv.json. You only need to do this once per group.
Can I use this with multiple groups?
The current implementation saves one conversation at a time. For multiple groups, you can manually set the conv_file config to different paths per group, or extend send.py to accept a conversation ID parameter.
What happens if the bot crashes?
The bot has built-in exponential backoff (5s to 60s) and will auto-reconnect. If you set up the LaunchAgent via install.sh, macOS will also restart the process if it exits.
Does this work on Linux?
Yes. The Python code is cross-platform. The LaunchAgent setup is macOS-only, but you can use systemd on Linux instead. A systemd unit file example:
[Unit]
Description=DingTalk Bridge Bot
After=network.target
[Service]
ExecStart=/usr/bin/python3 /path/to/dingtalk-bridge/src/stream_bot.py
Restart=always
RestartSec=5
Environment=DINGTALK_APP_KEY=your_key
Environment=DINGTALK_APP_SECRET=your_secret
Environment=DINGTALK_WORKDIR=/path/to/project
[Install]
WantedBy=multi-user.targetIs this an official Anthropic product?
No. This is a community skill that follows the open Agent Skills specification. It works with Claude Code but is independently maintained.
PRs welcome. Please ensure all 27 tests pass before submitting:
python3 tests/test_dingtalk.pyBuilt for Claude Code • Powered by DingTalk Open Platform
