ragV98 commited on
Commit
02e1dba
·
1 Parent(s): 2bf582d

removing meta shite

Browse files
components/gateways/headlines_to_wa.py CHANGED
@@ -2,8 +2,6 @@ import datetime # Import datetime for dynamic date
2
  import json
3
  import logging
4
  import os
5
- import re
6
- import time
7
  from typing import Dict, List, Optional
8
 
9
  import redis
@@ -21,23 +19,6 @@ def getenv_strip(name: str, default: Optional[str] = None) -> Optional[str]:
21
  return v.strip() if isinstance(v, str) else v
22
 
23
 
24
- def only_digits(s: Optional[str]) -> Optional[str]:
25
- """Keep only digits from a string (useful for Meta Phone Number ID)."""
26
- if not s:
27
- return s
28
- return re.sub(r"\D+", "", s)
29
-
30
-
31
- def _mask_identifier(value: Optional[str]) -> str:
32
- """Mask sensitive identifiers in logs."""
33
- if not value:
34
- return "<unset>"
35
- trimmed = value.strip()
36
- if len(trimmed) <= 6:
37
- return f"***{trimmed[-3:]}"
38
- return f"***{trimmed[-4:]}"
39
-
40
-
41
  # -----------------------------------------
42
  # 🌐 Configuration from Environment Vars
43
  # -----------------------------------------
@@ -51,17 +32,6 @@ WHATSAPP_TO_NUMBER = getenv_strip("WHATSAPP_TO_NUMBER", "353899495777")
51
  GUPSHUP_SOURCE_NUMBER = getenv_strip("GUPSHUP_SOURCE_NUMBER")
52
  GUPSHUP_APP_NAME = getenv_strip("GUPSHUP_APP_NAME")
53
 
54
- # Meta (Cloud API) configuration (used for typing + mark-as-read when provider == "meta_cloud")
55
- META_GRAPH_VERSION = getenv_strip("META_GRAPH_VERSION", getenv_strip("WHATSAPP_CLOUD_GRAPH_VERSION", "v23.0"))
56
- META_PHONE_NUMBER_ID = only_digits(
57
- getenv_strip("WHATSAPP_CLOUD_PHONE_NUMBER_ID") or getenv_strip("META_PHONE_NUMBER_ID")
58
- )
59
- # IMPORTANT: Do NOT default to WHATSAPP_TOKEN (that is Gupshup).
60
- META_ACCESS_TOKEN = getenv_strip("WHATSAPP_CLOUD_TOKEN") or getenv_strip("META_ACCESS_TOKEN")
61
-
62
- # Global backoff state for typing indicator attempts
63
- _META_TYPING_SUPPRESS_UNTIL: Optional[float] = None
64
-
65
 
66
  # ✅ Redis connection
67
  try:
@@ -131,66 +101,6 @@ def _base_payload(destination_number: str) -> Dict[str, object]:
131
  }
132
 
133
 
