- Environment-based configuration (no hardcoded secrets) - OAuth authentication via Authentik - ElevenLabs TTS integration via SAG CLI - FCM push notification support - User preferences sync system - Multi-user support with per-user context files - No internal IPs or service accounts in tracked files
179 lines
4.2 KiB
Bash
Executable File
179 lines
4.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# alfred-notify - Send notifications and alarms to Alfred mobile app
|
|
# Usage: alfred-notify [OPTIONS] MESSAGE
|
|
|
|
set -euo pipefail
|
|
|
|
# Configuration
|
|
PROXY_URL="${ALFRED_PROXY_URL:-http://localhost:18790}"
|
|
NOTIFICATION_TYPE="alert"
|
|
TITLE="AI Assistant"
|
|
PRIORITY="default"
|
|
SOUND="true"
|
|
VIBRATE="true"
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Usage
|
|
usage() {
|
|
cat << EOF
|
|
Usage: alfred-notify [OPTIONS] MESSAGE
|
|
|
|
Send notifications and alarms to Alfred mobile app via proxy.
|
|
|
|
OPTIONS:
|
|
-a, --alarm Send as alarm (high priority, full screen)
|
|
-t, --title TITLE Notification title (default: "AI Assistant")
|
|
-p, --priority LEVEL Priority: low, default, high (default: default)
|
|
-s, --no-sound Disable sound
|
|
-v, --no-vibrate Disable vibration
|
|
--user USER_ID Send only to devices for this user (OAuth sub)
|
|
-u, --url URL Proxy URL (default: http://localhost:18790)
|
|
-h, --help Show this help
|
|
|
|
EXAMPLES:
|
|
# Simple notification
|
|
alfred-notify "Reminder: Check the oven"
|
|
|
|
# Alarm with custom title
|
|
alfred-notify --alarm --title "Wake Up!" "Time to get up"
|
|
|
|
# Quiet notification
|
|
alfred-notify --no-sound --no-vibrate "Silent message"
|
|
|
|
# Custom proxy URL
|
|
alfred-notify --url http://192.168.1.169:18790 "From remote server"
|
|
|
|
ENVIRONMENT:
|
|
ALFRED_PROXY_URL Override default proxy URL
|
|
|
|
NOTES:
|
|
- Alarms use high priority and are more intrusive
|
|
- Messages sent via FCM will wake the device
|
|
- Token persistence ensures delivery even after proxy restarts
|
|
|
|
EOF
|
|
exit 0
|
|
}
|
|
|
|
# Parse arguments
|
|
MESSAGE=""
|
|
USER_ID=""
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
-a|--alarm)
|
|
NOTIFICATION_TYPE="alarm"
|
|
PRIORITY="high"
|
|
shift
|
|
;;
|
|
-t|--title)
|
|
TITLE="$2"
|
|
shift 2
|
|
;;
|
|
-p|--priority)
|
|
PRIORITY="$2"
|
|
shift 2
|
|
;;
|
|
-s|--no-sound)
|
|
SOUND="false"
|
|
shift
|
|
;;
|
|
-v|--no-vibrate)
|
|
VIBRATE="false"
|
|
shift
|
|
;;
|
|
--user)
|
|
USER_ID="$2"
|
|
shift 2
|
|
;;
|
|
-u|--url)
|
|
PROXY_URL="$2"
|
|
shift 2
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
;;
|
|
-*)
|
|
echo -e "${RED}Error: Unknown option: $1${NC}" >&2
|
|
echo "Use --help for usage information" >&2
|
|
exit 1
|
|
;;
|
|
*)
|
|
MESSAGE="$1"
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Validate message
|
|
if [[ -z "$MESSAGE" ]]; then
|
|
echo -e "${RED}Error: MESSAGE is required${NC}" >&2
|
|
echo "Use: alfred-notify [OPTIONS] MESSAGE" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Build JSON payload
|
|
if [[ -n "$USER_ID" ]]; then
|
|
JSON_PAYLOAD=$(cat <<EOF
|
|
{
|
|
"notificationType": "$NOTIFICATION_TYPE",
|
|
"title": "$TITLE",
|
|
"message": "$MESSAGE",
|
|
"priority": "$PRIORITY",
|
|
"sound": $SOUND,
|
|
"vibrate": $VIBRATE,
|
|
"userId": "$USER_ID"
|
|
}
|
|
EOF
|
|
)
|
|
else
|
|
JSON_PAYLOAD=$(cat <<EOF
|
|
{
|
|
"notificationType": "$NOTIFICATION_TYPE",
|
|
"title": "$TITLE",
|
|
"message": "$MESSAGE",
|
|
"priority": "$PRIORITY",
|
|
"sound": $SOUND,
|
|
"vibrate": $VIBRATE
|
|
}
|
|
EOF
|
|
)
|
|
fi
|
|
|
|
# Send notification
|
|
RESPONSE=$(curl -s -X POST "$PROXY_URL/api/notify" \
|
|
-H "Content-Type: application/json" \
|
|
-d "$JSON_PAYLOAD" \
|
|
-w "\n%{http_code}")
|
|
|
|
# Parse response
|
|
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
|
BODY=$(echo "$RESPONSE" | head -n-1)
|
|
|
|
# Check result
|
|
if [[ "$HTTP_CODE" == "200" ]]; then
|
|
# Parse success response
|
|
CLIENTS=$(echo "$BODY" | grep -o '"clients":[0-9]*' | cut -d: -f2)
|
|
FCM=$(echo "$BODY" | grep -o '"fcm":[0-9]*' | cut -d: -f2)
|
|
|
|
echo -e "${GREEN}✓ Notification sent${NC}"
|
|
echo " Type: $NOTIFICATION_TYPE"
|
|
echo " WebSocket clients: $CLIENTS"
|
|
echo " FCM devices: $FCM"
|
|
|
|
if [[ "$CLIENTS" == "0" ]] && [[ "$FCM" == "0" ]]; then
|
|
echo -e "${YELLOW}⚠ Warning: No devices received notification${NC}" >&2
|
|
echo " Make sure Alfred app is connected or FCM token is registered" >&2
|
|
exit 2
|
|
fi
|
|
else
|
|
echo -e "${RED}✗ Failed to send notification${NC}" >&2
|
|
echo " HTTP Status: $HTTP_CODE" >&2
|
|
echo " Response: $BODY" >&2
|
|
exit 1
|
|
fi
|