Initial commit: CI Agent competitive-intelligence monitoring app

FastAPI + Celery + Next.js + Postgres/Redis app with company monitoring,
source collection, LLM-based change analysis, enrichment, and account
security (Turnstile, escalating lockout, email verification).
This commit is contained in:
2026-08-05 10:48:20 -04:00
commit 1a4c80958f
365 changed files with 43541 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
"""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"))