import logging import requests from celery import shared_task from django.conf import settings logger = logging.getLogger(__name__) SMS_ENDPOINT = "https://api.sms.ir/v1/send/verify" SMS_TEMPLATE_MAP = { "auth_register_otp": "SMS_AUTH_OTP_TEMPLATE_ID", "auth_login_otp": "SMS_AUTH_OTP_TEMPLATE_ID", "auth_reset_password_otp": "SMS_AUTH_OTP_TEMPLATE_ID", "auth_verify_mobile_otp": "SMS_AUTH_OTP_TEMPLATE_ID", "event_cancellation": "SMS_EVENT_CANCELLATION_TEMPLATE_ID", "event_reschedule": "SMS_EVENT_RESCHEDULE_TEMPLATE_ID", "payment_status": "SMS_PAYMENT_STATUS_TEMPLATE_ID", } def _template_id_for_kind(kind: str) -> str: setting_name = SMS_TEMPLATE_MAP.get(kind, "") return getattr(settings, setting_name, "") if setting_name else "" def _send_sms(receptor: str, template_id: str | int, variables: list[dict] | None = None): headers = { "Content-Type": "application/json", "Accept": "application/json", "x-api-key": settings.SMS_APIKEY, } payload = { "mobile": receptor, "templateId": int(template_id), "parameters": variables or [], } response = requests.post( SMS_ENDPOINT, json=payload, headers=headers, timeout=10, ) response.raise_for_status() return response @shared_task(bind=True, max_retries=3) def send_critical_sms(self, mobile: str, kind: str, code_or_message: str): try: template_id = _template_id_for_kind(kind) if not template_id or not settings.SMS_APIKEY: logger.info( "SMS skipped for mobile=%s kind=%s template=%s configured=%s payload=%s", mobile, kind, bool(template_id), bool(settings.SMS_APIKEY), code_or_message, ) return {"mobile": mobile, "kind": kind, "sent": False} variables = [{"name": "OTP", "value": str(code_or_message)}] if kind in {"event_cancellation", "event_reschedule", "payment_status"}: variables = [{"name": "MESSAGE", "value": str(code_or_message)}] _send_sms(mobile, template_id, variables=variables) logger.info("SMS sent to %s for kind=%s", mobile, kind) return {"mobile": mobile, "kind": kind, "sent": True} except Exception as exc: logger.error("Failed to send SMS to %s for kind=%s: %s", mobile, kind, exc) raise self.retry(exc=exc, countdown=60) @shared_task(bind=True, max_retries=1) def send_verification_email(self, user_id, verification_url): logger.info("Legacy verification email task skipped for user=%s url=%s", user_id, verification_url) return {"skipped": True} @shared_task(bind=True, max_retries=1) def send_password_reset_email(self, user_id, reset_url): logger.info("Legacy password reset email task skipped for user=%s url=%s", user_id, reset_url) return {"skipped": True} @shared_task(bind=True, max_retries=1) def send_email_verified_success(self, user_id: int): logger.info("Legacy verification success email task skipped for user=%s", user_id) return {"skipped": True}