129 lines
4.7 KiB
Python
129 lines
4.7 KiB
Python
from flask import Flask, request, jsonify
|
|
import os
|
|
import sqlite3
|
|
import hashlib
|
|
from superoffice_client import SuperOfficeClient # Our new shiny client class
|
|
|
|
app = Flask(__name__)
|
|
|
|
# --- CONFIGURATION ---
|
|
DB_FILE = "marketing_matrix.db"
|
|
|
|
# UDF ProgIds (from our plan)
|
|
PROG_ID_CONTACT_VERTICAL = "SuperOffice:5"
|
|
PROG_ID_PERSON_ROLE = "SuperOffice:3"
|
|
PROG_ID_CONTACT_CHALLENGE = "SuperOffice:6"
|
|
PROG_ID_PERSON_SUBJECT = "SuperOffice:5"
|
|
PROG_ID_PERSON_INTRO = "SuperOffice:6"
|
|
PROG_ID_PERSON_PROOF = "SuperOffice:7"
|
|
PROG_ID_PERSON_HASH = "SuperOffice:8"
|
|
|
|
# --- CORE LOGIC ---
|
|
def get_text_from_matrix(vertical_id, role_id):
|
|
"""Fetches the pre-generated text block from the local SQLite DB."""
|
|
conn = sqlite3.connect(DB_FILE)
|
|
c = conn.cursor()
|
|
c.execute("SELECT subject, intro, social_proof FROM text_blocks WHERE vertical_id = ? AND role_id = ?", (vertical_id, role_id))
|
|
row = c.fetchone()
|
|
conn.close()
|
|
return row if row else (None, None, None)
|
|
|
|
def process_single_person(client: SuperOfficeClient, person_id: int):
|
|
"""Central logic to update marketing copy for a single person."""
|
|
print(f"Processing Person ID: {person_id}")
|
|
|
|
person_data = client.get_person(person_id)
|
|
if not person_data:
|
|
raise ValueError(f"Person {person_id} not found")
|
|
|
|
contact_id = person_data.get('contact', {}).get('contactId')
|
|
if not contact_id:
|
|
raise ValueError("Person is not linked to a Contact")
|
|
|
|
contact_data = client.get_contact(contact_id)
|
|
if not contact_data:
|
|
raise ValueError(f"Contact {contact_id} not found")
|
|
|
|
# Extract and clean Vertical and Role IDs
|
|
vertical_id_raw = contact_data["UserDefinedFields"].get(PROG_ID_CONTACT_VERTICAL, "")
|
|
role_id_raw = person_data["UserDefinedFields"].get(PROG_ID_PERSON_ROLE, "")
|
|
|
|
if not vertical_id_raw or not role_id_raw:
|
|
raise ValueError("Vertical or Role ID is not set.")
|
|
|
|
vertical_id = int(vertical_id_raw.replace("[I:", "").replace("]", ""))
|
|
role_id = int(role_id_raw.replace("[I:", "").replace("]", ""))
|
|
|
|
# Get text from matrix
|
|
subject, intro, proof = get_text_from_matrix(vertical_id, role_id)
|
|
if not subject:
|
|
raise ValueError(f"No text found in matrix for V:{vertical_id}, R:{role_id}")
|
|
|
|
# Generate Hash
|
|
text_concat = f"{subject}{intro}{proof}"
|
|
copy_hash = hashlib.md5(text_concat.encode()).hexdigest()
|
|
|
|
# Prepare payloads
|
|
contact_payload = {PROG_ID_CONTACT_CHALLENGE: intro}
|
|
person_payload = {
|
|
PROG_ID_PERSON_SUBJECT: subject,
|
|
PROG_ID_PERSON_INTRO: intro,
|
|
PROG_ID_PERSON_PROOF: proof,
|
|
PROG_ID_PERSON_HASH: copy_hash
|
|
}
|
|
|
|
# Inject data
|
|
client.update_udfs("Contact", contact_id, contact_payload)
|
|
client.update_udfs("Person", person_id, person_payload)
|
|
|
|
return f"Updated Person {person_id} with texts for V:{vertical_id}/R:{role_id}"
|
|
|
|
# --- WEBHOOK ENDPOINTS ---
|
|
@app.route('/regenerate_for_person', methods=['POST'])
|
|
def webhook_person():
|
|
data = request.get_json()
|
|
if not data or "person_id" not in data:
|
|
return jsonify({"error": "Missing person_id"}), 400
|
|
|
|
try:
|
|
client = SuperOfficeClient()
|
|
message = process_single_person(client, data['person_id'])
|
|
return jsonify({"status": "success", "message": message}), 200
|
|
except Exception as e:
|
|
print(f"❌ Error processing person: {e}")
|
|
return jsonify({"error": str(e)}), 500
|
|
|
|
@app.route('/regenerate_for_contact', methods=['POST'])
|
|
def webhook_contact():
|
|
data = request.get_json()
|
|
if not data or "contact_id" not in data:
|
|
return jsonify({"error": "Missing contact_id"}), 400
|
|
|
|
contact_id = data['contact_id']
|
|
print(f"Received request to regenerate for all persons in Contact ID: {contact_id}")
|
|
|
|
try:
|
|
client = SuperOfficeClient()
|
|
contact = client.get_contact(contact_id)
|
|
if not contact or not contact.get('persons'):
|
|
return jsonify({"status": "success", "message": "No persons found for this contact."}), 200
|
|
|
|
updated_count = 0
|
|
for person_summary in contact['persons']:
|
|
try:
|
|
process_single_person(client, person_summary['personId'])
|
|
updated_count += 1
|
|
except Exception as e:
|
|
print(f" - Skipping Person {person_summary.get('personId')}: {e}")
|
|
|
|
return jsonify({"status": "success", "message": f"Processed {updated_count} persons for Contact {contact_id}"}), 200
|
|
|
|
except Exception as e:
|
|
print(f"❌ Error processing contact: {e}")
|
|
return jsonify({"error": str(e)}), 500
|
|
|
|
if __name__ == '__main__':
|
|
# For local dev. Use a proper WSGI server (Gunicorn) for production.
|
|
# Needs pip install Flask
|
|
app.run(host='0.0.0.0', port=5001, debug=True)
|