Files

153 lines
5.6 KiB
Python

import sqlite3
import os
import json
import requests
from dotenv import load_dotenv
load_dotenv(override=True)
DB_FILE = "marketing_matrix.db"
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
NOTION_API_KEY = os.getenv("NOTION_API_KEY")
NOTION_DB_INDUSTRIES = "2ec88f4285448014ab38ea664b4c2b81"
# --- MAPPINGS ---
# SuperOffice ID -> Notion Vertical Name
VERTICAL_MAP = {
23: "Logistics - Warehouse"
}
# SuperOffice ID -> Persona Name & Pains (aus unserer Definition)
ROLE_MAP = {
19: {"name": "Operativer Entscheider", "pains": "Zuverlässigkeit, einfache Bedienbarkeit, Personaleinsatz-Optimierung, minimale Störungen"},
20: {"name": "Infrastruktur-Verantwortlicher", "pains": "Technische Machbarkeit, IT-Sicherheit, Integration, Brandschutz"},
21: {"name": "Wirtschaftlicher Entscheider", "pains": "ROI, Amortisationszeit, Kostenstruktur, Einsparpotenziale"},
22: {"name": "Innovations-Treiber", "pains": "Wettbewerbsfähigkeit, Modernisierung, Employer Branding, Kundenerlebnis"}
}
# --- DATABASE SETUP ---
def init_db():
conn = sqlite3.connect(DB_FILE)
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS text_blocks
(vertical_id INTEGER, role_id INTEGER,
subject TEXT, intro TEXT, social_proof TEXT,
PRIMARY KEY (vertical_id, role_id))''')
conn.commit()
conn.close()
print("✅ Database initialized.")
# --- NOTION FETCHER ---
def get_vertical_pains_gains(vertical_name):
url = f"https://api.notion.com/v1/databases/{NOTION_DB_INDUSTRIES}/query"
headers = {
"Authorization": f"Bearer {NOTION_API_KEY}",
"Notion-Version": "2022-06-28",
"Content-Type": "application/json"
}
payload = {
"filter": {
"property": "Vertical",
"title": {"contains": vertical_name}
}
}
resp = requests.post(url, headers=headers, json=payload)
if resp.status_code == 200:
results = resp.json().get("results", [])
if results:
props = results[0]['properties']
pains = props.get('Pains', {}).get('rich_text', [])
gains = props.get('Gains', {}).get('rich_text', [])
return {
"pains": pains[0]['plain_text'] if pains else "",
"gains": gains[0]['plain_text'] if gains else ""
}
print(f"⚠️ Warning: No data found for {vertical_name}")
return {"pains": "N/A", "gains": "N/A"}
# --- GEMINI GENERATOR ---
def generate_text(vertical_name, v_data, role_id, role_data):
url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key={GEMINI_API_KEY}"
prompt = f"""
Du bist ein B2B-Copywriter. Erstelle 3 Textbausteine für eine Cold-Outreach E-Mail.
KONTEXT:
Branche: {vertical_name}
Branchen-Pains: {v_data['pains']}
Lösung-Gains: {v_data['gains']}
Rolle: {role_data['name']}
Rollen-Pains: {role_data['pains']}
AUFGABE:
1. Subject: Betreffzeile (max 40 Zeichen!). Knackig, Pain-bezogen.
2. Intro: Einleitungssatz (max 40 Zeichen!). Brücke Pain -> Lösung.
3. SocialProof: Referenzsatz (max 40 Zeichen!). "Wir arbeiten mit X..."
FORMAT (JSON):
{{ "Subject": "...", "Intro": "...", "SocialProof": "..." }}
"""
payload = {
"contents": [{"parts": [{"text": prompt}]}],
"generationConfig": {"responseMimeType": "application/json"}
}
try:
resp = requests.post(url, json=payload)
if resp.status_code == 200:
return json.loads(resp.json()['candidates'][0]['content']['parts'][0]['text'])
except Exception as e:
print(f"Gemini Error: {e}")
return None
# --- MAIN ---
def run_matrix():
init_db()
conn = sqlite3.connect(DB_FILE)
c = conn.cursor()
# Iterate Verticals
for v_id, v_name in VERTICAL_MAP.items():
print(f"\nProcessing Vertical: {v_name} (ID: {v_id})")
v_data = get_vertical_pains_gains(v_name)
# Iterate Roles
for r_id, r_data in ROLE_MAP.items():
print(f" > Generating for Role: {r_data['name']} (ID: {r_id})...", end="", flush=True)
# Check if exists (optional: skip if exists)
# ...
text_block = generate_text(v_name, v_data, r_id, r_data)
if text_block:
# Robustness: Handle list return from Gemini
if isinstance(text_block, list):
if len(text_block) > 0 and isinstance(text_block[0], dict):
text_block = text_block[0] # Take first item if list of dicts
else:
print(" ❌ Failed (Unexpected JSON format: List without dicts).")
continue
# Cut to 40 chars hard limit (Safety)
subj = text_block.get("Subject", "")[:40]
intro = text_block.get("Intro", "Intro")[:40] # Fallback key name check
if "Introduction_Textonly" in text_block: intro = text_block["Introduction_Textonly"][:40]
proof = text_block.get("SocialProof", "")[:40]
if "Industry_References_Textonly" in text_block: proof = text_block["Industry_References_Textonly"][:40]
c.execute("INSERT OR REPLACE INTO text_blocks VALUES (?, ?, ?, ?, ?)",
(v_id, r_id, subj, intro, proof))
conn.commit()
print(" ✅ Done.")
else:
print(" ❌ Failed.")
conn.close()
print("\nMatrix generation complete.")
if __name__ == "__main__":
run_matrix()