Skip to content

mguozhen/dingtalk-bridge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DingTalk Bridge

DingTalk Bridge

Connect any Claude Code agent to DingTalk group chat in 60 seconds.

60s Setup Agent Skills MIT License Claude Code Skill Python 3.9+ 27 Tests Passed

Quick StartFeaturesCommandsConfigurationArchitectureFAQ


What is this?

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.

Features

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

Quick Start

1. Install the skill

# 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.sh

The 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

2. Prerequisites: Create a DingTalk App

  1. Go to DingTalk Open Platform
  2. Create an Enterprise Internal App (企业内部应用)
  3. Enable Robot capability (机器人)
  4. Set message receive mode to Stream (Stream 模式)
  5. Copy the App Key and App Secret
  6. Add the bot to a group chat

3. Start the bot

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.

4. Send messages from Claude Code

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"

Commands

CLI

# 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.py

Python Module

from 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.")

Configuration

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)

Example: Environment Variables

export DINGTALK_APP_KEY="your_key_here"
export DINGTALK_APP_SECRET="your_secret_here"
export DINGTALK_WORKDIR="$HOME/my-project"

Example: config.json

{
  "app_key": "your_key_here",
  "app_secret": "your_secret_here",
  "workdir": "/home/user/my-project"
}

Architecture

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

Message Flow

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)

Running Tests

python3 tests/test_dingtalk.py
test_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.

FAQ

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.target
Is 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.

Contributing

PRs welcome. Please ensure all 27 tests pass before submitting:

python3 tests/test_dingtalk.py

License

MIT


Built for Claude Code • Powered by DingTalk Open Platform

About

DingTalk group chat bridge for Claude Code. Send messages, receive @mentions, auto-execute prompts via Stream SDK.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors