File size: 5,291 Bytes
64ef9f2
 
 
 
e4f3bc9
eb4b0f5
5093e27
 
64ef9f2
eb4b0f5
64ef9f2
3eb899a
 
eb882d5
966434b
 
64ef9f2
eb4b0f5
5093e27
 
966434b
5093e27
 
 
 
64ef9f2
eb4b0f5
 
 
 
 
 
 
 
 
 
 
64ef9f2
 
022166e
64ef9f2
5093e27
64ef9f2
 
 
5093e27
64ef9f2
 
3bbcbf3
 
 
5093e27
3bbcbf3
5093e27
3bbcbf3
9f13b5b
 
 
3bbcbf3
eb4b0f5
9f13b5b
3bbcbf3
9f13b5b
3bbcbf3
5093e27
3bbcbf3
 
 
 
022166e
 
3bbcbf3
eb4b0f5
 
 
9f13b5b
3bbcbf3
 
eb4b0f5
 
64ef9f2
5093e27
64ef9f2
1c8e081
3bbcbf3
eb882d5
e4f3bc9
 
eb882d5
966434b
5093e27
 
966434b
 
 
 
 
 
5093e27
64ef9f2
5093e27
966434b
9f13b5b
eb4b0f5
64ef9f2
 
3bbcbf3
 
 
 
e4f3bc9
64ef9f2
1c8e081
 
eb882d5
1c8e081
f5b0713
eb4b0f5
 
64ef9f2
 
5093e27
c066eb5
5093e27
a6c6341
5093e27
e4f3bc9
5093e27
966434b
64ef9f2
1c8e081
5093e27
 
 
 
 
9a7410d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import os
import json
import redis
import requests
import logging
import datetime # Import datetime for dynamic date

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# ๐ŸŒ Configuration from Environment Variables
REDIS_URL = os.environ.get("UPSTASH_REDIS_URL", "redis://localhost:6379")
WHATSAPP_API_URL = os.environ.get("WHATSAPP_API_URL", "https://api.gupshup.io/wa/api/v1/msg") 
WHATSAPP_TOKEN = os.environ.get("WHATSAPP_TOKEN")
WHATSAPP_TO_NUMBER = os.environ.get("WHATSAPP_TO_NUMBER", "353899495777")  
GUPSHUP_SOURCE_NUMBER = os.environ.get("GUPSHUP_SOURCE_NUMBER")  
GUPSHUP_APP_NAME = os.environ.get("GUPSHUP_APP_NAME")  

# โœ… Redis connection
try:
    redis_client = redis.Redis.from_url(REDIS_URL, decode_responses=True)
    redis_client.ping() 
    logging.info("Redis client connected successfully.")
except Exception as e:
    logging.error(f"โŒ Failed to connect to Redis: {e}")
    raise

# --- New: Topic mapping for display names and emojis ---
TOPIC_DISPLAY_MAP = {
    "india": {"name": "India", "emoji": "๐Ÿ‡ฎ๐Ÿ‡ณ"},
    "world": {"name": "World", "emoji": "๐ŸŒ"},
    "tech": {"name": "Technology", "emoji": "๐Ÿง "}, 
    "finance": {"name": "Business & Markets", "emoji": "๐Ÿ’ฐ"}, 
    "sports": {"name": "Sports", "emoji": "๐Ÿ†"}, 
}

# ๐Ÿงพ Fetch and format headlines
# UPDATED: To match the exact "NUSE DAILY" format and new item format
def fetch_cached_headlines() -> str:
    try:
        raw = redis_client.get("daily_news_feed_cache") 
        if not raw:
            logging.warning("โš ๏ธ No detailed news headlines found in cache.")
            return "โš ๏ธ No daily headlines found in cache."
        data = json.loads(raw)
    except Exception as e:
        logging.error(f"โŒ Error reading from Redis: {e}")
        return f"โŒ Error reading from Redis: {e}"

    # Get current date for the header
    today = datetime.date.today()
    formatted_date = today.strftime("%B %d, %Y")

    message_parts = []

    # Header section
    message_parts.append(f"Nuse Daily - {formatted_date}")
    message_parts.append("") 

    # Iterate through topics in a defined order for consistent output
    for topic_key, display_info in TOPIC_DISPLAY_MAP.items(): 
        stories_for_topic = data.get(topic_key) 
        
        if stories_for_topic: 
            message_parts.append(f"{display_info['emoji']} *{display_info['name']}*")
            
            sorted_story_ids = sorted(stories_for_topic.keys(), key=int) 

            for ref_id in sorted_story_ids:
                item = stories_for_topic[ref_id]
                summary = item.get("summary", "") 
                description = item.get("explanation", "") 
                
                # <<< UPDATED: Item format to "1. <summary> - <explanation>" >>>
                # Using U+2007 (Figure Space) for alignment
                message_parts.append(f"\u2007{ref_id}. \u2007{summary} - {description}")
            message_parts.append("") 

    # Footer section
    message_parts.append("")
    message_parts.append("Curated by Nuse.")

    return "\n".join(message_parts)

# ๐Ÿ“ค Send via Gupshup WhatsApp API
def send_to_whatsapp(message_text: str, destination_number: str) -> dict: 
    # Validate critical environment variables
    if not WHATSAPP_TOKEN or \
       not GUPSHUP_SOURCE_NUMBER or \
       not GUPSHUP_APP_NAME:
        error_msg = "โŒ Missing one or more critical WhatsApp API environment variables (WHATSAPP_TOKEN, GUPSHUP_SOURCE_NUMBER, GUPSHUP_APP_NAME)."
        logging.error(error_msg)
        return {"status": "failed", "error": error_msg, "code": 500}
    
    if not destination_number:
        error_msg = "โŒ Destination number cannot be empty."
        logging.error(error_msg)
        return {"status": "failed", "error": error_msg, "code": 400}


    headers = {
        "Content-Type": "application/x-www-form-urlencoded",
        "apikey": WHATSAPP_TOKEN, 
        "Cache-Control": "no-cache",
        "accept": "application/json" 
    }

    whatsapp_message_content = {
        "type": "text",
        "text": message_text 
    }
    
    payload = {
        "channel": "whatsapp",
        "source": GUPSHUP_SOURCE_NUMBER,
        "destination": destination_number,
        "src.name": GUPSHUP_APP_NAME,
        "message": message_text,
        "disablePreview": False, 
        "encode": False          
    }

    try:
        logging.info(f"Attempting to send standard text WhatsApp message to {destination_number}, {GUPSHUP_SOURCE_NUMBER}, {GUPSHUP_APP_NAME}, {WHATSAPP_TOKEN} via Gupshup. API URL: {WHATSAPP_API_URL} and message text is {message_text}")
        response = requests.post(
            WHATSAPP_API_URL, 
            headers=headers,
            data=payload, 
        )
        response.raise_for_status() 

        return {"status": "success", "details": response.json()}
    except requests.exceptions.RequestException as e:
        logging.error(f"โŒ Failed to send WhatsApp message: {e}")
        return {"status": "failed", "error": str(e), "code": e.response.status_code if e.response else 500}
    except Exception as e:
        logging.error(f"โŒ An unexpected error occurred during WhatsApp send: {e}")
        return {"status": "failed", "error": str(e), "code": 500}