Add three new automations: FreshRSS digest, birthday tracker, home stack monitor
- FreshRSS Smart Digest: Daily AI-ranked RSS summary at 7 AM - Birthday Tracker: Smart reminders for family birthdays with gift suggestions - Home Stack Monitor: Health checks every 15 min with self-healing attempts All cron jobs configured and ready to run. Telegram bot token saved to .env
This commit is contained in:
207
automations/freshrss-digest/daily-digest.sh
Executable file
207
automations/freshrss-digest/daily-digest.sh
Executable file
@@ -0,0 +1,207 @@
|
||||
#!/bin/bash
|
||||
# FreshRSS Smart Digest
|
||||
# Pulls unread articles, ranks them by relevance, delivers categorized summary
|
||||
# Runs daily at 7:00 AM (before AI newsletter digest)
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/../../.env" 2>/dev/null || true
|
||||
|
||||
# Config
|
||||
FRESHRSS_URL="${FRESHRSS_URL:-http://freshrss.kangaroo-eel.ts.net}"
|
||||
FRESHRSS_USER="${FRESHRSS_USER:-anthony}"
|
||||
TELEGRAM_CHAT="${TELEGRAM_CHAT:-1793951355}"
|
||||
|
||||
# Your interest keywords for relevance ranking
|
||||
INTERESTS=(
|
||||
"AI" "artificial intelligence" "machine learning" "LLM"
|
||||
"renewable energy" "solar" "wind" "battery" "EV" "electric vehicle"
|
||||
"politics" "Labor" "election" "government"
|
||||
"LGBTQ" "LGBT" "queer" "transgender"
|
||||
"Perth" "Western Australia" "WA"
|
||||
"climate" "environment"
|
||||
"mental health" "depression" "therapy"
|
||||
)
|
||||
|
||||
# Priority sources (always include these)
|
||||
PRIORITY_SOURCES=(
|
||||
"CNN"
|
||||
"MSNBC"
|
||||
"Al Jazeera"
|
||||
"ABC News"
|
||||
"The Guardian"
|
||||
"BlueSky"
|
||||
)
|
||||
|
||||
log() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
|
||||
}
|
||||
|
||||
fetch_unread() {
|
||||
log "Fetching unread articles from FreshRSS..."
|
||||
|
||||
local raw_output
|
||||
raw_output=$(/home/openclaw/.openclaw/workspace/skills/freshrss-reader/scripts/freshrss.sh headlines \
|
||||
--unread --count 50 2>/dev/null) || {
|
||||
log "ERROR: Failed to fetch from FreshRSS"
|
||||
return 1
|
||||
}
|
||||
|
||||
echo "$raw_output"
|
||||
}
|
||||
|
||||
# Score an article based on interest keywords
|
||||
score_article() {
|
||||
local title="$1"
|
||||
local source="$2"
|
||||
local categories="$3"
|
||||
local score=0
|
||||
local text="${title,,} ${categories,,}"
|
||||
|
||||
# Check interest keywords
|
||||
for interest in "${INTERESTS[@]}"; do
|
||||
if [[ "$text" == *"${interest,,}"* ]]; then
|
||||
((score+=2))
|
||||
fi
|
||||
done
|
||||
|
||||
# Priority sources get a boost
|
||||
for priority in "${PRIORITY_SOURCES[@]}"; do
|
||||
if [[ "$source" == *"$priority"* ]]; then
|
||||
((score+=3))
|
||||
fi
|
||||
done
|
||||
|
||||
echo "$score"
|
||||
}
|
||||
|
||||
# Parse articles and build digest
|
||||
build_digest() {
|
||||
local raw="$1"
|
||||
local output=""
|
||||
local must_read=""
|
||||
local skimmable=""
|
||||
local total_count=0
|
||||
|
||||
# Parse the output - each article is 3 lines: date/source/title, URL, categories
|
||||
local current_date=""
|
||||
local current_source=""
|
||||
local current_title=""
|
||||
local current_url=""
|
||||
local current_cats=""
|
||||
|
||||
while IFS= read -r line; do
|
||||
# Skip empty lines
|
||||
[[ -z "$line" ]] && continue
|
||||
|
||||
# Check if this is a title line (starts with [)
|
||||
if [[ "$line" =~ ^\[.*\].*:.*$ ]]; then
|
||||
# Save previous article if exists
|
||||
if [[ -n "$current_title" ]]; then
|
||||
local score
|
||||
score=$(score_article "$current_title" "$current_source" "$current_cats")
|
||||
|
||||
local article_formatted="• *${current_source}*: ${current_title}\n ${current_url}\n"
|
||||
|
||||
if ((score >= 5)); then
|
||||
must_read+="$article_formatted\n"
|
||||
elif ((score >= 2)); then
|
||||
skimmable+="$article_formatted\n"
|
||||
fi
|
||||
|
||||
((total_count++))
|
||||
fi
|
||||
|
||||
# Parse new article
|
||||
current_date=$(echo "$line" | sed 's/^\[\([^]]*\)\].*/\1/')
|
||||
current_source=$(echo "$line" | sed 's/^\[[^]]*\] \([^:]*\):.*/\1/')
|
||||
current_title=$(echo "$line" | sed 's/^\[[^]]*\] [^:]*: //')
|
||||
current_url=""
|
||||
current_cats=""
|
||||
|
||||
# Check if this is a URL line
|
||||
elif [[ "$line" =~ ^https?:// ]]; then
|
||||
current_url="$line"
|
||||
|
||||
# Check if this is categories line
|
||||
elif [[ "$line" =~ ^Categories:\ ]]; then
|
||||
current_cats=$(echo "$line" | sed 's/Categories: //')
|
||||
fi
|
||||
done <<< "$raw"
|
||||
|
||||
# Don't forget the last article
|
||||
if [[ -n "$current_title" ]]; then
|
||||
local score
|
||||
score=$(score_article "$current_title" "$current_source" "$current_cats")
|
||||
|
||||
local article_formatted="• *${current_source}*: ${current_title}\n ${current_url}\n"
|
||||
|
||||
if ((score >= 5)); then
|
||||
must_read+="$article_formatted\n"
|
||||
elif ((score >= 2)); then
|
||||
skimmable+="$article_formatted\n"
|
||||
fi
|
||||
|
||||
((total_count++))
|
||||
fi
|
||||
|
||||
# Build final message
|
||||
output="📰 *FreshRSS Daily Digest*\n\n"
|
||||
output+="Found *$total_count* unread articles.\n\n"
|
||||
|
||||
if [[ -n "$must_read" ]]; then
|
||||
output+="🔥 *Must Read*\n$must_read\n"
|
||||
fi
|
||||
|
||||
if [[ -n "$skimmable" ]]; then
|
||||
output+="📎 *Skimmable*\n$skimmable\n"
|
||||
fi
|
||||
|
||||
if [[ -z "$must_read" && -z "$skimmable" ]]; then
|
||||
output+="No high-priority articles today. You're caught up! 🎉\n"
|
||||
fi
|
||||
|
||||
output+="\n📖 [Open FreshRSS]($FRESHRSS_URL)"
|
||||
|
||||
echo -e "$output"
|
||||
}
|
||||
|
||||
send_telegram() {
|
||||
local message="$1"
|
||||
|
||||
log "Sending to Telegram..."
|
||||
|
||||
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\",
|
||||
\"disable_web_page_preview\": true
|
||||
}" > /dev/null || {
|
||||
log "ERROR: Failed to send Telegram message"
|
||||
return 1
|
||||
}
|
||||
|
||||
log "Sent to Telegram successfully"
|
||||
}
|
||||
|
||||
main() {
|
||||
log "Starting FreshRSS digest..."
|
||||
|
||||
# Fetch articles
|
||||
local raw_articles
|
||||
raw_articles=$(fetch_unread) || exit 1
|
||||
|
||||
# Build digest
|
||||
local digest
|
||||
digest=$(build_digest "$raw_articles")
|
||||
|
||||
# Send
|
||||
send_telegram "$digest"
|
||||
|
||||
log "Digest complete!"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user