61 lines
2.1 KiB
Python
61 lines
2.1 KiB
Python
import logging
|
|
from typing import Any
|
|
|
|
import httpx
|
|
|
|
from gapido_auth.domain.errors import ExternalServiceError
|
|
from gapido_auth.domain.ports import SmsClient
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class SmsIrSmsClient(SmsClient):
|
|
"""SMS.ir verify API implementation of the SMS provider strategy."""
|
|
|
|
_endpoint = "https://api.sms.ir/v1/send/verify"
|
|
|
|
def __init__(
|
|
self,
|
|
api_key: str,
|
|
timeout_seconds: float = 10.0,
|
|
transport: httpx.AsyncBaseTransport | None = None,
|
|
) -> None:
|
|
"""Configure credentials, timeout, and optional test transport."""
|
|
self._api_key = api_key
|
|
self._timeout_seconds = timeout_seconds
|
|
self._transport = transport
|
|
|
|
async def send_otp(self, mobile: str, code: str, template: str) -> None:
|
|
"""Send an OTP through SMS.ir using the configured verify template id."""
|
|
|
|
headers = {
|
|
"Content-Type": "application/json",
|
|
"Accept": "application/json",
|
|
"x-api-key": self._api_key,
|
|
}
|
|
payload = {
|
|
"mobile": mobile,
|
|
"templateId": int(template),
|
|
"parameters": [{"name": "OTP", "value": code}],
|
|
}
|
|
|
|
try:
|
|
async with httpx.AsyncClient(
|
|
timeout=self._timeout_seconds, transport=self._transport
|
|
) as client:
|
|
response = await client.post(self._endpoint, json=payload, headers=headers)
|
|
except httpx.HTTPError as exc:
|
|
logger.warning("SMS.ir network error for mobile=%s", mobile, exc_info=True)
|
|
raise ExternalServiceError("SMS.ir network error") from exc
|
|
|
|
if response.status_code != 200:
|
|
logger.warning("SMS.ir HTTP error status=%s mobile=%s", response.status_code, mobile)
|
|
raise ExternalServiceError("SMS.ir HTTP error")
|
|
|
|
data: dict[str, Any] = response.json()
|
|
if str(data.get("status", "")) != "1":
|
|
logger.warning("SMS.ir API error status=%s mobile=%s", data.get("status"), mobile)
|
|
raise ExternalServiceError("SMS.ir API error")
|
|
|
|
logger.info("OTP SMS sent successfully to mobile=%s via SMS.ir", mobile)
|