diff --git a/src/curaflow_agent/activities.py b/src/curaflow_agent/activities.py index 360f99f..fc182ea 100644 --- a/src/curaflow_agent/activities.py +++ b/src/curaflow_agent/activities.py @@ -92,15 +92,36 @@ async def analyze_lab_anomaly_activity(input_data: dict) -> dict: return result.model_dump() +def _send_via_local_gateway(to: str, message: str) -> bool: + """Helper to send message via the local WhatsApp web gateway.""" + use_local = os.environ.get("USE_LOCAL_WHATSAPP", "true").lower() == "true" + gateway_url = os.environ.get("LOCAL_WHATSAPP_URL", "http://localhost:5001/send-message") + if not use_local: + return False + try: + import urllib.request + import json + payload = json.dumps({"to": to, "message": message}).encode('utf-8') + req = urllib.request.Request( + gateway_url, + data=payload, + headers={'Content-Type': 'application/json'}, + method='POST' + ) + with urllib.request.urlopen(req, timeout=8) as response: + res_data = json.loads(response.read().decode('utf-8')) + if res_data.get("success"): + print(f"[Activities] WhatsApp message sent via local gateway to {res_data.get('recipient')}") + return True + except Exception as e: + print(f"[Activities] Local WhatsApp gateway failed: {e}. Falling back...") + return False + @activity.defn async def send_alert_activity(alert_data: dict) -> str: """ Mocks sending an alert to the physician. """ - # Real Twilio WhatsApp Integration - from twilio.rest import Client - import traceback - # Credentials from environment or fallbacks account_sid = os.environ.get("TWILIO_ACCOUNT_SID", "AC601e1962dc8417ddb3ae53cd8d865020") auth_token = os.environ.get("TWILIO_AUTH_TOKEN", "08a68571a251d6d62f60dc83fc725b5a") @@ -109,19 +130,27 @@ async def send_alert_activity(alert_data: dict) -> str: msg_body = f"🚨 *CURAFLOW CRITICAL ALERT* 🚨\n\n*Anomaly Detected:*\n{alert_data.get('danger_explanation', 'Unknown danger')}\n\n*Recommended Action:*\n{alert_data.get('recommended_action', 'Review immediately.')}" - print(f"!!! Triggering Real Twilio WhatsApp Alert to {physician_number} !!!") + print(f"!!! Triggering WhatsApp Alert to {physician_number} !!!") + # 1. Try local gateway first + if _send_via_local_gateway(physician_number, msg_body): + return f"WhatsApp alert dispatched via local gateway" + + # 2. Twilio Fallback try: + from twilio.rest import Client + import traceback client = Client(account_sid, auth_token) message = client.messages.create( from_=twilio_from, body=msg_body, to=physician_number ) - print(f"WhatsApp message sent successfully! SID: {message.sid}") - return f"WhatsApp alert dispatched (SID: {message.sid})" + print(f"WhatsApp message sent successfully via Twilio! SID: {message.sid}") + return f"WhatsApp alert dispatched via Twilio (SID: {message.sid})" except Exception as e: - print(f"Failed to send WhatsApp message: {str(e)}") + print(f"Failed to send WhatsApp message via Twilio: {str(e)}") + import traceback traceback.print_exc() return f"Failed to dispatch WhatsApp alert: {str(e)}" @@ -238,17 +267,22 @@ async def parse_booking_intent_activity(payload: dict) -> dict: @activity.defn async def send_whatsapp_reply_activity(payload: dict) -> str: """ - Sends a WhatsApp message using Twilio API. + Sends a WhatsApp message using local gateway or falls back to Twilio. payload: {"phone_number": "whatsapp:+123...", "message": "..."} """ + phone_number = payload.get("phone_number") + message_body = payload.get("message") + + # 1. Try local gateway first + if _send_via_local_gateway(phone_number, message_body): + return f"Sent via local gateway" + + # 2. Twilio Fallback from twilio.rest import Client import traceback - account_sid = os.environ.get("TWILIO_ACCOUNT_SID", "AC601e1962dc8417ddb3ae53cd8d865020") auth_token = os.environ.get("TWILIO_AUTH_TOKEN", "08a68571a251d6d62f60dc83fc725b5a") twilio_from = os.environ.get("TWILIO_FROM_NUMBER", "whatsapp:+14155238886") - phone_number = payload.get("phone_number") - message_body = payload.get("message") try: client = Client(account_sid, auth_token) @@ -257,10 +291,10 @@ async def send_whatsapp_reply_activity(payload: dict) -> str: body=message_body, to=phone_number ) - print(f"WhatsApp reply sent! SID: {message.sid}") - return f"Sent (SID: {message.sid})" + print(f"WhatsApp reply sent via Twilio! SID: {message.sid}") + return f"Sent via Twilio (SID: {message.sid})" except Exception as e: - print(f"Failed to send WhatsApp reply: {str(e)}") + print(f"Failed to send WhatsApp reply via Twilio: {str(e)}") traceback.print_exc() return f"Failed: {str(e)}"