user: User = Depends(get_current_user), _: None = Depends(require_csrf)): """REAL test send through Gmail API or SMTP XOAUTH2 using an authorized account. Returns the provider's message ID — never a fake success.""" import time t0 = time.monotonic() account = await db.get(GmailAccount, payload.account_id) if not account or account.user_id != user.id: raise HTTPException(status_code=404, detail="Gmail account not found") if account.status != "authorized" or not account.is_active: raise HTTPException(status_code=409, detail=f"Account is {account.status}; re-authorize first") if account.cooldown_until and account.cooldown_until > datetime.now(timezone.utc): raise HTTPException(status_code=409, detail="Account is in cooldown") # resolve body: template (with real variable substitution) or raw body template = None if payload.template_id: template = await db.get(EmailTemplate, payload.template_id) if not template or template.user_id != user.id: raise HTTPException(status_code=404, detail="Template not found") body_html = template.body_html if template else payload.body_html body_text = template.body_text if template else payload.body_text if not body_html and not body_text: raise HTTPException(status_code=400, detail="Provide a template or message body") problems = message_builder.validate_html(body_html) if body_html else [] if problems: # validate_html returns a list of problem strings raise HTTPException(status_code=400, detail=f"HTML rejected: {'; '.join(problems)}") # fake recipient record for variable substitution (test only) class _FakeRecipient: pass fr = _FakeRecipient() fr.email = str(payload.to_email) fr.first_name = "Test" fr.last_name = "Recipient" fr.company_name = await get_setting(db, "company_name", "Acme Corp") or "Acme Corp" fr.company_phone = "555-0100" fr.customer_email = str(payload.to_email) fr.custom_fields = {} engine = VariableEngine({}) g = GeneratedValues() if payload.use_random_variables: g.invoice_number = engine.generate_invoice_number(set()) g.amount = engine.generate_amount() g.shipping = engine.generate_shipping() g.invoice_date = "2025-01-15" g.due_date = "2025-01-30" unsub_url = f"{cfg.BASE_URL}/unsubscribe/test-token" res_html = engine.substitute(body_html or "", fr, g, custom_fields={}, extra={"unsubscribe_link": unsub_url, "company_phone": fr.company_phone}).text res_text = engine.substitute(body_text or "", fr, g, custom_fields={}, extra={"unsubscribe_link": unsub_url, "company_phone": fr.company_phone}).text subject = engine.substitute(payload.subject, fr, g).text attachments = [] if payload.include_pdf and body_html: pdf = await asyncio.get_event_loop().run_in_executor( None, message_builder.html_to_pdf, res_html) if pdf: attachments.append({"filename": "Test_Preview.pdf", "content": pdf, "mime_type": "application/pdf"}) mime = message_builder.build_mime_message( from_email=account.email,