codeBOKER commited on
Commit
b001995
·
verified ·
1 Parent(s): 8c22c70

Update telegram_handlers.py

Browse files
Files changed (1) hide show
  1. telegram_handlers.py +38 -68
telegram_handlers.py CHANGED
@@ -2,7 +2,8 @@ import httpx
2
  import json
3
  import html
4
  import re
5
- from config import TELEGRAM_URL
 
6
  from ai_service import get_ai_response
7
  from database import db_manager
8
  from schemas import WebhookData
@@ -10,14 +11,10 @@ from schemas import WebhookData
10
  TELEGRAM_IP = "149.154.167.220"
11
  MAX_TELEGRAM_MESSAGE_LENGTH = 4096
12
 
13
-
14
  def _sanitize_telegram_text(text: str) -> str:
15
  if text is None:
16
  return ""
17
-
18
  normalized = str(text).replace("\r\n", "\n").replace("\r", "\n")
19
-
20
- # Remove control/surrogate chars that Telegram can reject.
21
  cleaned = "".join(
22
  ch
23
  for ch in normalized
@@ -25,18 +22,13 @@ def _sanitize_telegram_text(text: str) -> str:
25
  )
26
  return cleaned.strip()
27
 
28
-
29
  def _format_telegram_message(text: str) -> str:
30
- """Convert **bold** to <b>bold</b> for HTML parse mode."""
31
  if not text:
32
  return text
33
- # First escape HTML to prevent injection
34
  escaped = html.escape(text, quote=False)
35
- # Replace **text** with <b>text</b> (non-greedy)
36
  formatted = re.sub(r'\*\*(.*?)\*\*', r'<b>\1</b>', escaped)
37
  return formatted
38
 
39
-
40
  async def telegram_webhook(data: WebhookData):
41
  try:
42
  if not data.message or not data.message.text:
@@ -44,73 +36,51 @@ async def telegram_webhook(data: WebhookData):
44
 
45
  telegram_id = data.message.chat.id
46
  user_text = data.message.text
47
-
48
  username = data.message.chat.username
49
  first_name = data.message.chat.first_name
50
 
 
51
  if db_manager:
52
  await db_manager.create_or_update_user(telegram_id, username, first_name, data.message.chat.last_name)
53
 
54
-
55
  ai_answer = await get_ai_response(user_text, telegram_id)
56
-
57
-
58
-
59
- if TELEGRAM_URL:
60
- try:
61
- from config import TELEGRAM_TOKEN
 
 
62
 
63
- async with httpx.AsyncClient(timeout=40.0, verify=False) as client:
64
- prepared_text = _sanitize_telegram_text(
65
- ai_answer or "Sorry, I couldn't generate a response. Please try again."
66
- )
67
- if not prepared_text:
68
- prepared_text = "Sorry, I couldn't generate a response. Please try again."
69
-
70
- # Format for HTML parse mode
71
- formatted_text = _format_telegram_message(prepared_text)
72
-
73
- final_text = formatted_text[:MAX_TELEGRAM_MESSAGE_LENGTH]
74
- payload = {
75
- "chat_id": telegram_id,
76
- "text": final_text if final_text.strip() else ".",
77
- "parse_mode": "HTML",
78
- }
79
-
80
-
81
- try:
82
- response = await client.post(TELEGRAM_URL, data=payload)
83
- except Exception:
84
- print(f"--- DNS Failed. Forcing Direct IP Routing to {TELEGRAM_IP} ---")
85
-
86
- forced_ip_url = f"https://{TELEGRAM_IP}/bot{TELEGRAM_TOKEN}/sendMessage"
87
- json_body = json.dumps(payload, ensure_ascii=False).encode("utf-8")
88
- headers = {
89
- "Host": "api.telegram.org",
90
- "Content-Type": "application/json; charset=utf-8",
91
- "Content-Length": str(len(json_body)),
92
- }
93
-
94
- response = await client.post(
95
- forced_ip_url,
96
- content=json_body,
97
- headers=headers,
98
- )
99
-
100
- if response.status_code == 200:
101
- print("--- Success: Telegram message delivered ---")
102
- else:
103
- print("--- Telegram payload rejected ---")
104
- print(f"--- Payload: {payload} ---")
105
- print(
106
- f"--- Telegram Rejected Request: "
107
- f"{response.status_code} - {response.text} ---"
108
  )
