import os import json import requests import sqlite3 import re # Load API Key def get_gemini_key(): candidates = [ "gemini_api_key.txt", # Current dir "/app/gemini_api_key.txt", # Docker default os.path.join(os.path.dirname(__file__), "gemini_api_key.txt"), # Script dir os.path.join(os.path.dirname(os.path.dirname(__file__)), 'gemini_api_key.txt') # Parent dir ] for path in candidates: if os.path.exists(path): try: with open(path, 'r') as f: return f.read().strip() except: pass return os.getenv("GEMINI_API_KEY") def get_matrix_context(industry_name, persona_name): """Fetches Pains, Gains and Arguments from CE Database.""" context = { "industry_pains": "", "industry_gains": "", "persona_description": "", "persona_arguments": "" } db_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'companies_v3_fixed_2.db') if not os.path.exists(db_path): return context try: conn = sqlite3.connect(db_path) c = conn.cursor() # Get Industry Data c.execute('SELECT pains, gains FROM industries WHERE name = ?', (industry_name,)) ind_res = c.fetchone() if ind_res: context["industry_pains"], context["industry_gains"] = ind_res # Get Persona Data c.execute('SELECT description, convincing_arguments FROM personas WHERE name = ?', (persona_name,)) per_res = c.fetchone() if per_res: context["persona_description"], context["persona_arguments"] = per_res conn.close() except Exception as e: print(f"DB Error in matrix lookup: {e}") return context def get_product_recommendation(area_str): """ Selects the right robot based on the surface area mentioned in the lead. """ # Naive extraction of first number in the string nums = re.findall(r'\d+', area_str.replace('.', '').replace(',', '')) area_val = int(nums[0]) if nums else 0 if area_val >= 5000 or "über 10.000" in area_str: return { "name": "Scrubber 75", "reason": "als industrielles Kraftpaket für Großflächen ausgelegt", "usp": "höchste Effizienz und Autonomie auf mehreren tausend Quadratmetern" } elif area_val >= 1000: return { "name": "Scrubber 50 oder Phantas", "reason": "die optimale Balance zwischen Reinigungsleistung und Wendigkeit", "usp": "ideal für mittelgroße Fertigungs- und Lagerbereiche" } else: return { "name": "Phantas oder Pudu CC1", "reason": "kompakt und wendig für komplexe Umgebungen", "usp": "perfekt für Büros, Praxen oder engere Verkehrswege" } def generate_email_draft(lead_data, company_data, booking_link="[IHR BUCHUNGSLINK - BITTE IN .ENV EINTRAGEN]"): """ Generates a high-end, personalized sales email using Gemini API and Matrix knowledge. """ api_key = get_gemini_key() if not api_key: return "Error: Gemini API Key not found." # Extract Data from Lead Engine company_name = lead_data.get('company_name', 'Interessent') contact_name = lead_data.get('contact_name', 'Damen und Herren') # Metadata from Lead meta = {} if lead_data.get('lead_metadata'): try: meta = json.loads(lead_data['lead_metadata']) except: pass area = meta.get('area', 'Unbekannte Fläche') purpose = meta.get('purpose', 'Reinigung') role = meta.get('role', 'Wirtschaftlicher Entscheider') # Data from Company Explorer ce_summary = company_data.get('research_dossier') or company_data.get('summary', '') ce_vertical = company_data.get('industry_ai') or company_data.get('vertical', 'Industry - Manufacturing') ce_opener = company_data.get('ai_opener', '') # Product logic product = get_product_recommendation(area) # Fetch "Golden Records" from Matrix matrix = get_matrix_context(ce_vertical, role) # Prompt Engineering for "Unwiderstehliche E-Mail" prompt = f""" Du bist ein Senior Sales Executive bei Robo-Planet. Antworte auf eine Anfrage von Tradingtwins. Schreibe eine E-Mail auf "Human Expert Level". WICHTIGE STRATEGIE: - Starte NICHT mit seiner Position (CFO). Starte mit der Wertschätzung für sein UNTERNEHMEN ({company_name}). - Der Empfänger soll durch die Tiefe der Argumente MERKEN, dass wir für einen Entscheider schreiben. - Mappe ihn erst später als "finanziellen/wirtschaftlichen Entscheider". - Erwähne eine ROI-Perspektive (Amortisation). KONTEXT (Vom Company Explorer): - Firma: {company_name} - Branche: {ce_vertical} - Branchen-Pains (Nutze diese für die Argumentation): {matrix['industry_pains']} - Branchen-Gains: {matrix['industry_gains']} - Dossier/Business-Profil: {ce_summary} - Strategischer Aufhänger: {ce_opener} ANSPRECHPARTNER: - Name: {contact_name} - Rolle: {role} PRODUKT-EMPFEHLUNG (Basierend auf Fläche {area}): - Modell: {product['name']} - Warum: {product['reason']} - USP: {product['usp']} ANFRAGE-DETAILS: - Bedarf: {area} - Zweck: {purpose} AUFGABE: Schreibe eine E-Mail mit dieser Struktur: 1. EINSTIEG: Fokus auf Klemm Bohrtechnik und deren Marktstellung/Produkte (Bezug auf den 'Strategischen Aufhänger'). 2. DIE BRÜCKE: Verknüpfe die Präzision ihrer Produkte mit der Notwendigkeit von sauberen Hallenböden (besonders bei {area}). Nutze den Schmerzpunkt "Prozesssicherheit/Sensorik". 3. DIE LÖSUNG: Positioniere den {product['name']} als genau die richtige Wahl für diese Größenordnung ({area}). 4. ROI-LOGIK: Sprich ihn als wirtschaftlichen Entscheider an. Erwähne, dass wir für solche Projekte ROI-Kalkulationen erstellen, die oft eine Amortisation in unter 18-24 Monaten zeigen. 5. CALL TO ACTION: Beratungsgespräch + Buchungslink: {booking_link} STIL: Senior, Augenhöhe, keine Floskeln, extrem fokussiert auf Effizienz und Qualität. FORMAT: Betreff: [Relevanter Betreff, der direkt auf Klemm Bohrtechnik / Effizienz zielt] [E-Mail Text] """ # Call Gemini API url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key={api_key}" headers = {'Content-Type': 'application/json'} payload = {"contents": [{"parts": [{"text": prompt}]}]} try: response = requests.post(url, headers=headers, json=payload) response.raise_for_status() result = response.json() return result['candidates'][0]['content']['parts'][0]['text'] except Exception as e: return f"Error generating draft: {str(e)}" if __name__ == "__main__": # Test Mock mock_lead = { "company_name": "Klinikum Test", "contact_name": "Dr. Müller", "lead_metadata": json.dumps({"area": "5000 qm", "purpose": "Desinfektion und Boden", "city": "Berlin"}) } mock_company = { "vertical": "Healthcare / Krankenhaus", "summary": "Ein großes Klinikum der Maximalversorgung mit Fokus auf Kardiologie." } print(generate_email_draft(mock_lead, mock_company))