""" AUTHOR: Khushal P Soonderji DATE: Monday, 9th Dec., 2024 OBJECTIVE: To send SMS from clients like Nimbus SMS (India) and Savvy Bulk SMS (Kenya). REFERENCES: N/A DOWNLOADS: N/A """ # ***************************************************************************************************************** # ***** **** # *** IMPORT *** # ***** **** # ***************************************************************************************************************** # To make sibling directories accessible for imports: import sys sys.path.append(".") sys.path.append("..") # My async utils: from utils_v2.string import json from utils_v2.date_time import date_time from utils_v2.database.async_mysql_v2 import AsyncMySQL from utils_v2.database.async_mongo_v2 import AsyncMongo # SMS-related utils: from utils_v2.sms.models.behaviour.nimbus.async_nimbus import AsyncNimbusSMS from utils_v2.sms.models.behaviour.savvy_bulk_sms.async_savvy_bulk_sms import AsyncSavvyBulkSMS # Base model: from models.behaviour.base import BaseModel # Data models: from models.data.core.auth_token import CoreAuthTokenModel from models.data.core.message import CoreMessageModel from models.data.api.sms.send import ( SMSSendRequestHeaders, SMSSendRequestData, NimbusSMSIndiaMessage, SavvyBulkSMSKenyaMessage ) from utils_v2.sms.models.data.sms_message import SentSMSMessageModel # To work with MongoDB: from bson import ObjectId # To work with datatypes: from typing import Literal # To make deep-copies: import copy # ***************************************************************************************************************** # ***** **** # *** MACROS / ONE-TIME INIT *** # ***** **** # ***************************************************************************************************************** # --- Nothing Yet # ***************************************************************************************************************** # ***** **** # *** VARIABLES *** # ***** **** # ***************************************************************************************************************** # --- Nothing Yet # ***************************************************************************************************************** # ***** **** # *** FUNCTIONS *** # ***** **** # ***************************************************************************************************************** # --- Nothing Yet # ***************************************************************************************************************** # ***** **** # *** CLASSES *** # ***** **** # ***************************************************************************************************************** class SMSSendModel(BaseModel): MESSAGES_COLLECTION = "_messages" async def send_sms( self, mongo_conn: AsyncMongo, token_id: ObjectId | str, auth_token: CoreAuthTokenModel, inbound_data: SMSSendRequestData, session_token: str = None ) -> SentSMSMessageModel: """ To store auth/tokens for a particular service to the database. :param mongo_conn: The database connection (MongoDB) to use to perform the action. :param auth_token: An instance of the core auth-token model that holds data in the database. :param session_token: The session token of the user who requested this service. :return: An ObjectId to later store the granted tokens. """ # Basic prep: event_ts = date_time.get_current_utc_date_time(as_string = False) client_response = None message_id = None sms_sent = None # ┏┓ ┳┓• ┓ ┏┓┳┳┓┏┓ ┳ ┓• # ┣ ┏┓┏┓ ┃┃┓┏┳┓┣┓┓┏┏ ┗┓┃┃┃┗┓ ┃┏┓┏┫┓┏┓ # ┻ ┗┛┛ ┛┗┗┛┗┗┗┛┗┻┛ ┗┛┛ ┗┗┛ ┻┛┗┗┻┗┗┻ if isinstance(inbound_data.message, NimbusSMSIndiaMessage): # Prepare the client: sms_client = AsyncNimbusSMS( entity_id = auth_token.auth.get("entityId"), sender_id = auth_token.auth.get("senderId"), user_id = auth_token.auth.get("userId"), api_key = auth_token.auth.get("apiKey"), http_client = self._http_client ) # Send the SMS: client_response = await sms_client.send_sms( recipient_number = inbound_data.message.recipientNo, message = inbound_data.message.text, template_id = inbound_data.message.templateId ) # ┏┓ ┏┓ ┳┓ ┓┓ ┏┓┳┳┓┏┓ ┓┏┓ # ┣ ┏┓┏┓ ┗┓┏┓┓┏┓┏┓┏ ┣┫┓┏┃┃┏ ┗┓┃┃┃┗┓ ┃┫ ┏┓┏┓┓┏┏┓ # ┻ ┗┛┛ ┗┛┗┻┗┛┗┛┗┫ ┻┛┗┻┗┛┗ ┗┛┛ ┗┗┛ ┛┗┛┗ ┛┗┗┫┗┻ # ┛ ┛ elif isinstance(inbound_data.message, SavvyBulkSMSKenyaMessage): # Prepare the client: sms_client = AsyncSavvyBulkSMS( api_key = auth_token.auth.get("apiKey"), partner_id = auth_token.auth.get("partnerId"), short_code = auth_token.auth.get("shortCode"), http_client = self._http_client ) # Send the SMS: client_response = await sms_client.send_sms( recipient_number = inbound_data.message.recipientNo, message = inbound_data.message.text ) # ┏┓ ┏┳┓┓ ┳┳┓ # ┗┓┏┓┓┏┏┓ ┃ ┣┓┏┓ ┃┃┃┏┓┏┏┏┓┏┓┏┓ # ┗┛┗┻┗┛┗ ┻ ┛┗┗ ┛ ┗┗ ┛┛┗┻┗┫┗ # ┛ # Save the message: if client_response: message_id = await mongo_conn.insert_one( collection = self.MESSAGES_COLLECTION, document = CoreMessageModel( ts = event_ts, readTs = event_ts, tokenId = ObjectId(token_id), serviceType = auth_token.serviceType, client = auth_token.client, clientMessageId = client_response.messageId, clientThreadId = None, isInward = False, sentSuccessfully = client_response.success, payload = client_response.model_dump() ).model_dump() ) # Done here: return client_response # ***************************************************************************************************************** # ***** **** # *** MAIN PROGRAM *** # ***** **** # ***************************************************************************************************************** if __name__ == "__main__": pass