File size: 5,560 Bytes
a42f9f6
fa969c2
 
 
 
21725a9
6b6dd1e
 
fa969c2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b6f476e
fa969c2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b6f476e
fa969c2
 
 
 
b6f476e
fa969c2
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
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,
    }