Documentation Index Fetch the complete documentation index at: https://factory-docs-auto-sync-jp-docs.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
This cookbook shows how to set up custom notifications so you know when Droid needs your input or when important events occur during a session.
How it works
Notification hooks can:
Trigger on multiple events : Notification, Stop, SubagentStop, SessionEnd
Support multiple channels : Desktop notifications, system sounds, Slack, email, webhooks
Provide context : Include session details, task completion status, error messages
Filter intelligently : Only notify on important events
Work cross-platform : macOS, Linux, Windows
Prerequisites
Install notification tools for your platform:
macOS
Linux
Windows (PowerShell)
# Built-in commands (no installation needed)
which osascript # For display notifications
which afplay # For sounds
For Slack notifications, create a webhook at api.slack.com/messaging/webhooks .
Basic notifications
Desktop notification when Droid waits
Get notified when Droid is waiting for your input.
Create .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
Add to ~/.factory/settings.json (user-wide):
{
"hooks" : {
"Notification" : [
{
"hooks" : [
{
"type" : "command" ,
"command" : "~/.factory/hooks/notify-wait.sh" ,
"timeout" : 5
}
]
}
]
}
}
Sound alert when task completes
Play a sound when Droid finishes.
Create .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
Add to ~/.factory/settings.json:
{
"hooks" : {
"Stop" : [
{
"hooks" : [
{
"type" : "command" ,
"command" : "~/.factory/hooks/completion-sound.sh" ,
"timeout" : 3
}
]
}
]
}
}
Advanced notifications
Slack integration
Send Slack messages when Droid completes tasks.
Create .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
Set your webhook URL:
# Add to ~/.bashrc or ~/.zshrc
export SLACK_WEBHOOK_URL = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
Add to ~/.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
}
]
}
]
}
}
Email notifications
Send email alerts for important events.
Create .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
Configure environment:
# Add to ~/.bashrc or ~/.zshrc
export DROID_NOTIFY_EMAIL = "your-email@example.com"
Rich desktop notifications with actions
macOS notifications with action buttons.
Create .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 integration
Send notifications to custom webhooks:
Create .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"
Real-world examples
Example 1: Focus mode notifications
Only notify when you’re away from your desk:
Create .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
Example 2: Team notification dashboard
Log all events to a shared dashboard:
Create .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
Best practices
Keep notification scripts fast
Use short timeouts to avoid blocking Droid: {
"timeout" : 5 // 5 seconds max for notifications
}
Handle failures gracefully
Don’t block execution if notifications fail: # Continue even if curl fails
curl -X POST " $URL " ... || true
exit 0
Respect user preferences
Check environment variables for opt-out: if [ " $DROID_DISABLE_NOTIFICATIONS " = "true" ]; then
exit 0
fi
Test notifications
Manually trigger hooks for testing: # Test notification script
echo '{"hook_event_name":"Notification","message":"Test"}' | .factory/hooks/notify-wait.sh
Use appropriate notification levels
Different events warrant different urgency:
Notification: High urgency (Droid waiting)
Stop: Medium urgency (task complete)
SessionEnd: Low urgency (FYI only)
Troubleshooting
Problem : No notifications show up
Solution : Check notification permissions:
# macOS - check System Settings > Notifications
# Linux - verify notify-send works
notify-send "Test" "This is a test"
# Check if hooks are executing
droid --debug
Problem : Slack messages not sending
Solution : Test webhook directly:
curl -X POST " $SLACK_WEBHOOK_URL " \
-H 'Content-Type: application/json' \
-d '{"text":"Test from curl"}'
Problem : Getting spammed with alerts
Solution : Add rate limiting:
# 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
Problem : No audio alert
Solution : Check audio system:
# 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
See also