Mục lục
- Hook nào cho tình huống nào
- Bạn cần gì
- Bước 1 — Tạo hai kênh
- Bước 2 — Thêm hooks
- Bước 3 — Kiểm thử mà không cần chờ yêu cầu thật
- Bước 4 — Cho kênh blocked đổ chuông
- Tránh ngập thông báo
- Chạy Claude Code từ xa hoặc trong CI
- Khắc phục sự cố
- Câu hỏi thường gặp
- Làm sao nhận thông báo khi Claude Code cần cấp quyền?
- Làm sao biết Claude Code đã xong một tác vụ?
- Thông báo có thể xuyên qua chế độ Không làm phiền không?
- Cách này có dùng được với Claude Code trên web hoặc phiên từ xa không?
- Đặt URL webhook trong settings.json có an toàn không?
- Tổng kết
- Bài viết liên quan
Claude Code dừng lại trong hai tình huống đáng chú ý: nó bị chặn để chờ bạn (một yêu cầu cấp quyền, một câu hỏi), hoặc nó đã làm xong. Nếu bạn không nhìn vào terminal, hai trường hợp này trông y hệt nhau — không có gì xảy ra, và phiên làm việc nằm im cho đến khi bạn quay lại. Cách khắc phục là một hook: vài dòng trong settings.json gửi webhook tới điện thoại của bạn ngay khi một trong hai tình huống xảy ra.
Hướng dẫn này cho bạn cấu hình để sao chép, giải thích nên dùng hook event nào cho tình huống nào, và đi qua các chi tiết giúp nó chạy ổn định: đọc input của hook, cách đặt dấu nháy trong shell, và tránh bị ngập trong thông báo.
Hook nào cho tình huống nào
Claude Code chạy hook theo các sự kiện trong vòng đời của nó. Hai sự kiện giải quyết vấn đề này (tài liệu tham chiếu hooks):
| Bạn muốn biết khi… | Hook event | Matcher / bộ lọc |
|---|---|---|
| Claude đang chờ quyết định cấp quyền | Notification | permission_prompt |
| Claude đã rảnh và đang chờ input của bạn | Notification | idle_prompt |
| Claude phản hồi xong | Stop | không cần |
matcher của hook Notification lọc theo loại thông báo, nên bạn chọn được chính xác thông báo nào đến điện thoại. Input đến dưới dạng JSON qua stdin và gồm notification_type, message, cwd và session_id. Hook Notification không thể chặn hay thay đổi bất cứ thứ gì — chúng chỉ quan sát, đúng thứ bạn cần ở đây.
Input của Stop có last_assistant_message, đoạn văn bản cuối cùng Claude tạo ra. Đó là một dòng tóm tắt miễn phí cho thông báo.
Bạn cần gì
- Echobell trên điện thoại (App Store / Google Play)
curlvàjqtrên máy chạy Claude Code- Hai phút
Bước 1 — Tạo hai kênh
Đừng gửi mọi thứ vào một kênh. Trong Echobell, hãy tạo:
- Claude Blocked, loại Nhạy thời gian (Time Sensitive) hoặc Cuộc gọi — cho các yêu cầu cấp quyền, khi agent đang đứng yên và mỗi phút đều là lãng phí, cả tài nguyên tính toán lẫn thời gian của bạn
- Claude Done, loại Bình thường — một thông báo đẩy thông thường, đọc lúc nào cũng được
Sao chép URL webhook của từng kênh. Nó có dạng https://hook.echobell.one/t/<channel-token>. Hãy coi nó như mật khẩu: ai có nó cũng có thể làm điện thoại của bạn đổ chuông.
Lưu cả hai dưới dạng biến môi trường để chúng không bao giờ nằm trong file cấu hình được commit:
export ECHOBELL_CLAUDE_BLOCKED_URL="https://hook.echobell.one/t/<blocked-token>"
export ECHOBELL_CLAUDE_DONE_URL="https://hook.echobell.one/t/<done-token>"
Đặt chúng trong shell profile để Claude Code kế thừa.
Bước 2 — Thêm hooks
Thêm đoạn sau vào ~/.claude/settings.json để áp dụng cho mọi dự án, hoặc vào .claude/settings.local.json cho một repository:
{
"hooks": {
"Notification": [
{
"matcher": "permission_prompt",
"hooks": [
{
"type": "command",
"command": "jq -c '{title: \"Claude cần cấp quyền\", body: .message, project: (.cwd | split(\"/\") | last)}' | curl -sS -m 10 -X POST -H 'Content-Type: application/json' -d @- \"$ECHOBELL_CLAUDE_BLOCKED_URL\""
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "jq -c '{title: \"Claude đã xong\", body: (.last_assistant_message // \"Xong\" | .[0:200]), project: (.cwd | split(\"/\") | last)}' | curl -sS -m 10 -X POST -H 'Content-Type: application/json' -d @- \"$ECHOBELL_CLAUDE_DONE_URL\""
}
]
}
]
}
}
Từng phần làm gì:
jq -c '{...}'đọc JSON của hook từ stdin và dựng một payload nhỏ, để Echobell nhận đúng các trường bạn muốn thay vì toàn bộ tài liệu của hook..cwd | split("/") | lastbiến/home/me/code/apithànhapi, nên thông báo cho biết dự án nào đang yêu cầu..[0:200]cắt ngắn tin nhắn cuối. Nội dung thông báo bị worker của Echobell giới hạn ở 1500 byte, và màn hình khóa hiển thị còn ít hơn nhiều.-m 10đặt chocurlthời gian chờ 10 giây để sự cố mạng không bao giờ khiến Claude Code phải đợi hook của bạn.
Echobell hiển thị các key bạn gửi thông qua template của kênh, và kênh mới chưa có template nào đọc chúng — hãy đặt trong phần cài đặt kênh: template tiêu đề {{title}}, template nội dung {{body}}. Thêm {{project}} vào một trong hai nếu muốn hiện tên dự án, ví dụ {{title}} ({{project}}).
Bước 3 — Kiểm thử mà không cần chờ yêu cầu thật
Chạy thủ công cùng pipeline với một payload hook giả:
echo '{"message":"Claude needs your permission to use Bash","cwd":"/home/me/code/api","notification_type":"permission_prompt"}' \
| jq -c '{title: "Claude cần cấp quyền", body: .message, project: (.cwd | split("/") | last)}' \
| curl -sS -m 10 -X POST -H 'Content-Type: application/json' -d @- "$ECHOBELL_CLAUDE_BLOCKED_URL"
Nếu điện thoại sáng lên, phía Echobell đã ổn và vấn đề còn lại nằm ở cách Claude Code đọc cấu hình. Trong Claude Code, chạy /hooks để xác nhận hook đã được nạp; thay đổi cấu hình khi phiên đang chạy có thể cần mở menu hooks hoặc khởi động lại mới có hiệu lực.
Bước 4 — Cho kênh blocked đổ chuông
Thông báo đẩy thua chế độ Không làm phiền. Kênh Cuộc gọi hành xử như một cuộc gọi đến và xuyên qua chế độ Tập trung của iOS, điều đặc biệt quan trọng khi bạn giao một tác vụ dài rồi đi mất cả buổi tối. Nếu bạn chỉ muốn bị làm phiền với một số yêu cầu, hãy lọc bằng điều kiện kênh của Echobell trên các biến bạn gửi, ví dụ project == "api", thay vì sửa hook. Danh sách biến đầy đủ có trong tài liệu tham chiếu điều kiện.
Tránh ngập thông báo
Một phiên bận rộn có thể kích hoạt nhiều sự kiện Stop — mỗi phản hồi đều kết thúc bằng một sự kiện. Ba cách để giữ tín hiệu có ý nghĩa:
- Đừng gửi
Stoptới kênh đổ chuông. Hoàn thành không khẩn cấp; hãy để ở loại Bình thường. - Dùng
idle_promptthay choStopnếu bạn chỉ muốn biết khi Claude đã dừng và đang chờ bạn, thay vì sau mỗi phản hồi. - Thu hẹp theo dự án bằng một điều kiện, để repository thử nghiệm không báo cho bạn chút nào.
Chạy Claude Code từ xa hoặc trong CI
Cách tiếp cận này cũng hoạt động trong môi trường cloud hoặc từ xa, vì hook chỉ là một yêu cầu HTTPS đi ra. Không có gì cần truy cập được từ internet. Hãy đặt hai biến môi trường trong secrets của môi trường thay vì shell profile, và thông báo sẽ đến điện thoại bạn dù phiên chạy ở đâu.
Khắc phục sự cố
Không có gì đến, và bài kiểm thử thủ công cũng thất bại. Kiểm tra biến URL đã được đặt trong shell khởi chạy Claude Code chưa: echo "$ECHOBELL_CLAUDE_BLOCKED_URL". Biến rỗng khiến curl thất bại âm thầm.
Kiểm thử thủ công chạy được nhưng hook không kích hoạt. Xác nhận lại matcher: permission_prompt và idle_prompt là hai giá trị khác nhau, và matcher không khớp thì đơn giản là không bao giờ chạy. Chạy /hooks và kiểm tra JSON hợp lệ — một dấu phẩy thừa ở cuối sẽ vô hiệu hóa toàn bộ hook trong file cấu hình đó.
Nội dung thông báo trống. Bộ lọc jq tham chiếu một trường không tồn tại với sự kiện đó. message có trong input của Notification; last_assistant_message có trong input của Stop. Dùng // để cung cấp giá trị mặc định, như trong cấu hình ở trên.
Kích hoạt quá thường xuyên. Xem mục ở trên — chuyển từ Stop sang idle_prompt, hoặc thêm điều kiện.
Câu hỏi thường gặp
Làm sao nhận thông báo khi Claude Code cần cấp quyền?
Thêm một hook Notification với matcher permission_prompt gửi webhook tới một kênh. Echobell biến yêu cầu đó thành thông báo đẩy hoặc cảnh báo kiểu cuộc gọi trên điện thoại của bạn.
Làm sao biết Claude Code đã xong một tác vụ?
Thêm một hook Stop. Nó chạy khi Claude phản hồi xong, và input của nó có last_assistant_message, bạn có thể dùng làm nội dung thông báo.
Thông báo có thể xuyên qua chế độ Không làm phiền không?
Có, nếu kênh nhận là kênh Cuộc gọi. Nó hành xử như một cuộc gọi đến, loại mà chế độ Tập trung của iOS cho đi qua. Thông báo đẩy thường từ bất kỳ ứng dụng nào thì không.
Cách này có dùng được với Claude Code trên web hoặc phiên từ xa không?
Có. Hook chỉ tạo một yêu cầu HTTPS đi ra, nên hoạt động ở bất cứ đâu phiên có thể kết nối internet. Hãy cung cấp URL kênh qua secrets của môi trường.
Đặt URL webhook trong settings.json có an toàn không?
Nên dùng biến môi trường như ở trên để token không bị commit vào repository. Nếu bị lộ, hãy tạo kênh mới và bỏ kênh cũ.
Tổng kết
Hai kênh, hai hook và một pipeline jq | curl: kênh Cuộc gọi hoặc Nhạy thời gian cho permission_prompt, kênh Bình thường cho Stop. Sau đó bạn có thể giao một tác vụ agent dài, rời khỏi phòng, và chỉ bị gọi lại khi agent thực sự cần bạn.
Tải Echobell cho iPhone hoặc tải trên Google Play, rồi chạy bài kiểm thử thủ công ở trên trước khi giao cho nó một tác vụ dài.