Mr-Help commited on
Commit
41f2352
·
verified ·
1 Parent(s): 1a36746

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +205 -20
main.py CHANGED
@@ -1,13 +1,37 @@
1
  import json
 
2
  import requests
3
  from fastapi import FastAPI, Request
4
  from fastapi.middleware.cors import CORSMiddleware
5
  from fastapi.responses import JSONResponse
6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  GAS_WEBAPP_URL = "https://script.google.com/macros/s/AKfycbxFLlPzSvXM6xpVXR3-BjoK1lkNjYb8o1pctXI4Q2NZvv6wqKnIaSQA6hhL5lP_TQbTgQ/exec"
8
 
9
  app = FastAPI()
10
-
11
  app.add_middleware(
12
  CORSMiddleware,
13
  allow_origins=["*"],
@@ -16,36 +40,204 @@ app.add_middleware(
16
  allow_headers=["*"],
17
  )
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  @app.post("/recieve")
20
  async def webhook_receiver(req: Request):
21
  try:
22
  body = await req.json()
23
  except Exception:
24
- body = await req.body()
 
 
 
 
25
 
26
- print("===== RECEIVED =====")
27
- print(body)
28
- print("====================")
29
 
30
- return {"ok": True}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
  @app.post("/complaints")
33
  async def complaints_proxy(req: Request):
34
- # 1) اقرأ اللي جاي من الصفحة
35
  try:
36
  payload = await req.json()
37
  except Exception as e:
38
  print("❌ Failed to parse incoming JSON:", str(e))
39
- return JSONResponse(
40
- status_code=400,
41
- content={"ok": False, "error": "invalid json body"}
42
- )
43
 
44
  print("========== INCOMING PAYLOAD ==========")
45
  print(json.dumps(payload, ensure_ascii=False, indent=2))
46
  print("======================================")
47
 
48
- # 2) ابعت لـ GAS (server-to-server)
49
  try:
50
  gas_resp = requests.post(
51
  GAS_WEBAPP_URL,
@@ -54,15 +246,10 @@ async def complaints_proxy(req: Request):
54
  timeout=60
55
  )
56
  except Exception as e:
57
- # ✅ أهم جزء: ده كان غالبًا سبب الـ 500 عندك
58
  print("❌ ERROR calling GAS:", repr(e))
59
  return JSONResponse(
60
  status_code=502,
61
- content={
62
- "ok": False,
63
- "error": "failed to reach GAS",
64
- "details": str(e)
65
- }
66
  )
67
 
68
  print("========== GAS STATUS ==========")
@@ -71,8 +258,6 @@ async def complaints_proxy(req: Request):
71
  print((gas_resp.text or "")[:1500])
72
  print("=====================================================")
73
 
74
- # 3) رجّع نتيجة GAS للصفحة
75
- # (حتى لو GAS رجّع HTML أو خطأ)
76
  try:
77
  gas_json = gas_resp.json()
78
  return JSONResponse(status_code=200, content=gas_json)
 
1
  import json
2
+ import re
3
  import requests
4
  from fastapi import FastAPI, Request
5
  from fastapi.middleware.cors import CORSMiddleware
6
  from fastapi.responses import JSONResponse
7
 
8
+ # =========================
9
+ # Config
10
+ # =========================
11
+
12
+ GREENAPI_INSTANCE_ID = "7105210836"
13
+ GREENAPI_TOKEN = "805b69f6c85d4e6caea0edaba692b889abecc9e6bb8b457e8f"
14
+
15
+ GREENAPI_BASE = f"https://7105.api.greenapi.com/waInstance{GREENAPI_INSTANCE_ID}"
16
+
17
+ # Interactive buttons endpoint (زي المثال بتاعك)
18
+ GREENAPI_SEND_BUTTONS_URL = f"{GREENAPI_BASE}/sendInteractiveButtons/{GREENAPI_TOKEN}"
19
+
20
+ # Plain text endpoint (لو عندك endpoint مختلف في GreenAPI غيّره هنا)
21
+ GREENAPI_SEND_TEXT_URL = (
22
+ f"https://7105.api.greenapi.com/"
23
+ f"waInstance{GREENAPI_INSTANCE_ID}/sendMessage/{GREENAPI_TOKEN}"
24
+ )
25
+
26
+ COMPLAINT_FORM_URL = "https://www.google.com" # <-- حط لينك فورم الشكوى الحقيقي
27
+ AI_BOT_URL = "https://mr-help-adkbase.hf.space/processtext" # <-- endpoint بتاع البوت
28
+
29
+ TIMEOUT_SEC = 60
30
+
31
+ # (لو عايز تفضل GAS زي ما هو موجود)
32
  GAS_WEBAPP_URL = "https://script.google.com/macros/s/AKfycbxFLlPzSvXM6xpVXR3-BjoK1lkNjYb8o1pctXI4Q2NZvv6wqKnIaSQA6hhL5lP_TQbTgQ/exec"
33
 
34
  app = FastAPI()
 
35
  app.add_middleware(
36
  CORSMiddleware,
37
  allow_origins=["*"],
 
40
  allow_headers=["*"],
41
  )
42
 
43
+ # =========================
44
+ # Intent detection (بسيط)
45
+ # =========================
46
+
47
+ GREET_WORDS = [
48
+ "اهلا", "أهلا", "مرحبا", "هاي", "hello", "hi",
49
+ "السلام عليكم", "سلام عليكم", "مساء الخير", "صباح الخير",
50
+ "مساء الفل", "صباح الفل"
51
+ ]
52
+
53
+ COMPLAINT_WORDS = [
54
+ "شكوى", "شكاوي", "اشتكي", "مشكلة", "مشكلتي", "تذمر", "زعلان",
55
+ "سيء", "خدمة سيئة", "عايز أشتكي", "عايز اشتكي", "complaint"
56
+ ]
57
+
58
+ def detect_intent_simple(text: str) -> str:
59
+ t = (text or "").strip().lower()
60
+
61
+ if any(w in t for w in [x.lower() for x in GREET_WORDS]):
62
+ return "GREETING"
63
+
64
+ if any(w in t for w in [x.lower() for x in COMPLAINT_WORDS]):
65
+ return "COMPLAINT"
66
+
67
+ return "OTHER"
68
+
69
+ # =========================
70
+ # GreenAPI send helpers
71
+ # =========================
72
+
73
+ def send_interactive_buttons(chat_id: str, header: str, body: str, footer: str, buttons: list):
74
+ """
75
+ buttons example:
76
+ [{"buttonId":"1","buttonText":"..."}, ...]
77
+ OR url button:
78
+ {"type":"url","buttonId":"1","buttonText":"...","url":"..."}
79
+ """
80
+ payload = {
81
+ "chatId": chat_id,
82
+ "body": body,
83
+ "header": header,
84
+ "footer": footer,
85
+ "buttons": buttons
86
+ }
87
+ resp = requests.post(GREENAPI_SEND_BUTTONS_URL, json=payload, timeout=TIMEOUT_SEC)
88
+ return resp.status_code, (resp.text or "")[:1500]
89
+
90
+ def send_text_message(chat_id: str, message: str):
91
+ payload = {
92
+ "chatId": chat_id,
93
+ "message": message
94
+ }
95
+ headers = {
96
+ "Content-Type": "application/json"
97
+ }
98
+
99
+ resp = requests.post(
100
+ GREENAPI_SEND_TEXT_URL,
101
+ json=payload,
102
+ headers=headers,
103
+ timeout=TIMEOUT_SEC
104
+ )
105
+
106
+ return resp.status_code, (resp.text or "")[:1500]
107
+
108
+ # =========================
109
+ # AI bot call
110
+ # =========================
111
+
112
+ def call_ai_bot(message: str):
113
+ payload = {"message": message}
114
+ resp = requests.post(AI_BOT_URL, json=payload, timeout=TIMEOUT_SEC)
115
+ resp.raise_for_status()
116
+ try:
117
+ return resp.json()
118
+ except Exception:
119
+ return {"ok": False, "raw": resp.text}
120
+
121
+ # =========================
122
+ # Webhook receiver
123
+ # =========================
124
+
125
  @app.post("/recieve")
126
  async def webhook_receiver(req: Request):
127
  try:
128
  body = await req.json()
129
  except Exception:
130
+ raw = await req.body()
131
+ print("===== RECEIVED RAW =====")
132
+ print(raw)
133
+ print("========================")
134
+ return {"ok": True}
135
 
136
+ print("===== RECEIVED JSON =====")
137
+ print(json.dumps(body, ensure_ascii=False, indent=2))
138
+ print("=========================")
139
 
140
+ # 1) فلتر نوع الويبهوك
141
+ if body.get("typeWebhook") != "incomingMessageReceived":
142
+ return {"ok": True, "ignored": True}
143
+
144
+ # 2) استخرج wid + chatId + الرسالة
145
+ instance_wid = (body.get("instanceData") or {}).get("wid") # ده wid بتاع الـ instance
146
+ sender_data = body.get("senderData") or {}
147
+ chat_id = sender_data.get("chatId") # ده اللي لازم تبعت له الرد
148
+ msg_data = body.get("messageData") or {}
149
+
150
+ text_message = ""
151
+ if msg_data.get("typeMessage") == "textMessage":
152
+ text_message = ((msg_data.get("textMessageData") or {}).get("textMessage") or "").strip()
153
+
154
+ print(">>> instance_wid:", instance_wid)
155
+ print(">>> chat_id:", chat_id)
156
+ print(">>> text_message:", text_message)
157
+
158
+ # لو مفيش chat_id أو مفيش رسالة نصية، نوقف
159
+ if not chat_id or not text_message:
160
+ return {"ok": True, "skipped": True}
161
+
162
+ # 3) حدّد intent
163
+ intent = detect_intent_simple(text_message)
164
+ print(">>> intent:", intent)
165
+
166
+ # 4) ردود حسب intent
167
+ if intent == "GREETING":
168
+ header = "أهلاً بيك في ÄDK 👋"
169
+ body_txt = (
170
+ "منورنا! 😊\n"
171
+ "أنا مساعد ÄDK، تحب نساعدك في إيه؟"
172
+ )
173
+ footer = "ÄDK - German Courses"
174
+
175
+ buttons = [
176
+ {"buttonId": "1", "buttonText": "أنواع الكورسات"},
177
+ {"buttonId": "2", "buttonText": "تحديد مستوى"},
178
+ {"buttonId": "3", "buttonText": "تواصل معنا"},
179
+ ]
180
+
181
+ status, txt = send_interactive_buttons(chat_id, header, body_txt, footer, buttons)
182
+ print(">>> sent GREETING buttons:", status, txt)
183
+ return {"ok": True, "intent": intent}
184
+
185
+ if intent == "COMPLAINT":
186
+ header = "بنسمعك 🤝"
187
+ body_txt = "يسعدنا تواصلك. سجل الشكوى من الرابط ده، وفريقنا هيتواصل معاك في أقرب وقت."
188
+ footer = "شكراً لاختيار ÄDK"
189
+
190
+ buttons = [
191
+ {
192
+ "type": "url",
193
+ "buttonId": "1",
194
+ "buttonText": "تسجيل الشكوى",
195
+ "url": COMPLAINT_FORM_URL
196
+ }
197
+ ]
198
+
199
+ status, txt = send_interactive_buttons(chat_id, header, body_txt, footer, buttons)
200
+ print(">>> sent COMPLAINT url button:", status, txt)
201
+ return {"ok": True, "intent": intent}
202
+
203
+ # 5) غير كده → نبعته للـ AI bot
204
+ try:
205
+ bot_res = call_ai_bot(text_message)
206
+ # نتوقع {ok, intent, reply}
207
+ reply = ""
208
+ if isinstance(bot_res, dict):
209
+ reply = (bot_res.get("reply") or "").strip()
210
+ if not reply:
211
+ reply = "تمام — وصلت رسالتك. ممكن توضّحلي قصدك أكتر؟"
212
+
213
+ status, txt = send_text_message(chat_id, reply)
214
+ print(">>> sent AI reply:", status, txt)
215
+
216
+ return {"ok": True, "intent": "AI", "bot_intent": (bot_res.get("intent") if isinstance(bot_res, dict) else None)}
217
+
218
+ except Exception as e:
219
+ print("❌ AI bot failed:", str(e))
220
+ # fallback لطيف
221
+ status, txt = send_text_message(chat_id, "تمام — حصلت مشكلة بسيطة. ممكن تعيد إرسال رسالتك تاني؟")
222
+ print(">>> sent fallback:", status, txt)
223
+ return JSONResponse(status_code=200, content={"ok": True, "intent": "AI_FAILED", "error": str(e)})
224
+
225
+ # =========================
226
+ # Complaints proxy (زي ما هو عندك)
227
+ # =========================
228
 
229
  @app.post("/complaints")
230
  async def complaints_proxy(req: Request):
 
231
  try:
232
  payload = await req.json()
233
  except Exception as e:
234
  print("❌ Failed to parse incoming JSON:", str(e))
235
+ return JSONResponse(status_code=400, content={"ok": False, "error": "invalid json body"})
 
 
 
236
 
237
  print("========== INCOMING PAYLOAD ==========")
238
  print(json.dumps(payload, ensure_ascii=False, indent=2))
239
  print("======================================")
240
 
 
241
  try:
242
  gas_resp = requests.post(
243
  GAS_WEBAPP_URL,
 
246
  timeout=60
247
  )
248
  except Exception as e:
 
249
  print("❌ ERROR calling GAS:", repr(e))
250
  return JSONResponse(
251
  status_code=502,
252
+ content={"ok": False, "error": "failed to reach GAS", "details": str(e)}
 
 
 
 
253
  )
254
 
255
  print("========== GAS STATUS ==========")
 
258
  print((gas_resp.text or "")[:1500])
259
  print("=====================================================")
260
 
 
 
261
  try:
262
  gas_json = gas_resp.json()
263
  return JSONResponse(status_code=200, content=gas_json)