ragV98 commited on
Commit
3eb899a
Β·
1 Parent(s): b28c6c4
components/gateways/headlines_to_wa.py CHANGED
@@ -4,17 +4,18 @@ import redis
4
  import requests
5
  from fastapi import FastAPI
6
  from fastapi.responses import JSONResponse
7
- import logging # Import logging for better output
8
 
9
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
10
 
11
  # 🌐 Redis config
12
  REDIS_URL = os.environ.get("UPSTASH_REDIS_URL", "redis://localhost:6379")
13
- WHATSAPP_API_URL = os.environ.get("WHATSAPP_API_URL", "https://api.gupshup.io/sm/api/v1/msg")
14
- WHATSAPP_TOKEN = os.environ.get("WHATSAPP_TOKEN", "sk_e73f674b797549ed80c85105ded5a0d1")
15
- WHATSAPP_TO_NUMBER = os.environ.get("WHATSAPP_TO_NUMBER", "35389945777") # e.g., "91xxxxxxxxxx"
16
- GUPSHUP_SOURCE_NUMBER = os.environ.get("GUPSHUP_SOURCE_NUMBER", "15557926439") # e.g., your WABA number
17
- GUPSHUP_APP_NAME = os.environ.get("GUPSHUP_APP_NAME", "NuseAI") # e.g., your Gupshup app name
 
18
 
19
  # βœ… Redis connection
20
  try:
@@ -23,14 +24,11 @@ try:
23
  logging.info("Redis client connected successfully.")
24
  except Exception as e:
25
  logging.error(f"❌ Failed to connect to Redis: {e}")
26
- # Depending on your application's needs, you might want to exit or fail gracefully here.
27
  raise
28
 
29
  # 🧾 Fetch and format headlines
30
  def fetch_cached_headlines() -> str:
31
  try:
32
- # Assuming 'detailed_news_feed_cache' is the key for the final detailed headlines
33
- # This key should match what's used in components/generators/detailed_explainer.py
34
  raw = redis_client.get("detailed_news_feed_cache")
35
  if not raw:
36
  logging.warning("⚠️ No detailed news headlines found in cache.")
@@ -42,28 +40,20 @@ def fetch_cached_headlines() -> str:
42
 
43
  message_parts = ["πŸ—žοΈ *Your Daily Digest* 🟑\n"]
44
 
45
- # Iterate through topics in the order defined by TOPIC_KEYS (if available, otherwise iterate data.items())
46
- # Assuming TOPIC_KEYS is available globally or passed here if needed for consistent order
47
- # For now, just iterate through the data items as they are in the cached JSON
48
-
49
- # Sort topics alphabetically for consistent output if no external order is provided
50
  sorted_topics = sorted(data.keys())
51
 
52
  for topic_key in sorted_topics:
53
  stories = data[topic_key]
54
- # Format topic title nicely (e.g., "india" -> "India", "world" -> "World")
55
  title = topic_key.replace("_", " ").title()
56
  message_parts.append(f"🏷️ *{title}*")
57
 
58
- # Sort stories by their sequential ID for consistent order
59
- sorted_story_ids = sorted(stories.keys(), key=int) # Ensure keys are treated as integers for sorting
60
 
61
  for ref_id in sorted_story_ids:
62
  item = stories[ref_id]
63
- summary = item.get("title", "") # Use 'title' key for the summary/headline
64
- description = item.get("description", "") # Use 'description' key for the explanation
65
 
66
- # Ensure ref_id is a string for the message
67
  message_parts.append(f"{ref_id}. {summary}\n_Why this matters_: {description}")
68
  message_parts.append("") # spacing between sections
69
 
@@ -77,16 +67,16 @@ def send_to_whatsapp(message_text: str) -> dict:
77
  logging.error(error_msg)
78
  return {"status": "failed", "error": error_msg, "code": 500}
79
 
80
- # Gupshup requires the API key in the 'apikey' header
81
  headers = {
82
  "Content-Type": "application/x-www-form-urlencoded",
83
- "apikey": WHATSAPP_TOKEN # <<< FIX: API key in 'apikey' header
 
84
  }
85
 
