Add recipient notification detail and filtering, a queued admin composer, and contextual automatic titles. Retire email delivery, obsolete auth routes, newsletter data, and related templates and settings.
73 lines
2.4 KiB
Python
73 lines
2.4 KiB
Python
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)
|