"""Telnyx SMS provider via Telnyx's Programmable Messaging REST API (no SDK dependency - just a Bearer-authenticated POST), mirroring twilio_sms.py's shape. No-ops with a clear error if Telnyx isn't configured; the caller (alert_service) is what additionally gates on `NOTIFICATION_SMS_ENABLED` before ever constructing this provider. """ from __future__ import annotations import httpx from app.core.config import Settings from app.notifications.base import DeliveryResult, NotificationMessage _API_URL = "https://api.telnyx.com/v2/messages" class TelnyxSmsProvider: provider_name = "telnyx_sms" def __init__(self, settings: Settings) -> None: self._settings = settings async def send(self, message: NotificationMessage) -> DeliveryResult: settings = self._settings if not (settings.telnyx_api_key and settings.telnyx_from_number): return DeliveryResult(success=False, error="Telnyx is not configured") try: async with httpx.AsyncClient(timeout=15) as client: response = await client.post( _API_URL, headers={"Authorization": f"Bearer {settings.telnyx_api_key}"}, json={ "from": settings.telnyx_from_number, "to": message.destination_value, "text": message.body_text, }, ) except httpx.HTTPError as exc: return DeliveryResult(success=False, error=str(exc)) data = response.json() if response.status_code >= 400: errors = data.get("errors") or [] detail = errors[0].get("detail") if errors else response.text[:200] return DeliveryResult( success=False, error=f"Telnyx error {response.status_code}: {detail}" ) return DeliveryResult(success=True, external_message_id=data.get("data", {}).get("id"))