メインコンテンツへスキップ
このクックブックでは、Droidがあなたの入力を必要としている時や、セッション中に重要なイベントが発生した時に知ることができるカスタム通知の設定方法を説明します。

仕組み

通知フックは以下のことができます:
  1. 複数のイベントでトリガー: 通知、停止、サブエージェント停止、セッション終了
  2. 複数のチャンネルに対応: デスクトップ通知、システム音、Slack、メール、webhook
  3. コンテキストを提供: セッション詳細、タスク完了状況、エラーメッセージを含む
  4. インテリジェントフィルタリング: 重要なイベントのみを通知
  5. クロスプラットフォーム対応: macOS、Linux、Windows

前提条件

お使いのプラットフォーム用の通知ツールをインストール:
# Built-in commands (no installation needed)
which osascript  # For display notifications
which afplay     # For sounds
Slack通知については、api.slack.com/messaging/webhooksでwebhookを作成してください。

基本的な通知

Droidが待機している時のデスクトップ通知

Droidがあなたの入力を待っている時に通知を受け取ります。 .factory/hooks/notify-wait.shを作成:
#!/bin/bash

input=$(cat)
message=$(echo "$input" | jq -r '.message // "Droid needs your attention"')
hook_event=$(echo "$input" | jq -r '.hook_event_name')

# Only notify on actual wait events
if [ "$hook_event" != "Notification" ]; then
  exit 0
fi

# Platform-specific notification
if [[ "$OSTYPE" == "darwin"* ]]; then
  # macOS
  osascript -e "display notification \"$message\" with title \"Droid\" sound name \"Ping\""
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
  # Linux
  notify-send "Droid" "$message" -i dialog-information -u normal
elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" ]]; then
  # Windows
  powershell -Command "New-BurntToastNotification -Text 'Droid', '$message'"
fi

exit 0
chmod +x .factory/hooks/notify-wait.sh
~/.factory/settings.jsonに追加(ユーザー全体):
{
  "hooks": {
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "~/.factory/hooks/notify-wait.sh",
            "timeout": 5
          }
        ]
      }
    ]
  }
}

タスク完了時の音声アラート

Droidが終了した時に音を再生します。 .factory/hooks/completion-sound.shを作成:
#!/bin/bash

input=$(cat)
hook_event=$(echo "$input" | jq -r '.hook_event_name')

# Only alert on completion events
if [ "$hook_event" != "Stop" ]; then
  exit 0
fi

# Platform-specific sound
if [[ "$OSTYPE" == "darwin"* ]]; then
  # macOS - use system sounds
  afplay /System/Library/Sounds/Glass.aiff
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
  # Linux - use system bell or speaker-test
  paplay /usr/share/sounds/freedesktop/stereo/complete.oga 2>/dev/null || \
    echo -e '\a'  # Fallback to terminal bell
fi

exit 0
chmod +x .factory/hooks/completion-sound.sh
~/.factory/settings.jsonに追加:
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "~/.factory/hooks/completion-sound.sh",
            "timeout": 3
          }
        ]
      }
    ]
  }
}

高度な通知

Slack連携

Droidがタスクを完了した時にSlackメッセージを送信します。 .factory/hooks/slack-notify.shを作成:
#!/bin/bash
set -e

# Configure your Slack webhook URL
SLACK_WEBHOOK_URL="${SLACK_WEBHOOK_URL:-}"

if [ -z "$SLACK_WEBHOOK_URL" ]; then
  echo "SLACK_WEBHOOK_URL not set, skipping Slack notification"
  exit 0
fi

input=$(cat)
hook_event=$(echo "$input" | jq -r '.hook_event_name')
session_id=$(echo "$input" | jq -r '.session_id')
cwd=$(echo "$input" | jq -r '.cwd')

# Build message based on event type
case "$hook_event" in
  "Stop")
    title="✅ Droid Task Completed"
    color="good"
    ;;
  "SessionEnd")
    title="🏁 Droid Session Ended"
    color="#808080"
    reason=$(echo "$input" | jq -r '.reason')
    ;;
  "SubagentStop")
    title="🤖 Subagent Task Completed"
    color="good"
    ;;
  *)
    exit 0
    ;;
esac

