Files
2026-08-24 15:54:08 +03:30

65 lines
2.6 KiB
Python

# apps/messaging/providers/sms.py
"""
ارسال پیامک گروهی با متن آزاد (نه پترن OTP) — از همان کاوه‌نگاری که
apps/account/send_sms.py برای OTP استفاده می‌کند، ولی از API متفاوتی: پترن
OTP فقط اجازه‌ی ارسال یک قالب از پیش تاییدشده را می‌دهد، برای متن دلخواه باید
از API عادی ارسال (sms/sendarray.json برای چندگیرنده‌ی هم‌زمان با متن‌های
مجزا) استفاده کرد. این دو مسیر کاملا مستقل‌اند؛ send_sms.py دست‌نخورده ماند.
فقط دو مقدار از .env لازم است: KAVENEGAR_API_KEY و KAVENEGAR_SENDER_LINE.
اگر ساختار پاسخ/درخواست کاوه‌نگار حساب تو فرق دارد، فقط تابع
`_call_sendarray` را با مستندات https://kavenegar.com/rest.html هماهنگ کن.
"""
import json
import logging
import requests
from django.conf import settings
logger = logging.getLogger(__name__)
REQUEST_TIMEOUT_SECONDS = 15
KAVENEGAR_BASE = "https://api.kavenegar.com/v1"
def _call_sendarray(receptors: list[str], messages: list[str]) -> dict[str, bool]:
"""ارسال بالک؛ خروجی: {receptor: True/False} برای هر گیرنده."""
api_key = settings.KAVENEGAR_API_KEY
sender = settings.KAVENEGAR_SENDER_LINE
result = {r: False for r in receptors}
if not api_key or not sender:
logger.error("KAVENEGAR_API_KEY یا KAVENEGAR_SENDER_LINE در .env تنظیم نشده است")
return result
url = f"{KAVENEGAR_BASE}/{api_key}/sms/sendarray.json"
payload = {
"receptor": json.dumps(receptors),
"sender": json.dumps([sender] * len(receptors)),
"message": json.dumps(messages),
}
try:
response = requests.post(url, data=payload, timeout=REQUEST_TIMEOUT_SECONDS)
response.raise_for_status()
body = response.json()
if body.get("return", {}).get("status") == 200:
for r in receptors:
result[r] = True
else:
logger.error(f"❌ کاوه‌نگار خطا برگرداند: {body.get('return')}")
except (requests.RequestException, ValueError) as exc:
logger.error(f"❌ خطا در ارسال پیامک بالک: {exc}")
return result
def send_bulk_sms(recipients: list[tuple[str, str]]) -> dict[str, bool]:
"""recipients: [(phone, message), ...] -> {phone: sent_ok}"""
if not recipients:
return {}
phones = [p for p, _ in recipients]
messages = [m for _, m in recipients]
return _call_sendarray(phones, messages)