Files
openclaw-backups/automations/birthday-tracker/birthday-tracker.sh
Krilly 180532d1e3 Update automations: 3x daily FreshRSS, remove Mia, add Gotify, remove server monitor
- FreshRSS now runs 3x daily: 6:45 AM, 12 PM, 5 PM
- Removed Mia from birthday tracker 💔
- Removed home stack monitor cron jobs (already have monitoring)
- Added Gotify notifications to FreshRSS and birthday tracker
- Both Telegram and Gotify now receive alerts
2026-02-21 01:52:18 +00:00

351 lines
11 KiB
Bash
Executable File

#!/bin/bash
# Birthday & Gift Tracker
# Tracks family birthdays, sends reminders, suggests gifts
# Checks daily at 9:00 AM
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DATA_FILE="$SCRIPT_DIR/birthdays.json"
LOG_FILE="$SCRIPT_DIR/reminder-log.json"
source "$SCRIPT_DIR/../../.env" 2>/dev/null || true
TELEGRAM_CHAT="${TELEGRAM_CHAT:-1793951355}"
GOTIFY_URL="${GOTIFY_URL:-http://runtipi.kangaroo-eel.ts.net:8129}"
GOTIFY_TOKEN="${GOTIFY_TOKEN:-AGKnHafW3FGzBlt}"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
# Initialize data file if not exists
init_data() {
if [[ ! -f "$DATA_FILE" ]]; then
log "Creating birthday database..."
cat > "$DATA_FILE" << 'EOF'
{
"people": [
{
"name": "Grace Martin",
"relationship": "Mum",
"birthday": "06-02",
"birth_year": 1951,
"notes": "Cancer treatment ongoing - be extra thoughtful. Loves gardening, cooking, family time.",
"gift_ideas": ["Flowers", "Gardening supplies", "Photo album", "Day spa voucher", "Home-cooked meal"],
"past_gifts": []
},
{
"name": "Harvey Martin",
"relationship": "Dad",
"birthday": "12-08",
"birth_year": 1949,
"notes": "Full-time carer for Grace. Needs respite/support. Loves tech gadgets, wine, coffee.",
"gift_ideas": ["Ember mug", "Wine subscription", "Coffee beans", "Tech gadget", "Day out voucher"],
"past_gifts": []
},
{
"name": "Elizabeth Martin",
"relationship": "Sister",
"birthday": "09-11",
"birth_year": 1990,
"notes": "Vegan - avoid food gifts unless specifically vegan. Creative, environmentally conscious.",
"gift_ideas": ["Vegan cookbook", "Eco-friendly products", "Plants", "Art supplies", "Experience gift"],
"past_gifts": []
},
{
"name": "Alexander",
"relationship": "Godson/Cousin",
"birthday": "07-XX",
"birth_year": 2016,
"notes": "8 years old (born July 2016). Loves games, books, LEGO, sports.",
"gift_ideas": ["LEGO set", "Books", "Board games", "Sports equipment", "Science kit"],
"past_gifts": []
},
{
"name": "Mia Martin",
"relationship": "Doggo 🐕",
"birthday": "XX-XX",
"notes": "14 years old, beloved geriatric girl. Treats, toys, comfy beds.",
"gift_ideas": ["Premium dog treats", "Comfy bed", "New toy", "Grooming session"],
"past_gifts": []
}
],
"settings": {
"reminder_weeks_before": 2,
"reminder_days_before": 7,
"reminder_day_of": true
}
}
EOF
fi
if [[ ! -f "$LOG_FILE" ]]; then
echo '{"sent_reminders": []}' > "$LOG_FILE"
fi
}
# Get today's date in MM-DD format
today_mmdd() {
date +%m-%d
}
# Get today's date in YYYY-MM-DD format
today_yyyymmdd() {
date +%Y-%m-%d
}
# Calculate days until birthday
days_until_birthday() {
local bday_mmdd="$1"
local today=$(today_yyyymmdd)
local current_year=$(date +%Y)
# Handle missing day (XX)
if [[ "$bday_mmdd" == *"XX"* ]]; then
echo "unknown"
return
fi
local bday_this_year="$current_year-$bday_mmdd"
local bday_ts=$(date -d "$bday_this_year" +%s 2>/dev/null || echo "0")
local today_ts=$(date -d "$today" +%s)
# If birthday passed this year, calculate for next year
if ((bday_ts < today_ts)); then
((current_year++))
bday_this_year="$current_year-$bday_mmdd"
bday_ts=$(date -d "$bday_this_year" +%s)
fi
local diff=$(( (bday_ts - today_ts) / 86400 ))
echo "$diff"
}
# Check if reminder already sent today
reminder_sent() {
local person="$1"
local type="$2"
local today=$(today_yyyymmdd)
grep -q "\"$today-$person-$type\"" "$LOG_FILE" 2>/dev/null
}
# Log that reminder was sent
log_reminder() {
local person="$1"
local type="$2"
local today=$(today_yyyymmdd)
# Add to log
local temp_file=$(mktemp)
jq --arg key "$today-$person-$type" '.sent_reminders += [$key]' "$LOG_FILE" > "$temp_file"
mv "$temp_file" "$LOG_FILE"
}
# Clean old reminders from log (keep last 90 days)
cleanup_log() {
local cutoff=$(date -d "90 days ago" +%Y-%m-%d)
local temp_file=$(mktemp)
jq --arg cutoff "$cutoff" '.sent_reminders |= map(select(. > $cutoff or length < 10))' "$LOG_FILE" > "$temp_file" 2>/dev/null || true
mv "$temp_file" "$LOG_FILE" 2>/dev/null || true
}
# Send Telegram message
send_telegram() {
local message="$1"
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
-H "Content-Type: application/json" \
-d "{
\"chat_id\": \"$TELEGRAM_CHAT\",
\"text\": \"$message\",
\"parse_mode\": \"Markdown\"
}" > /dev/null || {
log "ERROR: Failed to send Telegram message"
return 1
}
}
# Send Gotify message
send_gotify() {
local title="$1"
local message="$2"
local priority="${3:-5}"
curl -s -X POST "${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}" \
-H "Content-Type: application/json" \
-d "{
\"title\": \"$title\",
\"message\": \"$message\",
\"priority\": $priority
}" > /dev/null || {
log "ERROR: Failed to send Gotify message"
return 1
}
}
# Generate gift suggestions text
gift_suggestions() {
local ideas=$(echo "$1" | jq -r '.gift_ideas | join(", ")')
local notes=$(echo "$1" | jq -r '.notes')
local past=$(echo "$1" | jq -r '.past_gifts | if length > 0 then "Past gifts: " + join(", ") else "" end')
local text="💡 *Gift Ideas:* $ideas"
if [[ -n "$past" && "$past" != "Past gifts: " ]]; then
text+="\n🎁 $past"
fi
text+="\n📝 *Notes:* $notes"
echo "$text"
}
# Check birthdays and send reminders
check_birthdays() {
log "Checking birthdays..."
local people=$(jq -c '.people[]' "$DATA_FILE")
local settings=$(jq '.settings' "$DATA_FILE")
local weeks_before=$(echo "$settings" | jq -r '.reminder_weeks_before')
local days_before=$(echo "$settings" | jq -r '.reminder_days_before')
local reminders_sent=0
while IFS= read -r person; do
local name=$(echo "$person" | jq -r '.name')
local relationship=$(echo "$person" | jq -r '.relationship')
local birthday=$(echo "$person" | jq -r '.birthday')
local birth_year=$(echo "$person" | jq -r '.birth_year // empty')
# Skip if no specific date
if [[ "$birthday" == *"XX"* ]]; then
continue
fi
local days_until=$(days_until_birthday "$birthday")
# Calculate age if birth year known
local age_text=""
if [[ -n "$birth_year" && "$birth_year" != "null" ]]; then
local current_year=$(date +%Y)
local age=$((current_year - birth_year))
if ((days_until < 365)); then
age_text=" (turning $age)"
fi
fi
# Check reminders
local should_remind=false
local reminder_type=""
local message=""
if ((days_until == 0)); then
reminder_type="today"
if ! reminder_sent "$name" "$reminder_type"; then
message="🎂 *Birthday Today!*\n\n*$name* — your $relationship$age_text\n\nDon't forget to call/message them! 💝"
local gifts=$(gift_suggestions "$person")
message+="\n\n$gifts"
should_remind=true
fi
elif ((days_until == days_before)); then
reminder_type="week"
if ! reminder_sent "$name" "$reminder_type"; then
message="📅 *Birthday Reminder*\n\n*$name* — your $relationship$age_text\nBirthday in *$days_until days* ($birthday)\n\nTime to plan something! 🎁"
local gifts=$(gift_suggestions "$person")
message+="\n\n$gifts"
should_remind=true
fi
elif ((days_until == weeks_before * 7)); then
reminder_type="twoweeks"
if ! reminder_sent "$name" "$reminder_type"; then
message="📅 *Upcoming Birthday*\n\n*$name* — your $relationship$age_text\nBirthday in *$days_until days* ($birthday)\n\nStart thinking about gifts! 🎁"
local gifts=$(gift_suggestions "$person")
message+="\n\n$gifts"
should_remind=true
fi
fi
if [[ "$should_remind" == true ]]; then
log "Sending $reminder_type reminder for $name"
send_telegram "$message"
# Also send to Gotify (strip markdown for cleaner display)
local plain_message
plain_message=$(echo -e "$message" | sed 's/\*//g')
local priority=5
[[ "$reminder_type" == "today" ]] && priority=8
send_gotify "Birthday: $name" "$plain_message" "$priority"
log_reminder "$name" "$reminder_type"
((reminders_sent++))
fi
done <<< "$people"
log "Sent $reminders_sent reminders"
}
# Add/update a person (can be called manually)
add_person() {
local name="$1"
local relationship="$2"
local birthday="$3" # MM-DD format
local notes="$4"
local temp_file=$(mktemp)
jq --arg name "$name" \
--arg rel "$relationship" \
--arg bday "$birthday" \
--arg notes "$notes" \
'.people += [{"name": $name, "relationship": $rel, "birthday": $bday, "notes": $notes, "gift_ideas": [], "past_gifts": []}]' \
"$DATA_FILE" > "$temp_file"
mv "$temp_file" "$DATA_FILE"
log "Added $name to birthday tracker"
}
# Log a past gift
log_gift() {
local name="$1"
local gift="$2"
local year="${3:-$(date +%Y)}"
local temp_file=$(mktemp)
jq --arg name "$name" \
--arg gift "$gift ($year)" \
'(.people[] | select(.name == $name)).past_gifts += [$gift]' \
"$DATA_FILE" > "$temp_file"
mv "$temp_file" "$DATA_FILE"
log "Logged gift for $name: $gift"
}
# Main
main() {
case "${1:-check}" in
check)
init_data
check_birthdays
cleanup_log
;;
add)
add_person "$2" "$3" "$4" "$5"
;;
gift)
log_gift "$2" "$3" "$4"
;;
list)
jq '.people[] | {name, relationship, birthday, notes}' "$DATA_FILE"
;;
*)
echo "Usage: $0 [check|add|gift|list]"
echo " check - Run daily birthday check"
echo " add 'Name' 'Relationship' 'MM-DD' 'Notes' - Add new person"
echo " gift 'Name' 'Gift description' [year] - Log a gift given"
echo " list - Show all tracked birthdays"
;;
esac
}
main "$@"