# Send to Slack
curl -X POST "$SLACK_WEBHOOK_URL" \
  -H 'Content-Type: application/json' \
  -d @- << EOF
{
  "attachments": [
    {
      "color": "$color",
      "title": "$title",
      "fields": [
        {
          "title": "Project",
          "value": "$(basename "$cwd")",
          "short": true
        },
        {
          "title": "Session",
          "value": "${session_id:0:8}...",
          "short": true
        }
      ],
      "footer": "Droids",
      "ts": $(date +%s)
    }
  ]
}
EOF

exit 0
chmod +x .factory/hooks/slack-notify.sh
webhook URLを設定:
# Add to ~/.bashrc or ~/.zshrc
export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
~/.factory/settings.jsonに追加:
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "~/.factory/hooks/slack-notify.sh",
            "timeout": 10
          }
        ]
      }
    ],
    "SessionEnd": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "~/.factory/hooks/slack-notify.sh",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

メール通知

重要なイベントのメールアラートを送信します。 .factory/hooks/email-notify.shを作成:
#!/bin/bash
set -e

# Configure email settings
EMAIL_TO="${DROID_NOTIFY_EMAIL:-your-email@example.com}"
EMAIL_FROM="${DROID_FROM_EMAIL:-droid@factory.ai}"

input=$(cat)
hook_event=$(echo "$input" | jq -r '.hook_event_name')

# Only notify on session end with errors
if [ "$hook_event" != "SessionEnd" ]; then
  exit 0
fi

reason=$(echo "$input" | jq -r '.reason')
session_id=$(echo "$input" | jq -r '.session_id')
cwd=$(echo "$input" | jq -r '.cwd')

# Check if session ended due to error
if [ "$reason" != "error" ] && [ "$reason" != "other" ]; then
  exit 0
fi

# Send email using sendmail or mail command
subject="Droid Session Ended: $(basename "$cwd")"
body="Session $session_id ended with reason: $reason

Project: $cwd
Time: $(date)

Check the logs for more details."

# Try sendmail first, fallback to mail command
if command -v sendmail &> /dev/null; then
  echo -e "Subject: $subject\nFrom: $EMAIL_FROM\nTo: $EMAIL_TO\n\n$body" | sendmail -t
elif command -v mail &> /dev/null; then
  echo "$body" | mail -s "$subject" "$EMAIL_TO"
else
  echo "No email command available (sendmail or mail)"
  exit 1
fi

exit 0
chmod +x .factory/hooks/email-notify.sh
環境を設定:
# Add to ~/.bashrc or ~/.zshrc
export DROID_NOTIFY_EMAIL="your-email@example.com"

アクション付きリッチデスクトップ通知

アクションボタン付きのmacOS通知。 .factory/hooks/rich-notify-macos.shを作成:
#!/bin/bash

input=$(cat)
hook_event=$(echo "$input" | jq -r '.hook_event_name')
message=$(echo "$input" | jq -r '.message // "Droid needs your attention"')
session_id=$(echo "$input" | jq -r '.session_id')

# Only for macOS
if [[ "$OSTYPE" != "darwin"* ]]; then
  exit 0
fi

case "$hook_event" in
  "Notification")
    # Notification with action buttons
    osascript << EOF
tell application "System Events"
  display notification "$message" with title "Droid Waiting" subtitle "Session: ${session_id:0:8}" sound name "Ping"
end tell
EOF
    ;;
    
  "Stop")
    # Success notification
    osascript << EOF
tell application "System Events"
  display notification "Task completed successfully" with title "Droid Complete" subtitle "$(basename "$PWD")" sound name "Glass"
end tell
EOF
    ;;
    
  "SessionEnd")
    reason=$(echo "$input" | jq -r '.reason')
    # Different sound based on reason
    sound="Purr"
    if [ "$reason" == "error" ]; then
      sound="Basso"
    fi
    
    osascript << EOF
tell application "System Events"
  display notification "Session ended: $reason" with title "Droid Session" subtitle "$(basename "$PWD")" sound name "$sound"
end tell
EOF
    ;;
esac

exit 0
chmod +x .factory/hooks/rich-notify-macos.sh

Webhook連携

カスタムwebhookに通知を送信: .factory/hooks/webhook-notify.shを作成:
#!/bin/bash
set -e

WEBHOOK_URL="${DROID_WEBHOOK_URL:-}"

if [ -z "$WEBHOOK_URL" ]; then
  exit 0
fi

