diff --git a/apps/core/models.py b/apps/core/models.py index 56987d4..0a5682e 100644 --- a/apps/core/models.py +++ b/apps/core/models.py @@ -1,2 +1,35 @@ from django.db import models +from django.db.models import TextChoices from django.utils.translation import gettext_lazy as _ + +from apps.gooyal_oauth2.settings import oauth2_settings +from utils.clients.sms.sms import BaseSMSClient +from utils.models import BaseModel +from utils.clients.sms.payam_sms.client import PayamSMSClient +from utils.clients.sms.mobin_sms.client import MobinSMSClient +from utils.clients.sms.fake.client import FakeClient + +import logging +logger = logging.getLogger(__name__) + + + +class SMSClienChoises(TextChoices): + FAKE = "fake", _("fake") + PAYAM_SMS = 'payam_sms', _('payam_sms') + MOBIN_SMS = 'mobin_sms', _('mobin_sms') + +class SMSPolicy(BaseModel): + application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL, on_delete=models.PROTECT, + related_name='+', null=True, blank=True, unique=True) + preferred = models.CharField(max_length=16, choices=SMSClienChoises.choices, default=SMSClienChoises.FAKE) + + @staticmethod + def get_client() -> BaseSMSClient: + policy = SMSPolicy.objects.get_or_create(application=None)[0] + if policy.preferred == SMSClienChoises.MOBIN_SMS: + return MobinSMSClient() + elif policy.preferred == SMSClienChoises.PAYAM_SMS: + return PayamSMSClient() + else: + return FakeClient() diff --git a/apps/users/models.py b/apps/users/models.py index 4da2cee..2eb6c67 100644 --- a/apps/users/models.py +++ b/apps/users/models.py @@ -15,8 +15,7 @@ from django.utils.translation import gettext_lazy as _ import uuid from django_minio_backend import MinioBackend, iso_date_prefix - -from utils.clients.payam_sms import send_sms +from apps.core.models import SMSPolicy from .provinces_and_cities import state # from .tasks import send_notification @@ -250,10 +249,11 @@ class User(AbstractUser): # # f"code is: {body}\n" # f"{settings.SMS_OTP_SIGNITURE}" ) - if settings.SMS_SEND: - send_sms(self.phone_number.strip('+'), message) - else: - logger.info(f'otp for: {self.phone_number} is {message}') + + sms_client = SMSPolicy.get_client() + sms_client.send_sms(self.phone_number.strip('+'), message) + + logger.info(f'otp for: {self.phone_number} is {message}') return # TODO: enable celery send_notification( diff --git a/utils/clients/mobin_sms/client.py b/utils/clients/mobin_sms/client.py deleted file mode 100644 index d23c5e0..0000000 --- a/utils/clients/mobin_sms/client.py +++ /dev/null @@ -1,34 +0,0 @@ -import urllib.parse -import requests - -from django.conf import settings - - -class MobinSMSClient: - access_token = settings.MOBIN_SMS_TOKEN - base_url = 'https://connect.mobinsms.com' - sender = '9890008050' - - def send_sms(self, phone_number, message): - return self.send_sms_quick([phone_number], message) - - def send_sms_quick(self, phone_number_list, message): - path = '/v1/send/quick' - url = urllib.parse.urljoin(self.base_url, path) - - body = { - "from": self.sender, - "to": phone_number_list, - "body": message, - "unique_id": "" # UDH (optional field) - } - - headers = { - "X-API-Key": self.access_token, - 'Content-Type': 'application/json', - 'Accept': 'application/json', - } - - response = requests.post(url, headers=headers, json=body, timeout=10) - print(response.text) - return response.json() diff --git a/utils/clients/payam_sms.py b/utils/clients/payam_sms.py deleted file mode 100644 index 6f6295d..0000000 --- a/utils/clients/payam_sms.py +++ /dev/null @@ -1,50 +0,0 @@ -# TODO: this is time fourced code. refactor - -import requests -from django.conf import settings - - -def get_access_token(): - payam_sms_system_name = settings.PAYAM_SMS_SYSTEM_NAME - payam_sms_username = settings.PAYAM_SMS_USERNAME - payam_sms_password = settings.PAYAM_SMS_PASSWORD - payam_sms_client_id = settings.PAYAM_SMS_CLIENT_ID - payam_sms_client_secret = settings.PAYAM_SMS_CLIENT_SECRET - auth = (payam_sms_client_id, payam_sms_client_secret) - url = f"https://www.payamsms.com/auth/oauth/token?systemName={payam_sms_system_name}&username={payam_sms_username}&password={payam_sms_password}&scope=webservice&grant_type=password" - - response_object = requests.post(url, auth=auth, json={}) - response = response_object.json() - return response["access_token"] - - -def send_sms(phone_number, message): - try: - url = "https://www.payamsms.com/panel/webservice/send" - - # access_token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJzb2JhbiIsInNjb3BlIjpbIndlYnNlcnZpY2UiXSwiZXhwIjoxNzQ0MTAyMDU5LCJ1c2VyRGV0YWlscyI6eyJpZCI6MjU0MCwidXNlck5hbWUiOiJzb2JhbiIsInJvbGUiOiJVU0VSIiwiZW5hYmxlZCI6dHJ1ZSwic3lzdGVtSWQiOjcyMiwiYWNjZXNzIjp7InJvbGUiOlsiYWRkIiwiZWRpdCIsImdldCIsImRlbGV0ZSJdLCJwaG9uZUJvb2siOlsiYWRkIiwiZWRpdCIsImdldExvY2FsIiwiZ2V0R2xvYmFsIiwiZGVsZXRlIl0sInNtcyI6WyJzaW5nbGUiLCJnZXRMb2NhbCIsImdldEdsb2JhbCIsImJ1bGsiLCJkYiJdLCJyZXBvcnQiOlsiZ2V0TW9HbG9iYWwiLCJnZXREYWlseUxvY2FsIiwiZ2V0TW9Mb2NhbCIsImdldERhaWx5R2xvYmFsIl0sIndzIjpbIndzIl0sInVzZXIiOlsiYWRkIiwiZWRpdCIsImdldExvY2FsIiwiZ2V0IiwiZ2V0R2xvYmFsIiwiZGVsZXRlIl0sInRvb2xzIjpbInJhY2UiLCJwZXJpb2RpYyIsInBvbGxpbmciLCJzZWNyZXRvcnkiLCJhdXRvYW5zd2VyIl0sImZpbmFuY2UiOlsidGRyIiwiY2hhcmdlIl19LCJyb2xlSWQiOjQ0NDAsImNoaWxkcmVuSWRzIjpbXSwic3lzdGVtVHlwZSI6Ik5PUk1BTCIsInN5c3RlbVBheW1lbnRUeXBlIjoiREVCSVQiLCJzeXN0ZW1OYW1lIjoic29iYW4iLCJzZW5kV2l0aE91dFBlcm1pc3Npb25TeXN0ZW0iOmZhbHNlLCJtaXNDdXN0b21lciI6Itio2YbYr9in2LEg2LPZiNio2KfZhiDYs9in2YXYp9mG2YciLCJwYXJlbnRVc2VyTmFtZSI6bnVsbCwicGFyZW50SWQiOm51bGwsImFkbWluIjp0cnVlfSwiYXV0aG9yaXRpZXMiOlsiVVNFUiJdLCJqdGkiOiJNeU5vTml2RURmc3YxUDR3U20tbTR2Y2NHODgiLCJjbGllbnRfaWQiOiJzb2JhbiJ9.9mdneDduK4OVH2zsXvRqvXt2qwpLvs0vCuseLaB-LCo' - access_token = get_access_token() - - body = [ - { - "sender": "98200000443295", - "recipient": phone_number, - "body": message, - # "customerId": "1", - # "sendDate": "2024-03-04 10:17:00" - } - ] - - headers = { - 'Authorization': f'Bearer {access_token}', - 'Content-Type': 'application/json', - 'Accept': 'application/json', - } - - response_object = requests.post(url, headers=headers, json=body, timeout=10) - print(response_object.text) - except Exception as e: - print(e) - - -# send_sms("989106853582", "تست") diff --git a/utils/clients/sms/mobin_sms/client.py b/utils/clients/sms/mobin_sms/client.py new file mode 100644 index 0000000..93ec55f --- /dev/null +++ b/utils/clients/sms/mobin_sms/client.py @@ -0,0 +1,43 @@ +import urllib.parse +import requests + +from django.conf import settings +import logging + +from utils.clients.sms.sms import BaseSMSClient + +logger = logging.getLogger(__name__) + +class MobinSMSClient(BaseSMSClient): + access_token = settings.MOBIN_SMS_TOKEN + base_url = 'https://connect.mobinsms.com' + sender = '9890008050' + + def send_sms(self, phone_number, message): + return self.send_sms_quick([phone_number], message) + + def send_sms_quick(self, phone_number_list, message): + try: + path = '/v1/send/quick' + url = urllib.parse.urljoin(self.base_url, path) + + body = { + "from": self.sender, + "to": phone_number_list, + "body": message, + "unique_id": "" # UDH (optional field) + } + + headers = { + "X-API-Key": self.access_token, + 'Content-Type': 'application/json', + 'Accept': 'application/json', + } + + response = requests.post(url, headers=headers, json=body, timeout=10) + logger.info(response.text) + return response.json() + + except Exception as e: + logger.exception(f'error sending sms to {phone_number_list}: {e}') + diff --git a/utils/clients/sms/payam_sms/client.py b/utils/clients/sms/payam_sms/client.py new file mode 100644 index 0000000..ec4b57b --- /dev/null +++ b/utils/clients/sms/payam_sms/client.py @@ -0,0 +1,54 @@ +# TODO: this is time fourced code. refactor + +import requests +from django.conf import settings +import logging + +from utils.clients.sms.sms import BaseSMSClient + +logger = logging.getLogger(__name__) + +class PayamSMSClient(BaseSMSClient): + def get_access_token(self): + payam_sms_system_name = settings.PAYAM_SMS_SYSTEM_NAME + payam_sms_username = settings.PAYAM_SMS_USERNAME + payam_sms_password = settings.PAYAM_SMS_PASSWORD + payam_sms_client_id = settings.PAYAM_SMS_CLIENT_ID + payam_sms_client_secret = settings.PAYAM_SMS_CLIENT_SECRET + auth = (payam_sms_client_id, payam_sms_client_secret) + url = f"https://www.payamsms.com/auth/oauth/token?systemName={payam_sms_system_name}&username={payam_sms_username}&password={payam_sms_password}&scope=webservice&grant_type=password" + + response_object = requests.post(url, auth=auth, json={}) + response = response_object.json() + return response["access_token"] + + + def send_sms(self, phone_number, message): + try: + url = "https://www.payamsms.com/panel/webservice/send" + + # access_token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJzb2JhbiIsInNjb3BlIjpbIndlYnNlcnZpY2UiXSwiZXhwIjoxNzQ0MTAyMDU5LCJ1c2VyRGV0YWlscyI6eyJpZCI6MjU0MCwidXNlck5hbWUiOiJzb2JhbiIsInJvbGUiOiJVU0VSIiwiZW5hYmxlZCI6dHJ1ZSwic3lzdGVtSWQiOjcyMiwiYWNjZXNzIjp7InJvbGUiOlsiYWRkIiwiZWRpdCIsImdldCIsImRlbGV0ZSJdLCJwaG9uZUJvb2siOlsiYWRkIiwiZWRpdCIsImdldExvY2FsIiwiZ2V0R2xvYmFsIiwiZGVsZXRlIl0sInNtcyI6WyJzaW5nbGUiLCJnZXRMb2NhbCIsImdldEdsb2JhbCIsImJ1bGsiLCJkYiJdLCJyZXBvcnQiOlsiZ2V0TW9HbG9iYWwiLCJnZXREYWlseUxvY2FsIiwiZ2V0TW9Mb2NhbCIsImdldERhaWx5R2xvYmFsIl0sIndzIjpbIndzIl0sInVzZXIiOlsiYWRkIiwiZWRpdCIsImdldExvY2FsIiwiZ2V0IiwiZ2V0R2xvYmFsIiwiZGVsZXRlIl0sInRvb2xzIjpbInJhY2UiLCJwZXJpb2RpYyIsInBvbGxpbmciLCJzZWNyZXRvcnkiLCJhdXRvYW5zd2VyIl0sImZpbmFuY2UiOlsidGRyIiwiY2hhcmdlIl19LCJyb2xlSWQiOjQ0NDAsImNoaWxkcmVuSWRzIjpbXSwic3lzdGVtVHlwZSI6Ik5PUk1BTCIsInN5c3RlbVBheW1lbnRUeXBlIjoiREVCSVQiLCJzeXN0ZW1OYW1lIjoic29iYW4iLCJzZW5kV2l0aE91dFBlcm1pc3Npb25TeXN0ZW0iOmZhbHNlLCJtaXNDdXN0b21lciI6Itio2YbYr9in2LEg2LPZiNio2KfZhiDYs9in2YXYp9mG2YciLCJwYXJlbnRVc2VyTmFtZSI6bnVsbCwicGFyZW50SWQiOm51bGwsImFkbWluIjp0cnVlfSwiYXV0aG9yaXRpZXMiOlsiVVNFUiJdLCJqdGkiOiJNeU5vTml2RURmc3YxUDR3U20tbTR2Y2NHODgiLCJjbGllbnRfaWQiOiJzb2JhbiJ9.9mdneDduK4OVH2zsXvRqvXt2qwpLvs0vCuseLaB-LCo' + access_token = self.get_access_token() + + body = [ + { + "sender": "98200000443295", + "recipient": phone_number, + "body": message, + # "customerId": "1", + # "sendDate": "2024-03-04 10:17:00" + } + ] + + headers = { + 'Authorization': f'Bearer {access_token}', + 'Content-Type': 'application/json', + 'Accept': 'application/json', + } + + response_object = requests.post(url, headers=headers, json=body, timeout=10) + logger.info(response_object.text) + return response_object + except Exception as e: + logger.exception(f'error sending sms to {phone_number}: {e}') +