urmi-ai/backend/app/routes_messages.py
2026-10-02 11:22:40 +05:30

118 lines
3.9 KiB
Python

from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException, Response, status
from pydantic import BaseModel, Field
from sqlalchemy.orm import Session
from .api_key_auth import current_api_user
from .database import get_db
from .message_send_service import SendMessageError, send_template_messages
from .models import UserAccount
router = APIRouter(prefix="/api/v1/messages", tags=["messages"])
SEND_SMS_EXPLORER = {
"id": "send-sms",
"method": "POST",
"path": "/api/v1/messages/send",
"title": "Send template SMS",
"summary": "Send a DLT-approved SMS using an API key, approved sender ID, and template.",
"authentication": {
"type": "api_key",
"header": "Authorization",
"format": "Bearer urmi_live_<key>",
"alternate_header": "X-Api-Key",
},
"request_body": {
"sender_id": {
"type": "string",
"required": True,
"description": "Approved DLT sender header, e.g. URMIAI",
"example": "URMIAI",
},
"template_id": {
"type": "uuid",
"required": True,
"description": "Approved template UUID from Message settings",
},
"to": {
"type": "string",
"required": True,
"description": "Recipient mobile number with country code, e.g. 919999999999",
"example": "919999999999",
},
"message": {
"type": "string",
"required": True,
"description": "Final SMS text with all {#var#} / {#num#} placeholders replaced",
"example": "Your URMI app verification code is 482916. It is valid for 10 minutes. Do not share it to anyone - URMI AI",
},
},
"responses": {
"200": {
"description": "SMS accepted by the gateway",
"example": {
"success": True,
"job_id": "123456789",
"message_id": "987654321",
"to": "919999999999",
"sender_id": "URMIAI",
"template_id": "00000000-0000-0000-0000-000000000001",
"template_name": "URMI_OTP_VERIFICATION",
"dlt_template_id": "1777178797989033323",
},
},
"401": {"description": "Missing or invalid API key"},
"404": {"description": "Sender or template not found for this account"},
"422": {"description": "Template mismatch or gateway rejection"},
"502": {"description": "SMS gateway request failed"},
"503": {"description": "SMS gateway credentials are not configured"},
},
}
class SendMessageRequest(BaseModel):
sender_id: str = Field(min_length=3, max_length=11)
template_id: UUID
to: str = Field(min_length=10, max_length=15)
message: str = Field(min_length=1, max_length=1000)
@router.get("/docs/send")
def send_message_docs() -> dict:
return SEND_SMS_EXPLORER
def _raise_send_error(error: SendMessageError) -> None:
raise HTTPException(status_code=error.status_code, detail=error.detail)
@router.post("/send")
def send_message(
payload: SendMessageRequest,
db: Session = Depends(get_db),
user: UserAccount = Depends(current_api_user),
) -> dict:
try:
result = send_template_messages(
db,
user,
sender_id=payload.sender_id,
template_id=payload.template_id,
message=payload.message,
recipients=[payload.to],
)
except SendMessageError as exc:
_raise_send_error(exc)
first = result["results"][0]
return {
"success": result["success"],
"job_id": first["job_id"],
"message_id": first["message_id"],
"to": first["to"],
"sender_id": result["sender_id"],
"template_id": result["template_id"],
"template_name": result["template_name"],
"dlt_template_id": result["dlt_template_id"],
}