109
-
110
- except Exception as send_error:
111
- print(f"--- Emergency: Network Blockage Detected: {str(send_error)} ---")
112
-
113
  return {"status": "ok"}
114
  except Exception as e:
115
  print(f"Error in webhook: {str(e)}")
116
- return {"status": "error", "message": str(e)}
 
2
  import json
3
  import html
4
  import re
5
+ import asyncio
6
+ from config import TELEGRAM_URL, TELEGRAM_TOKEN
7
  from ai_service import get_ai_response
8
  from database import db_manager
9
  from schemas import WebhookData
 
11
  TELEGRAM_IP = "149.154.167.220"
12
  MAX_TELEGRAM_MESSAGE_LENGTH = 4096
13
 
 
14
  def _sanitize_telegram_text(text: str) -> str:
15
  if text is None:
16
  return ""
 
17
  normalized = str(text).replace("\r\n", "\n").replace("\r", "\n")
 
 
18
  cleaned = "".join(
19
  ch
20
  for ch in normalized
 
22
  )
23
  return cleaned.strip()
24
 
 
25
  def _format_telegram_message(text: str) -> str:
 
26
  if not text:
27
  return text
 
28
  escaped = html.escape(text, quote=False)
 
29
  formatted = re.sub(r'\*\*(.*?)\*\*', r'<b>\1</b>', escaped)
30
  return formatted
31
 
 
32
  async def telegram_webhook(data: WebhookData):
33
  try:
34
  if not data.message or not data.message.text:
 
36
 
37
  telegram_id = data.message.chat.id
38
  user_text = data.message.text
 
39
  username = data.message.chat.username
40
  first_name = data.message.chat.first_name
41
 
42
+ # 1. تحديث المستخدم (Async)
43
  if db_manager:
44
  await db_manager.create_or_update_user(telegram_id, username, first_name, data.message.chat.last_name)
45
 
46
+ # 2. الحصول على رد الـ AI
47
  ai_answer = await get_ai_response(user_text, telegram_id)
48
+ final_response = ai_answer or "Sorry, I couldn't generate a response."
49
+
50
+ # 3. إرسال الرسالة باستخدام IP مباشر لتجنب تأخير DNS
51
+ if TELEGRAM_TOKEN:
52
+ async with httpx.AsyncClient(timeout=40.0, verify=False) as client:
53
+ prepared_text = _sanitize_telegram_text(final_response)
54
+ formatted_text = _format_telegram_message(prepared_text)
55
+ final_text = formatted_text[:MAX_TELEGRAM_MESSAGE_LENGTH]
56
 
57
+ payload = {
58
+ "chat_id": telegram_id,
59
+ "text": final_text if final_text.strip() else ".",
60
+ "parse_mode": "HTML",
61
+ }
62
+
63
+ # رابط مباشر لتجاوز DNS
64
+ forced_ip_url = f"https://{TELEGRAM_IP}/bot{TELEGRAM_TOKEN}/sendMessage"
65
+ headers = {
66
+ "Host": "api.telegram.org",
67
+ "Content-Type": "application/json; charset=utf-8",
68
+ }
69
+
70
+ response = await client.post(forced_ip_url, json=payload, headers=headers)
71
+
72
+ if response.status_code == 200:
73
+ print("--- Success: Telegram message delivered ---")
74
+ # 4. حفظ المحادثة بعد التأكد من وصول الرسالة
75
+ if db_manager:
76
+ await asyncio.gather(
77
+ db_manager.save_message(telegram_id, user_text, "user"),
78
+ db_manager.save_message(telegram_id, final_response, "assistant")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  )
80
+ else:
81
+ print(f"--- Telegram Rejected: {response.status_code} - {response.text} ---")
82
+
 
83
  return {"status": "ok"}
84
  except Exception as e:
85
  print(f"Error in webhook: {str(e)}")
86
+ return {"status": "error", "message": str(e)}