fix bug sms

This commit is contained in:
javad committed 2026-10-09 10:32:27 +03:30
1 parent 48d0ecba79
commit ae4dbab3cc
5 files changed
+93 -13

No files matched your search

+30 -5
View File
@@ -1,22 +1,25 @@
from abc import ABC, abstractmethod
import requests
import logging
from django.conf import settings
logger = logging.getLogger(__name__)
class SmsProviderABC(ABC):
@abstractmethod
def send_sms(self, mobile: str, message: str) -> bool:
def send_sms(self, mobile: str, message: str) -> bool | None:
pass
class DefaultSmsProvider(SmsProviderABC):
def send_sms(self, mobile: str, message: str) -> bool:
def send_sms(self, mobile: str, message: str) -> bool | None:
default_provider = DosefrNavadHashtSMS()
return default_provider.send_sms(mobile, message)
class DosefrNavadHashtSMS(SmsProviderABC):
def send_sms(self, mobile: str, message: str) -> bool:
def send_sms(self, mobile: str, message: str) -> bool | None:
payload = {
'USERNAME': 'vsms7937',
'PASSWORD': '335577775533',
@@ -27,9 +30,31 @@ class DosefrNavadHashtSMS(SmsProviderABC):
try:
r = requests.get('http://www.0098sms.com/sendsmslink.aspx', params=payload, timeout=10)
r.raise_for_status()
except (requests.Timeout, requests.ConnectionError):
# The provider may have dispatched the SMS before its reply was lost.
logger.warning('SMS provider reply unavailable; dispatch is unconfirmed')
return None
except requests.HTTPError as error:
if error.response is not None and error.response.status_code >= 500:
logger.warning('SMS provider server error; dispatch is unconfirmed')
return None
return False
except requests.RequestException:
return False
# An HTTP 200 alone does not mean the SMS provider accepted the message.
# Unknown bodies are NOT evidence of rejection. In particular, never
# discard a delivered OTP just because the response contract differs.
success_codes = getattr(settings, 'SMS_SUCCESS_CODES', ('0',))
return r.text.strip() in success_codes
failure_codes = getattr(settings, 'SMS_FAILURE_CODES', ('error',))
body = r.text.strip().lstrip('\ufeff').strip()
def codes(values):
if isinstance(values, str):
values = values.split(',')
return {str(value).strip() for value in values}
if body in codes(success_codes):
return True
if body in codes(failure_codes):
return False
# Do not log the reply, URL, credentials, mobile, or OTP.
logger.warning('SMS provider returned an unrecognized reply; dispatch is unconfirmed')
return None