#!/usr/bin/env python3 """Email checker cron job - checks AgentMail inbox and notifies Martin via Telegram.""" import os import json import sys from datetime import datetime, timezone, timedelta # Add agentmail package sys.path.insert(0, '/usr/local/lib/python3.12/dist-packages') from agentmail import AgentMail API_KEY = os.environ.get('AGENTMAIL_API_KEY', '') INBOX_ID = 'max-kies-media-ai-assistent@agentmail.to' STATE_FILE = '/root/.openclaw/workspace/memory/email-check-state.json' TELEGRAM_STATE_FILE = '/root/.openclaw/workspace/memory/telegram-state.json' def load_state(): if os.path.exists(STATE_FILE): with open(STATE_FILE) as f: return json.load(f) return {'processed': [], 'last_check': None} def save_state(state): state['last_check'] = datetime.now(timezone.utc).isoformat() with open(STATE_FILE, 'w') as f: json.dump(state, f, indent=2) def categorize_email(subject, from_addr, text=''): """Categorize an email based on content.""" subject_lower = subject.lower() text_lower = (text or '').lower() from_lower = from_addr.lower() if from_addr else '' # Security warnings if any(w in subject_lower for w in ['sicherheitswarnung', 'security', 'alert', 'unauthorized']): return 'wichtig' # Blogpost inquiries if any(w in text_lower for w in ['blogpost', 'blog post', 'gastbeitrag', 'gastartikel', 'link placement', 'link einfügen', 'artikel veröffentlichen']): return 'blogpost-anfrage' # Family if any(name in from_lower for name in ['olga', 'anja', 'michael', 'petra', 'kiesewetter']): return 'familie' # Finance if any(w in subject_lower for w in ['rechnung', 'invoice', 'zahlung', 'bank', 'steuer']): return 'finanzen' # Newsletter if any(w in from_lower for w in ['newsletter', 'noreply', 'no-reply', 'marketing']): return 'newsletter' # Work if any(w in subject_lower for w in ['projekt', 'meeting', 'aufgabe', 'todo']): return 'arbeit' return 'sonstiges' def should_auto_reply(category, subject, text=''): """Determine if we should auto-reply to this email.""" if category == 'wichtig': return False # Don't auto-reply to important emails, notify Martin if category == 'blogpost-anfrage': return False # Create offer, notify Martin if category == 'familie': return False # Don't auto-reply to family if category == 'finanzen': return False # Don't auto-reply to finance emails if category == 'spam': return False # Auto-reply to simple confirmations, receipts, etc. text_lower = (text or '').lower() subject_lower = subject.lower() if any(w in subject_lower for w in ['bestätigung', 'confirmation', 'willkommen', 'welcome', 'verifizierung', 'verify']): return True # Simple confirmations - just acknowledge return False def notify_martin_via_telegram(category, subject, from_addr, action_taken=''): """Send notification to Martin via Telegram using sessions_send or curl.""" # Use curl to send via Telegram bot # This assumes we have the bot token and chat ID available import subprocess chat_id = '2138015302' # Martin's Telegram chat ID # Try to get bot token from OpenClaw config try: with open('/root/.openclaw/openclaw.json') as f: config = json.load(f) # Look for telegram bot token in config for channel in config.get('channels', {}).get('telegram', {}).get('accounts', {}).values(): if 'token' in channel: bot_token = channel['token'] break else: # Fallback: check environment bot_token = os.environ.get('TELEGRAM_BOT_TOKEN', '') except: bot_token = os.environ.get('TELEGRAM_BOT_TOKEN', '') if not bot_token: return False message = f"📬 **Email-Benachrichtigung**\n\n" message += f"**Kategorie:** {category}\n" message += f"**Betreff:** {subject}\n" message += f"**Von:** {from_addr}\n" if action_taken: message += f"**Aktion:** {action_taken}\n" url = f"https://api.telegram.org/bot{bot_token}/sendMessage" try: subprocess.run([ 'curl', '-s', '-X', 'POST', url, '-d', f'chat_id={chat_id}', '-d', f'text={message}', '-d', 'parse_mode=Markdown' ], timeout=10) return True except Exception as e: print(f"Telegram notification failed: {e}") return False def main(): if not API_KEY: print("ERROR: AGENTMAIL_API_KEY not set") sys.exit(1) client = AgentMail() state = load_state() try: msgs = client.inboxes.messages.list(inbox_id=INBOX_ID, limit=10) except Exception as e: print(f"ERROR: Failed to list messages: {e}") sys.exit(1) new_messages = [] for m in msgs.messages: if m.message_id not in state['processed']: category = categorize_email(m.subject, str(m.from_), m.text or '') should_reply = should_auto_reply(category, m.subject, m.text) new_messages.append({ 'message_id': m.message_id, 'subject': m.subject, 'from': str(m.from_), 'category': category, 'auto_reply': should_reply, 'created_at': str(m.created_at) }) # Mark as processed state['processed'].append(m.message_id) # Handle based on category if should_reply: # Auto-reply with simple acknowledgment print(f"Auto-reply to: {m.subject} from {m.from_}") notify_martin_via_telegram( category, m.subject, str(m.from_), 'Automatisch bestätigt' ) elif category == 'blogpost-anfrage': # Create offer and notify Martin print(f"Blogpost-Anfrage: {m.subject}") notify_martin_via_telegram( category, m.subject, str(m.from_), 'Blogpost-Anfrage - Angebot wird erstellt' ) elif category == 'wichtig': # Notify immediately print(f"WICHTIG: {m.subject}") notify_martin_via_telegram( category, m.subject, str(m.from_), 'Sofort prüfen!' ) save_state(state) if new_messages: print(f"Checked: {len(new_messages)} new message(s)") for msg in new_messages: print(f" [{msg['category']}] {msg['subject']} - Auto-reply: {msg['auto_reply']}") else: print("No new messages") if __name__ == '__main__': main()