Files
api_utils_converse_v2/models/behaviour/sms/send.py
T

215 lines
8.9 KiB
Python

"""
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