import requests import smtplib from email.mime.text import MIMEText # --- Environment settings --- TWENTY_API_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJmY2UyYjc4OS1iY2Y4LTQzMjAtYjEyZS0yMjUyZDZkNzhlZjUiLCJ0eXBlIjoiQVBJX0tFWSIsIndvcmtzcGFjZUlkIjoiZmNlMmI3ODktYmNmOC00MzIwLWIxMmUtMjI1MmQ2ZDc4ZWY1IiwiaWF0IjoxNzUwODU4OTI4LCJleHAiOjQ5MDQ0NTg5MjcsImp0aSI6ImNiOTcxMjEyLWExYjAtNGU5NS1hYjI5LWU3YjdiN2E4YWUwMyJ9.mujCJqNnnk0xcQ0VP8m9uLzzXDtjH9AGi0RF2I8VXHA" TWENTY_API = "https://crm.toothfairyai.com/rest" ZAMMAD_URL = "https://zammad.toothfairyai.com" ZAMMAD_TOKEN = "Ljej6w4vyEp4P4ES95Fi8bxL4Yj6h1G5y7SXMnWnx-EFKDPE6q3wkMdWXSKHy062" ZAMMAD_GROUP = "Users" SMTP_SERVER = "" SMTP_PORT = "" SMTP_USERNAME = "" SMTP_PASSWORD = "" CUSTOMER_REPLY_SUBJECT = "Thanks for contacting ToothFairyAI" SALES_EMAIL = "daniel.grozdanovic@icloud.com" SUPPORT_EMAIL = "support@yourcompany.com" # --- Debug print --- print("→ ZAMMAD_TOKEN:", repr(ZAMMAD_TOKEN)) print("→ ZAMMAD_URL: ", repr(ZAMMAD_URL)) print("→ TWENTY_API_KEY:", repr(TWENTY_API_KEY)) me = requests.get( f"{ZAMMAD_URL}/api/v1/users/me", headers={"Authorization": f"Token token={ZAMMAD_TOKEN}"} ) print("→ GET /users/me:", me.status_code, me.text) def is_business_opportunity(text): keywords = ["partner", "quote", "enterprise", "demo", "pricing", "ai", "onboarding"] return any(word in text.lower() for word in keywords) def push_to_twenty(submission): url = f"{TWENTY_API}/people" headers = { "Authorization": f"Bearer {TWENTY_API_KEY}", "Content-Type": "application/json" } payload = { "name": { "firstName": submission["first_name"], "lastName": submission["last_name"] }, "position": "first", "emails": { "primaryEmail": submission["email"], "additionalEmails": [] } } res = requests.post(url, headers=headers, json=payload) if res.status_code not in (200, 201): print("→ TwentyCRM error:", res.status_code, res.text) res.raise_for_status() return res.json()["data"]["createPerson"]["id"] def create_zammad_ticket(submission, is_lead): url = f"{ZAMMAD_URL}/api/v1/tickets" headers = { "Authorization": f"Token token={ZAMMAD_TOKEN}", "Content-Type": "application/json" } name = f"{submission['first_name']} {submission['last_name']}" ticket_title = f"{'Sales' if is_lead else 'Other'}: {name}" customer = submission["email"] if is_lead: article = { "to": SALES_EMAIL, "subject": ticket_title, "body": f"Name: {name}\nEmail: {customer}\n\nMessage:\n{submission['message']}", "note": submission["message"], "type": "email", "internal": False } else: article = { "subject": ticket_title, "body": submission["message"], "note": submission["message"], "type": "note", "internal": False } payload = { "title": ticket_title, "customer": customer, "group": ZAMMAD_GROUP, "article": article } res = requests.post(url, headers=headers, json=payload) if res.status_code not in (200, 201): print("→ Zammad create-ticket ERROR:", res.status_code, res.text) print("→ Payload was:", payload) res.raise_for_status() return res.json() def tag_zammad_ticket(ticket_id, tag): url = f"{ZAMMAD_URL}/api/v1/tickets/{ticket_id}" headers = { "Authorization": f"Token token={ZAMMAD_TOKEN}", "Content-Type": "application/json" } res = requests.put(url, headers=headers, json={"tags": [tag]}) if res.status_code not in (200, 201): print("→ Zammad tag-ticket ERROR:", res.status_code, res.text) res.raise_for_status() return res.json() def send_email(to, subject, body): if not SMTP_SERVER or not SMTP_PORT: print(f"[Mock email sent] → {to}\nSubject: {subject}\n\n{body}\n") return try: msg = MIMEText(body) msg["From"] = SMTP_USERNAME msg["To"] = to msg["Subject"] = subject with smtplib.SMTP(SMTP_SERVER, int(SMTP_PORT)) as server: server.starttls() server.login(SMTP_USERNAME, SMTP_PASSWORD) server.send_message(msg) print(f"[Real email sent] → {to}") except Exception as e: print(f"[Email error] → {e}") def process_submission(submission): is_lead = is_business_opportunity(submission["message"]) crm_id = push_to_twenty(submission) tag = "sales" if is_lead else "other" name = f"{submission['first_name']} {submission['last_name']}" ticket = create_zammad_ticket(submission, is_lead) tag_zammad_ticket(ticket["id"], tag) # 1. Confirmation to customer send_email( to=submission["email"], subject=CUSTOMER_REPLY_SUBJECT, body=( f"Hi {submission['first_name']},\n\n" f"Your ticket “{ticket['title']}” (ID #{ticket['id']}) is in our system—" "we'll be in touch soon.\n\nCheers,\nThe ToothFairyAI Team" ) ) # 2. Internal notification internal_to = SALES_EMAIL if is_lead else SUPPORT_EMAIL internal_subj = "🚀 New Business Lead" if is_lead else "ℹ️ New Inquiry" send_email( to=internal_to, subject=internal_subj, body=( f"CRM ID: {crm_id}\n" f"Zammad Ticket: #{ticket['id']} (Title: {ticket['title']}, Tags: {tag})\n" f"Name: {name}\n" f"Email: {submission['email']}\n" f"Message: {submission['message']}" ) ) if __name__ == "__main__": sample = { "first_name": "Joe", "last_name": "Smith", "email": "daniel.grozdanovic@icloud.com", "message": "Interested in a product demo" } process_submission(sample)