commit c35ee2edee3fa9ced93abd92bc791877eac28e57 Author: daniel.g Date: Tue Jul 22 13:46:31 2025 +0000 Add ticket.py diff --git a/ticket.py b/ticket.py new file mode 100644 index 0000000..366515a --- /dev/null +++ b/ticket.py @@ -0,0 +1,184 @@ +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)