import os import logging from datetime import datetime from groq import Groq from twilio.rest import Client from dotenv import load_dotenv load_dotenv() logging.basicConfig(format="%(asctime)s | %(levelname)s | %(message)s", level=logging.INFO) logger = logging.getLogger(__name__) BOT_TOKEN = os.environ["TELEGRAM_BOT_TOKEN"] MY_USER_ID = int(os.environ["TELEGRAM_USER_ID"]) WIFE_NUMBER = os.environ["WIFE_WHATSAPP_NUMBER"] TWILIO_FROM = os.environ["TWILIO_WHATSAPP_FROM"] TWILIO_SID = os.environ["TWILIO_ACCOUNT_SID"] TWILIO_TOKEN = os.environ["TWILIO_AUTH_TOKEN"] GROQ_KEY = os.environ["GROQ_API_KEY"] groq_client = Groq(api_key=GROQ_KEY) twilio_client = Client(TWILIO_SID, TWILIO_TOKEN) SYSTEM_PROMPT = "You are a helpful assistant that converts short personal status updates from a husband into warm WhatsApp messages to his wife. Return ONLY the final message text. No quotes, no explanations. Keep it friendly, casual, and under 2 sentences. Add a relevant emoji at the end." FALLBACK_TEMPLATES = { "office": "Hey! Reached office safely", "lunch": "Just had lunch, all good!", "late": "Running late today, will update soon", "home": "Reached home safely!", "meeting": "In a meeting, will reply later", "leaving": "Leaving office now, on my way!", } message_log = [] TELEGRAM_API = "https://api.telegram.org/bot" + BOT_TOKEN def generate_whatsapp_message(user_input): try: response = groq_client.chat.completions.create( model="llama3-8b-8192", messages=[ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": user_input}, ], temperature=0.7, max_tokens=100, ) return response.choices[0].message.content.strip() except Exception as e: logger.error("Groq error: %s", e) lower = user_input.lower() for keyword, template in FALLBACK_TEMPLATES.items(): if keyword in lower: return template return "Quick update: " + user_input def send_whatsapp(message): try: result = twilio_client.messages.create( body=message, from_="whatsapp:" + TWILIO_FROM, to="whatsapp:" + WIFE_NUMBER, ) logger.info("WhatsApp sent: SID=%s", result.sid) return True except Exception as e: logger.error("Twilio error: %s", e) return False def log_message(user_input, sent_message, success): message_log.append({ "time": datetime.now().strftime("%d %b %H:%M"), "input": user_input, "sent": sent_message, "success": success, }) if len(message_log) > 20: message_log.pop(0) async def send_telegram_reply(chat_id, text): """Send reply back to Telegram using httpx directly.""" import httpx url = TELEGRAM_API + "/sendMessage" payload = {"chat_id": chat_id, "text": text} try: async with httpx.AsyncClient() as client: await client.post(url, json=payload, timeout=10) except Exception as e: logger.error("Telegram reply error: %s", e) async def handle_update(data: dict): """Process incoming Telegram webhook update.""" message = data.get("message") or data.get("edited_message") if not message: return chat_id = message["chat"]["id"] user_id = message["from"]["id"] text = message.get("text", "").strip() if not text: return # Security check if user_id != MY_USER_ID: await send_telegram_reply(chat_id, "Sorry, this bot is private.") return # Handle commands if text == "/start": await send_telegram_reply(chat_id, "Status Bot is ready!\n\n" "Just type any update and I will send a WhatsApp to your wife.\n\n" "Examples:\n" "- reached office\n" "- had lunch\n" "- coming late, around 9pm\n" "- leaving office now\n\n" "Type /test to send a test message\n" "Type /history to see last 5 sent messages" ) return if text == "/test": await send_telegram_reply(chat_id, "Sending test message to your wife...") success = send_whatsapp("Test message from Status Bot - everything is working!") if success: await send_telegram_reply(chat_id, "Test sent successfully!") else: await send_telegram_reply(chat_id, "Failed. Check Twilio credentials in HF Secrets.") return if text == "/history": if not message_log: await send_telegram_reply(chat_id, "No messages sent yet.") return lines = ["Last messages:\n"] for entry in reversed(message_log[-5:]): status = "OK" if entry["success"] else "FAILED" lines.append("[" + status + "] " + entry["time"] + "\nYou: " + entry["input"] + "\nSent: " + entry["sent"] + "\n") await send_telegram_reply(chat_id, "\n".join(lines)) return # Normal message - generate and send WhatsApp await send_telegram_reply(chat_id, "Generating message...") whatsapp_msg = generate_whatsapp_message(text) success = send_whatsapp(whatsapp_msg) log_message(text, whatsapp_msg, success) if success: await send_telegram_reply(chat_id, "Sent to wife:\n" + whatsapp_msg) else: await send_telegram_reply(chat_id, "Failed to send.\nMessage was: " + whatsapp_msg)