codeBOKER commited on
Commit
5d10ce5
·
1 Parent(s): 8619a68

Update config and telegram handlers

Browse files
Files changed (2) hide show
  1. config.py +2 -2
  2. telegram_handlers.py +88 -32
config.py CHANGED
@@ -12,10 +12,10 @@ HF_TOKEN = os.environ.get("HF_TOKEN") or os.environ.get("HF_API_KEY")
12
  TELEGRAM_TOKEN = os.environ.get("TELEGRAM_TOKEN")
13
  SUPABASE_URL = os.environ.get("SUPABASE_URL")
14
  SUPABASE_KEY = os.environ.get("SUPABASE_KEY")
15
- TELEGRAM_DOMAIN = os.environ.get("TELEGRAM_DOMAIN")
16
 
17
  # Only create TELEGRAM_URL if token exists
18
- TELEGRAM_URL = f"{TELEGRAM_DOMAIN}/bot{TELEGRAM_TOKEN}/sendMessage" if TELEGRAM_TOKEN else None
19
 
20
  EMBED_MODEL = os.environ.get("EMBED_MODEL", "multilingual-e5-large")
21
  HF_MODEL = os.environ.get(
 
12
  TELEGRAM_TOKEN = os.environ.get("TELEGRAM_TOKEN")
13
  SUPABASE_URL = os.environ.get("SUPABASE_URL")
14
  SUPABASE_KEY = os.environ.get("SUPABASE_KEY")
15
+ TELEGRAM_DOMAIN = os.environ.get("TELEGRAM_DOMAIN", "https://api.telegram.org").rstrip("/")
16
 
17
  # Only create TELEGRAM_URL if token exists
18
+ TELEGRAM_URL = f"{TELEGRAM_DOMAIN}/bot{TELEGRAM_TOKEN}/sendMessage" if TELEGRAM_TOKEN and TELEGRAM_DOMAIN else None
19
 
20
  EMBED_MODEL = os.environ.get("EMBED_MODEL", "multilingual-e5-large")
21
  HF_MODEL = os.environ.get(
telegram_handlers.py CHANGED
@@ -1,4 +1,3 @@
1
- from fastapi import Request
2
  from pydantic import BaseModel
3
  import httpx
4
  import json
@@ -7,6 +6,50 @@ from ai_service import get_ai_response
7
  from database import db_manager
8
 
9
  TELEGRAM_IP = "149.154.167.220"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
  class ChatInfo(BaseModel):
12
  id: int
@@ -47,42 +90,55 @@ async def telegram_webhook(data: WebhookData):
47
  from config import TELEGRAM_TOKEN
48
 
49
  async with httpx.AsyncClient(timeout=40.0, verify=False, follow_redirects=True) as client:
50
- payload = {
51
- "chat_id": telegram_id,
52
- "text": ai_answer or "Sorry, I couldn't generate a response. Please try again."
53
- }
54
-
55
- print(f"--- Payload being sent: {payload} ---")
56
-
57
- try:
58
- # Attempt standard request
59
- response = await client.post(TELEGRAM_URL, json=payload)
60
- except Exception as dns_err:
61
- print(f"--- DNS Failed. Forcing Direct IP Routing to 149.154.167.220 ---")
62
-
63
- forced_ip_url = f"https://{TELEGRAM_IP}/bot{TELEGRAM_TOKEN}/sendMessage"
64
 
65
- # 1. Manually dump to JSON string to ensure UTF-8 for Arabic
66
- json_body = json.dumps(payload, ensure_ascii=False).encode('utf-8')
67
 
68
- headers = {
69
- "Host": "api.telegram.org",
70
- "Content-Type": "application/json",
71
- "Content-Length": str(len(json_body)) # Explicitly tell Telegram the size
72
  }
73
 
74
- # 2. Use 'content=' or 'data=' instead of 'json='
75
- response = await client.post(
76
- forced_ip_url,
77
- content=json_body,
78
- headers=headers
79
  )
80
-
81
- if response.status_code == 200:
82
- print(f"--- Success: Message delivered via Direct IP Pipeline ---")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  else:
84
- print(f"--- Payload: {payload} ---")
85
- print(f"--- Telegram Rejected Request: {response.status_code} - {response.text} ---")
86
 
87
  except Exception as send_error:
88
  print(f"--- Emergency: Network Blockage Detected: {str(send_error)} ---")
@@ -90,4 +146,4 @@ async def telegram_webhook(data: WebhookData):
90
  return {"status": "ok"}
91
  except Exception as e:
92
  print(f"Error in webhook: {str(e)}")
93
- return {"status": "error", "message": str(e)}
 
 
1
  from pydantic import BaseModel
2
  import httpx
3
  import json
 
6
  from database import db_manager
7
 
8
  TELEGRAM_IP = "149.154.167.220"
9
+ MAX_TELEGRAM_MESSAGE_LENGTH = 4096
10
+
11
+
12
+ def _sanitize_telegram_text(text: str) -> str:
13
+ if text is None:
14
+ return ""
15
+
16
+ normalized = str(text).replace("\r\n", "\n").replace("\r", "\n")
17
+
18
+ # Remove control/surrogate chars that Telegram can reject.
19
+ cleaned = "".join(
20
+ ch
21
+ for ch in normalized
22
+ if (ch in ("\n", "\t") or ord(ch) >= 32) and not (0xD800 <= ord(ch) <= 0xDFFF)
23
+ )
24
+ return cleaned.strip()
25
+
26
+
27
+ def _split_telegram_message(text: str, max_length: int = MAX_TELEGRAM_MESSAGE_LENGTH):
28
+ if len(text) <= max_length:
29
+ return [text]
30
+
31
+ parts = []
32
+ remaining = text
33
+
34
+ while len(remaining) > max_length:
35
+ split_at = remaining.rfind("\n", 0, max_length)
36
+ if split_at == -1:
37
+ split_at = remaining.rfind(" ", 0, max_length)
38
+ if split_at == -1:
39
+ split_at = max_length
40
+
41
+ part = remaining[:split_at].strip()
42
+ if not part:
43
+ part = remaining[:max_length]
44
+ split_at = max_length
45
+
46
+ parts.append(part)
47
+ remaining = remaining[split_at:].strip()
48
+
49
+ if remaining:
50
+ parts.append(remaining)
51
+
52
+ return parts
53
 
54
  class ChatInfo(BaseModel):
55
  id: int
 
90
  from config import TELEGRAM_TOKEN
91
 
92
  async with httpx.AsyncClient(timeout=40.0, verify=False, follow_redirects=True) as client:
93
+ prepared_text = _sanitize_telegram_text(
94
+ ai_answer or "Sorry, I couldn't generate a response. Please try again."
95
+ )
96
+ if not prepared_text:
97
+ prepared_text = "Sorry, I couldn't generate a response. Please try again."
 
 
 
 
 
 
 
 
 
98
 
99
+ message_parts = _split_telegram_message(prepared_text, MAX_TELEGRAM_MESSAGE_LENGTH)
 
100
 
101
+ for idx, part in enumerate(message_parts, start=1):
102
+ payload = {
103
+ "chat_id": telegram_id,
104
+ "text": part,
105
  }
106
 
107
+ print(
108
+ f"--- Sending Telegram message part {idx}/{len(message_parts)} "
109
+ f"(chars={len(part)}) ---"
 
 
110
  )
111
+
112
+ try:
113
+ # Use form data for maximal compatibility with Telegram endpoint parsers.
114
+ response = await client.post(TELEGRAM_URL, data=payload)
115
+ except Exception:
116
+ print(f"--- DNS Failed. Forcing Direct IP Routing to {TELEGRAM_IP} ---")
117
+
118
+ forced_ip_url = f"https://{TELEGRAM_IP}/bot{TELEGRAM_TOKEN}/sendMessage"
119
+ json_body = json.dumps(payload, ensure_ascii=False).encode("utf-8")
120
+ headers = {
121
+ "Host": "api.telegram.org",
122
+ "Content-Type": "application/json; charset=utf-8",
123
+ "Content-Length": str(len(json_body)),
124
+ }
125
+
126
+ response = await client.post(
127
+ forced_ip_url,
128
+ content=json_body,
129
+ headers=headers,
130
+ )
131
+
132
+ if response.status_code != 200:
133
+ print(f"--- Telegram payload rejected (part {idx}) ---")
134
+ print(f"--- Payload: {payload} ---")
135
+ print(
136
+ f"--- Telegram Rejected Request: "
137
+ f"{response.status_code} - {response.text} ---"
138
+ )
139
+ break
140
  else:
141
+ print("--- Success: All Telegram message parts delivered ---")
 
142
 
143
  except Exception as send_error:
144
  print(f"--- Emergency: Network Blockage Detected: {str(send_error)} ---")
 
146
  return {"status": "ok"}
147
  except Exception as e:
148
  print(f"Error in webhook: {str(e)}")
149
+ return {"status": "error", "message": str(e)}