Claude Codeの動作状況をDiscord Webhookで通知する設定。
- SessionStart: セッション開始時に通知
- Stop: 応答完了時に、最後の応答内容をDiscordに送信
transcript_summary は存在しない。使えるのは以下:
| フィールド | 説明 |
|---|---|
last_assistant_message |
最後の応答テキスト |
stop_hook_active |
true の場合は hook 起因の停止(無限ループ防止に必須) |
session_id |
セッションID |
transcript_path |
トランスクリプトのパス |
Claude Code (2025年2月時点) では、SessionStart hookが約0.3秒差で2回発火する。 PIDも異なるため、2つの別プロセスとして実行される。
対策: ロックファイルで5秒以内の重複実行を防止する。
Termux (Android) では /tmp/ への書き込みが Permission denied になる。
代わりに /data/data/com.termux/files/usr/tmp/ を使うこと。
{
"hooks": {
"SessionStart": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/discord-start.sh"
}
]
}
],
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/discord-stop.sh"
}
]
}
]
}
}#!/bin/bash
WEBHOOK_URL="YOUR_DISCORD_WEBHOOK_URL"
TMPDIR="/data/data/com.termux/files/usr/tmp" # Termux環境用。通常環境は /tmp でOK
LOCKFILE="$TMPDIR/session_start.lock"
# 5秒以内の重複実行を防止(SessionStartが2回発火するバグ対策)
if [ -f "$LOCKFILE" ]; then
LOCK_AGE=$(( $(date +%s) - $(stat -c %Y "$LOCKFILE" 2>/dev/null || echo 0) ))
if [ "$LOCK_AGE" -lt 5 ]; then
exit 0
fi
fi
touch "$LOCKFILE"
T=$(date '+%H:%M:%S')
PAYLOAD=$(jq -n --arg content "[$T] セッション開始" '{"username":"cc","content":$content}')
curl -sf -X POST "$WEBHOOK_URL" \
-H 'Content-Type: application/json' \
-d "$PAYLOAD" &>/dev/null &#!/bin/bash
WEBHOOK_URL="YOUR_DISCORD_WEBHOOK_URL"
# stdinからJSONを読み取り
INPUT=$(cat)
# stop_hook_activeがtrueなら何もしない(無限ループ防止)
ACTIVE=$(echo "$INPUT" | jq -r '.stop_hook_active // false' 2>/dev/null)
if [ "$ACTIVE" = "true" ]; then
exit 0
fi
# 最後の応答テキストを取得
MSG=$(echo "$INPUT" | jq -r '.last_assistant_message // "completed"' 2>/dev/null)
# 先頭に時刻を付与
TIMESTAMP=$(date '+%H:%M:%S')
MSG="[${TIMESTAMP}] ${MSG}"
# 2000文字制限(Discord制限)
MSG="${MSG:0:1900}"
# Discordに送信
PAYLOAD=$(jq -n --arg content "$MSG" '{"username":"cc","content":$content}')
curl -sf -X POST "$WEBHOOK_URL" \
-H 'Content-Type: application/json' \
-d "$PAYLOAD" &>/dev/null &jq- JSON処理curl- HTTP送信