86
  payload = {
87
  "channel": "whatsapp",
88
  "source": GUPSHUP_SOURCE_NUMBER,
89
- "destination": WHATSAPP_TO_NUMBER,
90
  "message": json.dumps({
91
  "type": "text",
92
  "text": message_text
@@ -95,12 +85,11 @@ def send_to_whatsapp(message_text: str) -> dict:
95
  }
96
 
97
  try:
98
- logging.info(f"Attempting to send WhatsApp message to {WHATSAPP_TO_NUMBER} via Gupshup.")
99
  response = requests.post(
100
- WHATSAPP_API_URL,
101
  headers=headers,
102
- data=payload,
103
- # auth=(WHATSAPP_TOKEN, '') # <<< REMOVED: This sends Basic Auth, which Gupshup doesn't support for API key
104
  )
105
  response.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)
106
 
@@ -130,19 +119,12 @@ def send_daily_whatsapp_digest():
130
  logging.info("βœ… WhatsApp message sent successfully.")
131
  return JSONResponse(status_code=200, content=result)
132
  else:
133
- logging.error(f"❌ Failed to send WhatsApp message: {result.get('error')}")
134
  return JSONResponse(status_code=result.get("code", 500), content=result)
135
 
136
  # πŸ§ͺ For local testing
137
  if __name__ == "__main__":
138
- # Set dummy environment variables for local testing if not already set
139
- os.environ.setdefault("WHATSAPP_API_URL", "https://api.gupshup.io/sm/api/v1/msg")
140
- os.environ.setdefault("WHATSAPP_TOKEN", "sk_e73f674b797549ed80c85105ded5a0d1") # Replace with a real dummy or your actual key
141
- os.environ.setdefault("WHATSAPP_TO_NUMBER", "35389945777") # Replace with a test number
142
- os.environ.setdefault("GUPSHUP_SOURCE_NUMBER", "15557926439") # Replace with your WABA number
143
- os.environ.setdefault("GUPSHUP_APP_NAME", "NuseAI") # Replace with your app name
144
-
145
- # Simulate a cached detailed feed for testing
146
  dummy_cached_detailed_feed = {
147
  "india": {
148
  "1": {"title": "India's Economy Surges", "description": "Rapid growth in manufacturing and services sectors signals a strong economic recovery, boosting investor confidence and job creation.", "sources": ["Times of India"]},
@@ -162,6 +144,5 @@ if __name__ == "__main__":
162
  print(msg_preview)
163
 
164
  logging.info("\n--- Sending WhatsApp Message (Test) ---\n")
165
- # This will attempt to send a real message if your env vars are valid
166
  test_result = send_to_whatsapp(msg_preview)
167
  print(test_result)
 
4
  import requests
5
  from fastapi import FastAPI
6
  from fastapi.responses import JSONResponse
7
+ import logging
8
 
9
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
10
 
11
  # 🌐 Redis config
12
  REDIS_URL = os.environ.get("UPSTASH_REDIS_URL", "redis://localhost:6379")
13
+ # <<< CHANGE 1: Update the API URL to match the curl template >>>
14
+ WHATSAPP_API_URL = os.environ.get("WHATSAPP_API_URL", "https://api.gupshup.io/wa/api/v1/msg")
15
+ WHATSAPP_TOKEN = os.environ.get("WHATSAPP_TOKEN")
16
+ WHATSAPP_TO_NUMBER = os.environ.get("WHATSAPP_TO_NUMBER") # e.g., "91xxxxxxxxxx"
17
+ GUPSHUP_SOURCE_NUMBER = os.environ.get("GUPSHUP_SOURCE_NUMBER") # e.g., your WABA number
18
+ GUPSHUP_APP_NAME = os.environ.get("GUPSHUP_APP_NAME") # e.g., your Gupshup app name
19
 
20
  # βœ… Redis connection
21
  try:
 
24
  logging.info("Redis client connected successfully.")
25
  except Exception as e:
26
  logging.error(f"❌ Failed to connect to Redis: {e}")
 
27
  raise
28
 
29
  # 🧾 Fetch and format headlines
30
  def fetch_cached_headlines() -> str:
31
  try:
 
 
32
  raw = redis_client.get("detailed_news_feed_cache")
33
  if not raw:
34
  logging.warning("⚠️ No detailed news headlines found in cache.")
 
40
 
41
  message_parts = ["πŸ—žοΈ *Your Daily Digest* 🟑\n"]
42
 
 
 
 
 
 
43
  sorted_topics = sorted(data.keys())
44
 
45
  for topic_key in sorted_topics:
46
  stories = data[topic_key]
 
47
  title = topic_key.replace("_", " ").title()
48
  message_parts.append(f"🏷️ *{title}*")
49
 
50
+ sorted_story_ids = sorted(stories.keys(), key=int)
 
51
 
52
  for ref_id in sorted_story_ids:
53
  item = stories[ref_id]
54
+ summary = item.get("title", "")
55
+ description = item.get("description", "")
56
 
 
57
  message_parts.append(f"{ref_id}. {summary}\n_Why this matters_: {description}")
58
  message_parts.append("") # spacing between sections
59
 
 
67
  logging.error(error_msg)
68
  return {"status": "failed", "error": error_msg, "code": 500}
69
 
 
70
  headers = {
71
  "Content-Type": "application/x-www-form-urlencoded",
72
+ "apikey": WHATSAPP_TOKEN, # API key in 'apikey' header
73
+ "Cache-Control": "no-cache" # <<< CHANGE 2: Add Cache-Control header
74
  }
75
 
76
  payload = {
77
  "channel": "whatsapp",
78
  "source": GUPSHUP_SOURCE_NUMBER,
79
+ "destination": WHATSAPP_TO_NUMBER, # Ensure this holds the full number, not just '91'
80
  "message": json.dumps({
81
  "type": "text",
82
  "text": message_text
 
85
  }
86
 
87
  try:
88
+ logging.info(f"Attempting to send WhatsApp message to {WHATSAPP_TO_NUMBER} via Gupshup. API URL: {WHATSAPP_API_URL}")
89
  response = requests.post(
90
+ WHATSAPP_API_URL, # Uses the updated URL
91
  headers=headers,
92
+ data=payload, # requests will correctly url-encode this dict
 
93
  )
94
  response.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)
95
 
 
119
  logging.info("βœ… WhatsApp message sent successfully.")
120
  return JSONResponse(status_code=200, content=result)
121
  else:
122
+ logging.error(f"❌ Failed to send WhatsApp message: {result.get("error")}")
123
  return JSONResponse(status_code=result.get("code", 500), content=result)
124
 
125
  # πŸ§ͺ For local testing
126
  if __name__ == "__main__":
127
+
 
 
 
 
 
 
 
128
  dummy_cached_detailed_feed = {
129
  "india": {
130
  "1": {"title": "India's Economy Surges", "description": "Rapid growth in manufacturing and services sectors signals a strong economic recovery, boosting investor confidence and job creation.", "sources": ["Times of India"]},
 
144
  print(msg_preview)
145
 
146
  logging.info("\n--- Sending WhatsApp Message (Test) ---\n")
 
147
  test_result = send_to_whatsapp(msg_preview)
148
  print(test_result)