Files
khatibi/integrations/sms/http.py
T
2026-10-10 14:21:04 +03:30

50 lines
2.3 KiB
Python

"""Provider عمومی مبتنی بر HTTP؛ مقادیر از SMSProviderConfig خوانده می‌شوند."""
import requests
from .base import SMSProvider, SMSResult
from .normalize import normalize_mobile
class HTTPSMSProvider(SMSProvider):
def __init__(self, config=None):
self.config = config
def send_message(self, mobile, message):
config = self.config
if config is None or not config.api_url:
return SMSResult(False, error="آدرس سرویس پیامک (api_url) تنظیم نشده است.")
if not normalize_mobile(str(mobile)):
return SMSResult(
False, provider_code="INVALID_NUMBER",
error="شمارهٔ موبایل گیرنده معتبر نیست.",
)
headers = {"Accept": "application/json", "Content-Type": "application/json"}
if config.api_token:
headers["Authorization"] = f"Bearer {config.api_token}"
try:
response = requests.post(
config.api_url,
json={"to": mobile, "message": message, "sender": config.sender},
headers=headers,
timeout=config.timeout_seconds or 30,
)
response.raise_for_status()
try:
data = response.json() if response.content else {}
except ValueError:
# بدنهٔ پاسخ JSON نبود (مثلاً صفحهٔ HTML خطای سرویس‌دهنده).
return SMSResult(
False, provider_code="BAD_RESPONSE",
error=f"پاسخ سرویس پیامک JSON معتبر نبود (HTTP {response.status_code}).",
)
# بعضی سرویس‌دهنده‌ها به‌جای آبجکت، لیست برمی‌گردانند.
if isinstance(data, list):
data = data[0] if data and isinstance(data[0], dict) else {}
elif not isinstance(data, dict):
data = {}
if data.get("success") is False:
return SMSResult(False, error=str(data.get("error", "Provider rejected SMS")))
return SMSResult(True, str(data.get("id") or data.get("message_id") or "http"))
except requests.RequestException as exc:
return SMSResult(False, error=str(exc))