134
- def _missing_meta_config(destination_number: Optional[str] = None) -> Optional[Dict[str, str]]:
135
- missing = []
136
- if not META_PHONE_NUMBER_ID:
137
- missing.append("WHATSAPP_CLOUD_PHONE_NUMBER_ID (or META_PHONE_NUMBER_ID)")
138
- if not META_ACCESS_TOKEN:
139
- missing.append("WHATSAPP_CLOUD_TOKEN (or META_ACCESS_TOKEN)")
140
- if not destination_number:
141
- missing.append("destination_number")
142
- if missing:
143
- msg = "❌ Missing Meta Cloud API config: " + ", ".join(missing)
144
- logging.error(msg)
145
- return {"status": "failed", "error": msg, "code": 500}
146
- return None
147
-
148
-
149
- # Optional early sanity hints in logs
150
- if META_PHONE_NUMBER_ID and not META_PHONE_NUMBER_ID.isdigit():
151
- logging.warning("META_PHONE_NUMBER_ID looks non-numeric after cleanup. Check your env value.")
152
- if META_ACCESS_TOKEN and not META_ACCESS_TOKEN.startswith("EAA"):
153
- logging.warning("META_ACCESS_TOKEN doesn't look like a typical Graph token (often starts with 'EAA').")
154
-
155
-
156
- # -----------------------------
157
- # HTTP helpers
158
- # -----------------------------
159
- def _post_to_meta_messages(payload: Dict[str, object]) -> Dict[str, object]:
160
- """POST to Meta WhatsApp Cloud `/messages` endpoint with detailed diagnostics."""
161
- url = f"https://graph.facebook.com/{META_GRAPH_VERSION}/{META_PHONE_NUMBER_ID}/messages"
162
- logging.debug("Meta POST URL: %s", url)
163
- try:
164
- response = requests.post(
165
- url,
166
- json=payload,
167
- headers={
168
- "Authorization": f"Bearer {META_ACCESS_TOKEN}",
169
- "Content-Type": "application/json",
170
- },
171
- timeout=10,
172
- )
173
- text = response.text # capture before raise_for_status for logging
174
- if response.status_code >= 400:
175
- logging.error("Meta POST %s failed: %s | %s", url, response.status_code, text)
176
- try:
177
- body = response.json()
178
- except ValueError:
179
- body = {"raw": text}
180
- return {"status": "failed", "code": response.status_code, "error": text, "details": body}
181
- try:
182
- return {"status": "success", "details": response.json() if text else {}}
183
- except ValueError:
184
- return {"status": "success", "details": {"raw": text}}
185
- except requests.exceptions.RequestException as exc:
186
- logging.error("Meta POST error: %s", exc)
187
- return {
188
- "status": "failed",
189
- "error": str(exc),
190
- "code": getattr(getattr(exc, "response", None), "status_code", 500),
191
- }
192
-
193
-
194
  def _post_to_gupshup(payload: Dict[str, object], action: str) -> Dict[str, object]:
195
  try:
