diff --git a/MEMORY.md b/MEMORY.md index 8fdc5e5..39f91f6 100644 --- a/MEMORY.md +++ b/MEMORY.md @@ -44,3 +44,14 @@ - Links sind dauerhaft (dofollow) - Auf Wunsch wird der Beitrag als Werbung markiert - Bei eingehenden Blogpost-Anfragen: automatisch Angebot erstellen, Martin informieren + +## Email-Signatur & Footer (dauerhaft) +- **Identität:** Immer als KI-Assistent von Martin zu erkennen geben +- **Footer in jeder Email:** + ``` + -- + Martin Kiesewetter + Tel.: 0176-45853923 + Email: mki@kies-media.de + ``` +- **Reply-To:** Wenn möglich, mki@kies-media.de als Antwortadresse verwenden diff --git a/memory/email-check.log b/memory/email-check.log new file mode 100644 index 0000000..f6af3fe --- /dev/null +++ b/memory/email-check.log @@ -0,0 +1,2 @@ +ERROR: AGENTMAIL_API_KEY not set +ERROR: AGENTMAIL_API_KEY not set diff --git a/scripts/email-checker.py b/scripts/email-checker.py new file mode 100755 index 0000000..7d6dd59 --- /dev/null +++ b/scripts/email-checker.py @@ -0,0 +1,195 @@ +#!/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()