Skip to content

Instantly share code, notes, and snippets.

@NickChristensen
Created December 13, 2025 17:42
Show Gist options
  • Select an option

  • Save NickChristensen/c79d633370512c9acaa382f752654399 to your computer and use it in GitHub Desktop.

Select an option

Save NickChristensen/c79d633370512c9acaa382f752654399 to your computer and use it in GitHub Desktop.
Claude Hook: Pushover notification on idle
#!/usr/bin/env fish
# Idle threshold in seconds - only send pushover if idle >= this long
set IDLE_THRESHOLD 30
set LOG_FILE /tmp/claude-notify.log
# Extract message from notification JSON
set MESSAGE (jq -r '.message')
echo "["(date "+%Y-%m-%d %H:%M:%S")"] Notification received: $MESSAGE" >> $LOG_FILE
# Sleep for threshold duration to see if user is actually away
sleep $IDLE_THRESHOLD
# Check current idle time in seconds
set IDLE_TIME (ioreg -c IOHIDSystem | awk '/HIDIdleTime/ {print int($NF/1000000000); exit}')
echo "["(date "+%Y-%m-%d %H:%M:%S")"] Idle time: {$IDLE_TIME}s, threshold: {$IDLE_THRESHOLD}s" >> $LOG_FILE
# Only send pushover notification if user has been idle long enough
if test $IDLE_TIME -ge $IDLE_THRESHOLD
echo "["(date "+%Y-%m-%d %H:%M:%S")"] Sending pushover notification" >> $LOG_FILE
source ~/.config/fish/conf.d/pushover_env.fish
pushover --app claude "$MESSAGE"
else
echo "["(date "+%Y-%m-%d %H:%M:%S")"] Skipping pushover notification" >> $LOG_FILE
end
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "INSERT_PATH/claude/hooks/notify.fish"
}
]
}
]
}
}
function pushover --description "Send Pushover notifications"
# Parse arguments
argparse --name=pushover 'h/help' 'a/app=' 't/title=' 'm/monospace' -- $argv
or return 1
# Show help if requested
if set -q _flag_help
echo "pushover - Send Pushover notifications"
echo ""
echo "USAGE:"
echo " pushover --app <appname> [--title <title>] <message>"
echo ""
echo "OPTIONS:"
echo " -h, --help Show this help message"
echo " -a, --app <name> App name (looks up PUSHOVER_TOKEN_<NAME>) [required]"
echo " -t, --title <text> Notification title (optional)"
echo " -m, --monospace Use monospace font for message"
echo ""
echo "ARGUMENTS:"
echo " <message> Message body (all remaining arguments)"
echo ""
echo "ENVIRONMENT VARIABLES:"
echo " PUSHOVER_USER_KEY Your Pushover user key (required)"
echo " PUSHOVER_TOKEN_<APPNAME> App-specific API tokens"
echo " PUSHOVER_DEBUG Show success confirmation when set"
echo ""
echo "SETUP FOR AGENTS:"
echo " 1. Source the environment file first:"
echo " source ~/.config/fish/conf.d/pushover_env.fish"
echo ""
echo " 2. Send notification:"
echo " pushover --app claude --title \"Job Done\" \"Task completed\""
echo ""
echo " Or in one command from non-fish shells:"
echo " fish -c 'source ~/.config/fish/conf.d/pushover_env.fish && \\"
echo " pushover --app claude --title \"Title\" \"Message\"'"
echo ""
echo "EXAMPLES:"
echo " # Basic usage"
echo " pushover --app claude --title \"Build Complete\" \"All tests passed\""
echo ""
echo " # Multi-word messages"
echo " pushover --app claude --title \"Status Update\" \"The job finished at \$(date)\""
echo ""
echo " # Monospace font for logs"
echo " pushover --app mac-mini --monospace --title \"Backup Failed\" \"Error log output\""
echo ""
echo "CREDENTIALS:"
echo " Add credentials to: ~/.config/fish/conf.d/pushover_env.fish"
echo " Format:"
echo " set -x PUSHOVER_USER_KEY \"your-user-key\""
echo " set -x PUSHOVER_TOKEN_CLAUDE \"your-app-token\""
return 0
end
# Validate required arguments
if not set -q _flag_app
echo "Error: --app is required" >&2
return 1
end
# Get the message from remaining arguments
if test (count $argv) -eq 0
echo "Error: message is required" >&2
return 1
end
set -l message (string join ' ' $argv)
# Validate user key exists
if not set -q PUSHOVER_USER_KEY
echo "Error: PUSHOVER_USER_KEY environment variable not set" >&2
echo "Add it to ~/.config/fish/conf.d/pushover_env.fish" >&2
return 1
end
# Look up token by app name (convert kebab-case to CONSTANT_CASE)
set -l app_name (string upper $_flag_app | string replace -a '-' '_')
set -l token_var_name "PUSHOVER_TOKEN_$app_name"
# Use Fish's indirect variable expansion
if not set -q $token_var_name
echo "Error: $token_var_name environment variable not set" >&2
echo "Add it to ~/.config/fish/conf.d/pushover_env.fish" >&2
echo "Example: set -x PUSHOVER_TOKEN_$app_name \"your-token-here\"" >&2
return 1
end
set -l app_token $$token_var_name
# Send the notification
set -l curl_args -s -X POST https://api.pushover.net/1/messages.json \
-d "token=$app_token" \
-d "user=$PUSHOVER_USER_KEY" \
-d "message=$message"
# Add title if provided
if set -q _flag_title
set curl_args $curl_args -d "title=$_flag_title"
end
# Add monospace flag if requested
if set -q _flag_monospace
set curl_args $curl_args -d "monospace=1"
end
set -l response (curl $curl_args)
# Check if the request was successful
if test $status -ne 0
echo "Error: curl request failed" >&2
return 1
end
# Parse JSON response to check for errors
if echo $response | string match -q '*"status":0*'
echo "Error: Pushover API returned an error:" >&2
echo $response | string match -r '"errors":\[.*?\]' >&2
return 1
end
# Success - optionally show confirmation
if test -n "$PUSHOVER_DEBUG"
echo "Notification sent successfully" >&2
end
return 0
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment