#!/bin/bash # Smart Newsletter Digest with Feedback Learning set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" IMAP_SKILL="/home/openclaw/.openclaw/workspace/skills/imap-smtp-email" source "$SCRIPT_DIR/../../.env" 2>/dev/null || true source "$IMAP_SKILL/.env" 2>/dev/null || true TELEGRAM_CHAT="${TELEGRAM_CHAT:-1793951355}" NTFY_URL="${NTFY_URL:-}" NTFY_TOPIC="${NTFY_TOPIC:-}" NTFY_MIN_PRIORITY="${NTFY_MIN_PRIORITY:-4}" PREFERENCES_FILE="$SCRIPT_DIR/newsletter-preferences.json" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" } init_preferences() { if [[ ! -f "$PREFERENCES_FILE" ]]; then cat > "$PREFERENCES_FILE" << 'EOF' { "liked_topics": ["AI", "machine learning", "productivity", "automation"], "disliked_topics": [], "preferred_sources": [], "avoided_sources": [], "feedback_count": 0 } EOF fi } fetch_and_build_digest() { cd "$IMAP_SKILL" python3 << 'PYEOF' import subprocess import re import json from datetime import datetime # Fetch emails result = subprocess.run( ['python3', 'scripts/imap-py.py', 'check', '--limit', '50', '--recent', '24h'], capture_output=True, text=True ) output = result.stdout # Parse emails newsletters = [] current = {} patterns = ['aivalley', 'deepview', 'rundown', 'tldr', 'benedict', 'newsletter', 'digest', 'daily', 'weekly', 'briefing'] for line in output.split('\n'): line = line.strip() if line.startswith('● UID:'): if current.get('uid'): newsletters.append(current) current = {'uid': line.split(':')[1].strip()} elif line.startswith('From:'): current['from'] = line.replace('From:', '').strip() elif line.startswith('Subject:'): current['subject'] = line.replace('Subject:', '').strip() elif line.startswith('Date:'): current['date'] = line.replace('Date:', '').strip() if current.get('uid'): newsletters.append(current) # Filter for newsletters filtered = [] for email in newsletters: sender = email.get('from', '').lower() subject = email.get('subject', '').lower() for p in patterns: if p in sender or p in subject: filtered.append(email) break # Load preferences try: with open('/home/openclaw/.openclaw/workspace/automations/newsletter-digest/newsletter-preferences.json') as f: prefs = json.load(f) except: prefs = {'liked_topics': [], 'disliked_topics': [], 'preferred_sources': []} # Score for nl in filtered: score = 0 subject = nl.get('subject', '').lower() sender = nl.get('from', '').lower() for topic in prefs.get('liked_topics', []): if topic.lower() in subject: score += 2 for topic in prefs.get('disliked_topics', []): if topic.lower() in subject: score -= 2 for src in prefs.get('preferred_sources', []): if src.lower() in sender: score += 3 nl['score'] = score filtered.sort(key=lambda x: x.get('score', 0), reverse=True) # Build message lines = [] lines.append("📬 *Newsletter Digest*") lines.append(f"_({datetime.now().strftime('%B %d, %Y')})_") lines.append("") lines.append(f"Found *{len(filtered)}* newsletters in past 24h") lines.append("") for nl in filtered[:8]: score = nl.get('score', 0) emoji = "🔥" if score >= 3 else "📌" if score > 0 else "📄" subject = nl.get('subject', 'No subject')[:70] sender = nl.get('from', 'Unknown')[:35] lines.append(f"{emoji} *{subject}*") lines.append(f" _{sender}_") lines.append("") if not filtered: lines.append("No newsletters found! 📭") lines.append("━━━━━━━━━━━━━━━━") lines.append("💭 Reply: 👍/👎 or `more X`/`less X`") print('\n'.join(lines)) PYEOF } 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\", \"disable_web_page_preview\": true}" > /dev/null } send_ntfy() { local title="$1" local msg="$2" local priority="${3:-4}" local sound="${4:-default}" [[ -z "$NTFY_URL" ]] && return 0 [[ -z "$NTFY_TOPIC" ]] && return 0 # Enforce minimum priority (default 4) if [[ "$priority" =~ ^[0-9]+$ ]] && [[ "$NTFY_MIN_PRIORITY" =~ ^[0-9]+$ ]]; then if (( priority < NTFY_MIN_PRIORITY )); then priority="$NTFY_MIN_PRIORITY" fi fi curl -s -X POST "${NTFY_URL}/$NTFY_TOPIC" \ -H "Title: $title" \ -H "Priority: $priority" \ -H "Sound: $sound" \ -d "$msg" > /dev/null 2>&1 || true } main() { log "Starting newsletter digest..." init_preferences local digest digest=$(fetch_and_build_digest) send_telegram "$digest" send_ntfy "🦀 Newsletter digest" "Digest sent to Telegram" 4 default log "Done!" } main "$@"