Files
mivanchenko c3e520aabb
Test backoffice (smb-crm) / test (push) Successful in 1m43s
Rate-limit public bookings per contact; add direct owner contact endpoint
Public booking API now rejects a 6th active booking from the same
customer_contact within 24h (429), stopping one contact from filling
every slot on every resource, while owner-entered manual bookings stay
unaffected.

Add POST /api/contact: client sites can reach their own owner's inbox
directly (via their existing login email) for general inquiries,
separate from the agency's leads/Telegram pipeline (n8n/lead-intake.json),
which stays reserved for actual prospects contacting the agency itself.
Paris Barber Shop's contact form and Rückruf widget now point here; the
Rückruf floating widget itself has been removed from the site.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 04:47:06 +02:00

47 lines
1.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Direct customer-to-owner contact email: a client's own site visitor asking
a question or requesting a callback (contact_api.py) reaches the business
owner's inbox directly. This is deliberately NOT the agency's leads pipeline
(n8n/lead-intake.json, the leads table, the agency's Telegram) -- that path
still exists separately for prospects contacting the agency itself (the
"DEMO" client_id on the marketing/demo pages), which are genuine sales leads
for the agency, not a client's own customers.
Recipient is resolved via booking_db.list_users(client_id) (the owner's own
login email, e.g. inhaber@<slug>.mivanchenko.de) -- every provisioned client
already has at least one owner account by the time their site can receive
contact requests. Fire-and-forget via mailer.py, same as booking_mail.py/
owner_mail.py.
"""
import booking_db as bdb
import booking_mail
import mailer
from flask import render_template
def notify_owner_of_contact(client_id, payload):
"""Returns True if at least one owner account was found and an email was
queued, False if this client has no owner account yet (nothing to notify
-- the caller turns that into a clean 404, since there is no one to
receive the message)."""
users = bdb.list_users(client_id)
if not users:
return False
client = bdb.get_client(client_id)
business_name = (client or {}).get("business_name") or "Ihre Website"
html = render_template(
"emails/contact_notification.html",
business_name=business_name,
name=payload.get("name") or "",
contact=payload.get("contact") or "",
service_interest=payload.get("service_interest") or "",
message=payload.get("message") or "",
)
from_addr = booking_mail._sender_for(client)
for user in users:
mailer.send_email(
user["email"],
f"Neue Anfrage über Ihre Website {business_name}",
html,
from_addr=from_addr)
return True