task-notify
by wuliang142857v1.0.0
DingTalk notifications for Claude Code with remote interaction support. Get notified when Claude needs attention and reply remotely.
MIT GitHub
Keywords
notificationdingtalkremotehooksinteraction
Documentation
# Claude Task Notify
[简体中文](README.zh_CN.md) | English
A Claude Code plugin for DingTalk notifications with remote interaction support. Get notified when Claude Code needs your attention and reply remotely via web interface.
## Features
- **DingTalk Notifications**: Get notified when Claude Code asks questions or completes tasks
- **Remote Interaction**: Reply to Claude Code questions from your phone via web interface
- **Secure**: Uses DingTalk's signature verification
- **Auto-injection**: Automatically injects your replies into Claude Code via tmux
- **Plugin Architecture**: Easy installation as a Claude Code plugin
## Architecture
```
+------------------+ +-------------------+ +------------------+
| Claude Code |---->| Hook Scripts |---->| DingTalk |
| (in tmux) | | | | Robot |
+------------------+ +-------------------+ +------------------+
^ |
| v
| +-------------------+ +------------------+
| | Poll Script |<----| Worker API |
| | (background) | | (optional) |
| +-------------------+ +------------------+
| | ^
+------------------------+ |
(tmux inject) +------------------+
| Web Browser |
| (user reply) |
+------------------+
```
## Prerequisites
- Claude Code CLI
- tmux
- jq
- curl
- DingTalk Robot with signature verification enabled
## Installation
### Option 1: Plugin Mode (Recommended)
```bash
git clone https://github.com/wuliang142857/claude-task-notify.git
cd claude-task-notify
./install.sh
# Select option 1 for plugin mode
```
This installs the plugin to `~/.claude/plugins/local/notify/`.
### Option 2: Legacy Mode
```bash
./install.sh
# Select option 2 for legacy mode
```
This copies scripts to `~/.claude/scripts/`.
## Configuration
### 1. Configure DingTalk Credentials
Add to `~/.claude/settings.json`:
```json
{
"env": {
"DINGTALK_WEBHOOK_URL": "https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN",
"DINGTALK_SECRET": "SECxxxxxxxx"
}
}
```
Or use the interactive setup command:
```
/notify:setup
```
### 2. Configure Hooks
For plugin mode, add to `~/.claude/settings.json`:
```json
{
"hooks": {
"UserPromptSubmit": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "~/.claude/plugins/local/notify/scripts/kill-poll-processes.sh",
"timeout": 5
}
]
}
],
"PreToolUse": [
{
"matcher": "AskUserQuestion",
"hooks": [
{
"type": "command",
"command": "~/.claude/plugins/local/notify/scripts/handle-ask-user.sh",
"timeout": 30
}
]
}
],
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "~/.claude/plugins/local/notify/scripts/handle-stop.sh"
}
]
}
]
}
}
```
### 3. Test Configuration
```
/notify:test
```
## Plugin Commands
| Command | Description |
|---------|-------------|
| `/notify:status` | Check notification service status |
| `/notify:test` | Send a test notification to DingTalk |
| `/notify:setup` | Interactive setup guide |
## Optional: Remote Interaction
For full remote interaction support (reply via web interface), deploy the Worker API.
### Deploy Worker
See [worker/README.md](worker/README.md) for deployment instructions.
### Configure Worker URL
Add to `~/.claude/settings.json`:
```json
{
"env": {
"CLAUDE_WORKER_URL": "https://your-worker-url.workers.dev"
}
}
```
Default: `https://claude-interactive-message.wuliang142857.me`
## How It Works
### AskUserQuestion Hook
When Claude Code uses the `AskUserQuestion` tool:
1. `handle-ask-user.sh` is triggered
2. Sends notification to DingTalk with question details
3. If Worker is configured, creates a session for remote reply
4. Starts background polling process
5. When user replies via web, poll script injects the answer into tmux
### Stop Hook
When Claude Code stops (task complete or needs input):
1. `handle-stop.sh` is triggered
2. Extracts Claude's last output from transcript
3. Sends notification to DingTalk
4. If Worker is configured, allows user to send next instruction remotely
### UserPromptSubmit Hook
When user types directly in Claude Code:
1. `kill-poll-processes.sh` is triggered
2. Kills any running poll processes (no longer needed)
## Scripts
| Script | Purpose |
|--------|---------|
| `notify-dingtalk.sh` | Core notification script with DingTalk signature |
| `handle-ask-user.sh` | AskUserQuestion hook handler |
| `handle-stop.sh` | Stop hook handler |
| `poll-reply.sh` | Background polling for remote replies |
| `kill-poll-processes.sh` | Clean up poll processes |
## Environment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| `DINGTALK_WEBHOOK_URL` | Yes | DingTalk robot webhook URL |
| `DINGTALK_SECRET` | Yes | DingTalk robot signature secret |
| `CLAUDE_WORKER_URL` | No | Worker API URL for remote interaction |
## Troubleshooting
### Notifications not received
1. Check DingTalk credentials in settings.json
2. Verify the robot has correct IP whitelist or use signature mode
3. Run `/notify:test` to verify configuration
### Remote reply not working
1. Verify Worker URL is accessible
2. Check if running in tmux session
3. Check poll logs: `cat /tmp/claude-poll-*.log`
### Poll process not stopping
Check status: `/notify:status`
Or manually kill: `pkill -f poll-reply.sh`
## Directory Structure
```
claude-task-notify/
├── .claude-plugin/
│ ├── plugin.json # Plugin metadata
│ └── marketplace.json # Marketplace description
├── plugins/
│ └── notify/
│ ├── .claude-plugin/
│ │ └── plugin.json # Notify plugin metadata
│ ├── commands/
│ │ ├── status.md # /notify:status command
│ │ ├── test.md # /notify:test command
│ │ └── setup.md # /notify:setup command
│ └── scripts/
│ ├── notify-dingtalk.sh
│ ├── handle-ask-user.sh
│ ├── handle-stop.sh
│ ├── poll-reply.sh
│ └── kill-poll-processes.sh
├── worker/ # Cloudflare Worker for remote interaction
├── install.sh
├── README.md
└── README.zh_CN.md
```
## License
MIT License
## Contributing
Pull requests are welcome. For major changes, please open an issue first.