feat: 支持 PreToolUse 事件,AskUserQuestion 触发通知

- handler.go 添加 PreToolUse 事件处理,提取 AskUserQuestion 的 question 字段作为通知内容
- README.md 更新 hooks 配置示例、支持事件文档和测试命令
This commit is contained in:
2026-06-21 22:46:20 +08:00
parent ad585bf101
commit 2ac582ecfd
2 changed files with 45 additions and 2 deletions
+25 -2
View File
@@ -5,7 +5,7 @@
## 功能特性
- **实时通知**:当 Claude Code 需要关注时,立即收到手机推送
- **多事件支持**:Notification(权限请求、等待输入等)和 Stop(任务完成)
- **多事件支持**:Notification(权限请求、等待输入等)、Stop(任务完成)、PreToolUse(提问通知)
- **轻量部署**:单个 Docker 容器,资源占用极低
- **灵活配置**:通过环境变量自定义 Gotify 服务器和 Token
@@ -73,6 +73,17 @@ docker-compose up -d
"type": "command",
"command": "curl -s -X POST http://47.121.181.112:8082/hooks -H 'Content-Type: application/json' -d @-"
}
],
"PreToolUse": [
{
"matcher": "AskUserQuestion",
"hooks": [
{
"type": "command",
"command": "curl -s -X POST http://47.121.181.112:8082/hooks -H 'Content-Type: application/json' -d @-"
}
]
}
]
}
}
@@ -96,6 +107,13 @@ docker-compose up -d
| 正常完成 | 任务完成 | 5 | Claude 完成了本轮回复 |
| 循环检测 | 循环停止 | 8 | Stop hook 连续触发多次,已自动停止 |
### PreToolUse 事件
| 工具名称 | 标题 | 优先级 | 说明 |
|----------|------|--------|------|
| `AskUserQuestion` | 等待回答 | 6 | Claude 向你提问,等待回答 |
| 其他工具 | 工具调用 | 4 | Claude 正在使用工具 |
## 配置说明
| 环境变量 | 必填 | 说明 |
@@ -164,6 +182,11 @@ curl -X POST http://47.121.181.112:8082/hooks \
curl -X POST http://47.121.181.112:8082/hooks \
-H 'Content-Type: application/json' \
-d '{"session_id":"test","cwd":"/tmp","hook_event_name":"Stop"}'
# 模拟 AskUserQuestion 事件
curl -X POST http://47.121.181.112:8082/hooks \
-H 'Content-Type: application/json' \
-d '{"session_id":"test","cwd":"/tmp","hook_event_name":"PreToolUse","tool_name":"AskUserQuestion","tool_input":{"question":"你想使用哪种数据库?"}}'
```
## 项目结构
@@ -184,7 +207,7 @@ cc-hook/
## 扩展计划
- [ ] 数据库记录:将 Hook 事件写入数据库,便于复盘和分析
- [ ] 更多事件支持:Tool Use、Error 等事件类型
- [x] 更多事件支持:PreToolUse(AskUserQuestion 提问通知)
- [ ] 消息模板:自定义通知消息格式
- [ ] 多 Gotify 支持:同时推送到多个 Gotify 服务器
+20
View File
@@ -49,6 +49,8 @@ func (h *HookHandler) HandleHook(w http.ResponseWriter, r *http.Request) {
title, message, priority = h.handleNotification(event)
case "Stop":
title, message, priority = h.handleStop(event)
case "PreToolUse":
title, message, priority = h.handlePreToolUse(event)
default:
log.Printf("ignored event: %s", event.HookEventName)
w.WriteHeader(http.StatusOK)
@@ -90,6 +92,24 @@ func (h *HookHandler) handleNotification(event ClaudeCodeHookEvent) (title, mess
return title, message, priority
}
func (h *HookHandler) handlePreToolUse(event ClaudeCodeHookEvent) (title, message string, priority int) {
switch event.ToolName {
case "AskUserQuestion":
title = "Claude Code - 等待回答"
if question, ok := event.ToolInput["question"].(string); ok && question != "" {
message = "Claude 向你提问: " + question
} else {
message = "Claude 向你提出了一个问题,等待你的回答"
}
priority = 6
default:
title = "Claude Code - 工具调用"
message = fmt.Sprintf("Claude 正在使用 %s", event.ToolName)
priority = 4
}
return title, message, priority
}
func (h *HookHandler) handleStop(event ClaudeCodeHookEvent) (title, message string, priority int) {
if event.StopHookActive {
// Avoid infinite loop: Stop hook triggered too many times