196
  logging.info(
@@ -306,123 +216,19 @@ def send_to_whatsapp(message_text: str, destination_number: str) -> Dict[str, ob
306
 
307
 
308
  def send_seen_receipt(destination_number: str, message_id: Optional[str]) -> Dict[str, object]:
309
- """Mark an inbound message as read via the WhatsApp Cloud API."""
310
- if not message_id:
311
- logging.debug("Skipping seen receipt for %s due to missing message id", destination_number)
312
- return {"status": "skipped", "reason": "missing_message_id"}
313
-
314
- logging.info(
315
- "Seen receipt intent (Meta Cloud): msg_id=%s | phone_id=%s | token_prefix=%s",
316
  message_id,
317
- _mask_identifier(META_PHONE_NUMBER_ID),
318
- (META_ACCESS_TOKEN[:3] if META_ACCESS_TOKEN else "<none>"),
319
  )
320
-
321
- if not META_PHONE_NUMBER_ID or not META_ACCESS_TOKEN:
322
- error_msg = (
323
- "❌ Missing WhatsApp Cloud API credentials for mark-as-read. "
324
- "Set WHATSAPP_CLOUD_PHONE_NUMBER_ID (or META_PHONE_NUMBER_ID) and "
325
- "WHATSAPP_CLOUD_TOKEN (or META_ACCESS_TOKEN)."
326
- )
327
- logging.error(error_msg)
328
- return {"status": "failed", "error": error_msg, "code": 500}
329
-
330
- url = f"https://graph.facebook.com/{META_GRAPH_VERSION}/{META_PHONE_NUMBER_ID}/messages"
331
- logging.debug("Meta mark-as-read URL: %s", url)
332
- payload = {
333
- "messaging_product": "whatsapp",
334
- "status": "read",
335
- "message_id": message_id,
336
- "typing_indicator": {"type": "text"},
337
- }
338
-
339
- try:
340
- response = requests.post(
341
- url,
342
- json=payload,
343
- headers={
344
- "Authorization": f"Bearer {META_ACCESS_TOKEN}",
345
- "Content-Type": "application/json",
346
- },
347
- timeout=10,
348
- )
349
- text = response.text
350
- if response.status_code >= 400:
351
- logging.error("Meta mark-as-read failed: %s | %s", response.status_code, text)
352
- try:
353
- body = response.json()
354
- except ValueError:
355
- body = {"raw": text}
356
- return {"status": "failed", "details": body, "code": response.status_code}
357
-
358
- try:
359
- body = response.json()
360
- except ValueError:
361
- body = {"raw": text}
362
- return {"status": "success", "details": body}
363
- except requests.exceptions.RequestException as exc:
364
- logging.error("❌ Meta mark-as-read error: %s", exc)
365
- return {
366
- "status": "failed",
367
- "error": str(exc),
368
- "code": getattr(getattr(exc, "response", None), "status_code", 500),
369
- }
370
 
371
 
372
  def send_typing_indicator(destination_number: str, status: str = "typing") -> Dict[str, object]:
373
- """Send typing hints via Meta's WhatsApp Cloud API (per official docs)."""
374
- global _META_TYPING_SUPPRESS_UNTIL
375
-
376
- if _META_TYPING_SUPPRESS_UNTIL:
377
- remaining = _META_TYPING_SUPPRESS_UNTIL - time.time()
378
- if remaining > 0:
379
- logging.debug(
380
- "Meta typing indicator suppressed for %.1fs; skipping send for %s",
381
- remaining,
382
- destination_number,
383
- )
384
- return {"status": "skipped", "reason": "meta_typing_suppressed"}
385
- _META_TYPING_SUPPRESS_UNTIL = None
386
-
387
- normalized = (status or "typing").strip().lower()
388
- if normalized in {"typing_on", "start"}:
389
- normalized = "typing"
390
- elif normalized in {"typing_off", "stop", "stopped"}:
391
- normalized = "paused"
392
- elif normalized not in {"typing", "paused"}:
393
- logging.debug("Unknown typing status '%s'; defaulting to 'typing'", status)
394
- normalized = "typing"
395
-
396
- config_error = _missing_meta_config(destination_number)
397
- if config_error:
398
- return config_error
399
-
400
  logging.debug(
401
- "Typing indicator config: meta_phone_number_id=%s | gupshup_source_number=%s | whatsapp_to_number=%s",
402
- _mask_identifier(META_PHONE_NUMBER_ID),
403
- _mask_identifier(GUPSHUP_SOURCE_NUMBER),
404
- _mask_identifier(WHATSAPP_TO_NUMBER),
405
  )
406
-
407
- payload = {
408
- "messaging_product": "whatsapp",
409
- "to": destination_number,
410
- "type": "typing",
411
- "typing": {"status": normalized},
412
- }
413
-
414
- logging.info("Sending typing indicator (%s) to %s via Meta Cloud API", normalized, destination_number)
415
- result = _post_to_meta_messages(payload)
416
-
417
- if result.get("status") != "success":
418
- _META_TYPING_SUPPRESS_UNTIL = time.time() + 300 # back off for 5 minutes
419
- logging.warning(
420
- "Meta typing indicator failed; suppressing attempts for 5 minutes (%s)",
421
- result.get("error"),
422
- )
423
- if not META_PHONE_NUMBER_ID and not META_ACCESS_TOKEN:
424
- logging.warning(
425
- "Meta typing disabled until credentials are set (WHATSAPP_CLOUD_PHONE_NUMBER_ID / META_PHONE_NUMBER_ID, WHATSAPP_CLOUD_TOKEN / META_ACCESS_TOKEN)."
426
- )
427
-
428
- return result
 
2
  import json
3
  import logging
4
  import os
 
 
5
  from typing import Dict, List, Optional
6
 
7
  import redis
 
19
  return v.strip() if isinstance(v, str) else v
20
 
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  # -----------------------------------------
23
  # 🌐 Configuration from Environment Vars
24
  # -----------------------------------------
 
32
  GUPSHUP_SOURCE_NUMBER = getenv_strip("GUPSHUP_SOURCE_NUMBER")
33
  GUPSHUP_APP_NAME = getenv_strip("GUPSHUP_APP_NAME")
34
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
  # ✅ Redis connection
37
  try:
 
101
  }
102
 
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  def _post_to_gupshup(payload: Dict[str, object], action: str) -> Dict[str, object]:
105
  try:
106
  logging.info(
 
216
 
217
 
218
  def send_seen_receipt(destination_number: str, message_id: Optional[str]) -> Dict[str, object]:
219
+ """Stub for mark-as-read; Meta integration disabled."""
220
+ logging.debug(
221
+ "Seen receipt skipped for %s (Meta integration disabled). message_id=%s",
222
+ destination_number,
 
 
 
223
  message_id,
 
 
224
  )
225
+ return {"status": "skipped", "reason": "meta_disabled"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
 
227
 
228
  def send_typing_indicator(destination_number: str, status: str = "typing") -> Dict[str, object]:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  logging.debug(
230
+ "Typing indicator '%s' skipped for %s (Meta integration disabled).",
231
+ status,
232
+ destination_number,
 
233
  )
234
+ return {"status": "skipped", "reason": "meta_disabled"}