input=$(cat)

# Forward the entire hook input to webhook
curl -X POST "$WEBHOOK_URL" \
  -H 'Content-Type: application/json' \
  -d "$input" \
  --max-time 5 \
  --silent \
  --show-error

exit 0
chmod +x .factory/hooks/webhook-notify.sh
export DROID_WEBHOOK_URL="https://your-webhook-url.com/droid-events"

実際の使用例

例1: フォーカスモード通知

デスクから離れている時のみ通知: .factory/hooks/smart-notify.shを作成:
#!/bin/bash

input=$(cat)

# Check if user is idle (macOS)
if [[ "$OSTYPE" == "darwin"* ]]; then
  idle_time=$(ioreg -c IOHIDSystem | awk '/HIDIdleTime/ {print int($NF/1000000000)}')
  
  # Only notify if idle for more than 60 seconds
  if [ "$idle_time" -lt 60 ]; then
    exit 0
  fi
fi

# Send notification
message=$(echo "$input" | jq -r '.message // "Droid needs your attention"')
osascript -e "display notification \"$message\" with title \"Droid\" sound name \"Ping\""

exit 0

例2: チーム通知ダッシュボード

すべてのイベントを共有ダッシュボードに記録: .factory/hooks/team-logger.shを作成:
#!/bin/bash
set -e

# Central logging endpoint
LOG_ENDPOINT="${TEAM_LOG_ENDPOINT:-}"

if [ -z "$LOG_ENDPOINT" ]; then
  exit 0
fi

input=$(cat)
hook_event=$(echo "$input" | jq -r '.hook_event_name')
session_id=$(echo "$input" | jq -r '.session_id')
cwd=$(echo "$input" | jq -r '.cwd')

# Add metadata
payload=$(echo "$input" | jq -c ". + {
  user: \"$USER\",
  hostname: \"$HOSTNAME\",
  timestamp: \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",
  project: \"$(basename "$cwd")\"
}")

# Send to logging service
curl -X POST "$LOG_ENDPOINT" \
  -H 'Content-Type: application/json' \
  -d "$payload" \
  --max-time 3 \
  --silent

exit 0

ベストプラクティス

1

Keep notification scripts fast

Use short timeouts to avoid blocking Droid:
{
  "timeout": 5  // 5 seconds max for notifications
}
2

Handle failures gracefully

Don’t block execution if notifications fail:
# Continue even if curl fails
curl -X POST "$URL" ... || true
exit 0
3

Respect user preferences

Check environment variables for opt-out:
if [ "$DROID_DISABLE_NOTIFICATIONS" = "true" ]; then
  exit 0
fi
4

Test notifications

Manually trigger hooks for testing:
# Test notification script
echo '{"hook_event_name":"Notification","message":"Test"}' | .factory/hooks/notify-wait.sh
5

Use appropriate notification levels

Different events warrant different urgency:
  • Notification: High urgency (Droid waiting)
  • Stop: Medium urgency (task complete)
  • SessionEnd: Low urgency (FYI only)

トラブルシューティング

問題: 通知が表示されない 解決策: 通知の権限を確認:
# macOS - check System Settings > Notifications
# Linux - verify notify-send works
notify-send "Test" "This is a test"

# Check if hooks are executing
droid --debug
問題: Slackメッセージが送信されない 解決策: webhookを直接テスト:
curl -X POST "$SLACK_WEBHOOK_URL" \
  -H 'Content-Type: application/json' \
  -d '{"text":"Test from curl"}'
問題: アラートスパムを受け取る 解決策: レート制限を追加:
# Only notify once every 5 minutes
LAST_NOTIFY_FILE="/tmp/droid-last-notify"

if [ -f "$LAST_NOTIFY_FILE" ]; then
  last_time=$(cat "$LAST_NOTIFY_FILE")
  current_time=$(date +%s)
  if [ $((current_time - last_time)) -lt 300 ]; then
    exit 0
  fi
fi

date +%s > "$LAST_NOTIFY_FILE"
# ... send notification
問題: 音声アラートが鳴らない 解決策: 音声システムを確認:
# macOS - list available sounds
ls /System/Library/Sounds/

# Test sound
afplay /System/Library/Sounds/Glass.aiff

# Linux - check audio
paplay /usr/share/sounds/freedesktop/stereo/complete.oga

関連項目