Mr-Help's picture
Update main.py
fa969c2 verified
Raw
History Blame Contribute Delete
5.56 kB
from fastapi import FastAPI, Request
import logging
import json
from datetime import datetime, timedelta
from typing import Any, Dict, List, Tuple
app = FastAPI()
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
)
log = logging.getLogger("supabase-receiver")
def extract_records(payload: Any) -> List[Dict]:
"""
نحاول نطلع records من البودي بأي شكل محتمل:
- { "record": {...} }
- { "records": [ {...}, {...} ] }
- [ {...}, {...} ]
- أو dict واحد نعتبره row واحد.
"""
if isinstance(payload, dict):
if "record" in payload and isinstance(payload["record"], dict):
return [payload["record"]]
if "records" in payload and isinstance(payload["records"], list):
return [r for r in payload["records"] if isinstance(r, dict)]
return [payload]
elif isinstance(payload, list):
return [r for r in payload if isinstance(r, dict)]
else:
return []
def parse_lead_timestamp(raw_ts: str) -> Tuple[str, str]:
"""
يحوّل lead_timestamp إلى:
- deadline: تاريخ ووقت +24 ساعة (string)
- due_date: تاريخ فقط (string)
لو مفيش timestamp هنستخدم الوقت الحالي.
"""
if not raw_ts:
now = datetime.utcnow()
deadline = now + timedelta(hours=24)
else:
ts = raw_ts.replace("Z", "+00:00")
dt = datetime.fromisoformat(ts)
deadline = dt + timedelta(hours=24)
deadline_str = deadline.strftime("%Y-%m-%d %H:%M:%S")
due_date = deadline.date().isoformat()
return deadline_str, due_date
def build_odoo_payload_from_lead(lead: Dict) -> Dict:
"""
نفس المابّينج تقريبًا اللي هنعمله في السيرفر الحقيقي،
بس هنا عشان نطبع كود جاهز للتست لوكال.
"""
full_name = lead.get("full_name") or lead.get("name") or "Lead"
email = lead.get("email") or ""
phone = lead.get("phone") or ""
city_from_lead = lead.get("city") or False
platform = lead.get("platform") or ""
lead_ts = lead.get("lead_timestamp")
deadline_str, due_date = parse_lead_timestamp(lead_ts)
body = {
"name": full_name,
"date_deadline": deadline_str,
"user_id": lead.get("lead_id"), # زي ما اتفقنا
"active": True,
"kanban_state": "grey",
"type": "opportunity",
"stage_id": 18,
"tag_ids": [],
"color": 0,
"adgroup_name": lead.get("campaign_name"),
"adset_name": lead.get("adset_name"),
"ad_name": lead.get("ad_name", ""),
"lead_timestamp": lead_ts,
"source_id": None,
"source_company": "Jizan",
"due_date": due_date,
"call_logs": "",
"call_log_result": "",
"age": None,
"specialty_id": False,
"gender_id": False,
"city_ar": city_from_lead or "غير محدد",
"email_from": email,
"city": False,
"phone": phone,
"platform": platform,
}
return body
def build_python_snippet_for_odoo(payload: Dict) -> str:
"""
يبني كود Python جاهز تقدر تاخده كوبي-بيست،
وتستعمله لوكال عشان يبعته لـ Odoo.
"""
payload_json = json.dumps(payload, ensure_ascii=False, indent=4)
snippet = f'''import requests
ODOO_LEAD_URL = "https://odoo.binrushd.care/api/crm.lead"
token = "PASTE_TOKEN_HERE" # حط التوكن اللي جالك من /api/auth/token
payload = {payload_json}
headers = {{
"Authorization": f"Bearer {{token}}",
"Content-Type": "application/json",
}}
resp = requests.post(ODOO_LEAD_URL, json=payload, headers=headers, timeout=30)
print(resp.status_code)
print(resp.text)
'''
return snippet
@app.post("/")
async def receive_from_supabase(request: Request):
"""
Endpoint رئيسي تستقبله Supabase Webhook.
- يطبع البودي بالكامل في اللوج
- يطلع أول record
- يبني منه payload لـ Odoo
- يطبع كود Python في اللوج تقدر تاخده كوبي-بيست وتجرّبه لوكال.
"""
try:
body = await request.json()
except Exception as e:
log.error("Failed to parse JSON body: %s", e)
return {"status": "error", "detail": f"Invalid JSON: {e}"}
# 1) طباعة البودي الخام
log.info("=== RAW WEBHOOK BODY FROM SUPABASE ===")
log.info(json.dumps(body, ensure_ascii=False, indent=2))
# 2) استخراج records
records = extract_records(body)
if not records:
log.warning("No records found in webhook payload.")
return {"status": "ok", "note": "no records in payload"}
first = records[0]
log.info("=== FIRST RECORD (lead) ===")
log.info(json.dumps(first, ensure_ascii=False, indent=2))
# 3) بناء payload لـ Odoo
odoo_payload = build_odoo_payload_from_lead(first)
log.info("=== ODOO PAYLOAD (dict) ===")
log.info(json.dumps(odoo_payload, ensure_ascii=False, indent=2))
# 4) توليد كود Python جاهز
python_snippet = build_python_snippet_for_odoo(odoo_payload)
log.info("=== PYTHON SNIPPET TO SEND THIS LEAD TO ODOO ===")
log.info("\n%s", python_snippet)
# 5) نرجّع response بسيط
return {
"status": "ok",
"records_received": len(records),
"preview_odoo_payload": odoo_payload,
}