Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#654 SMS budget (enable check for not allowed phone numbers) #164

Merged
merged 3 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ def enqueue_dlr_request(self, pk: str):
DeliveryReport.objects.filter(pk=pk).update(status=DeliveryReport.Status.DELIVERED)

def client_send(self, sender: str, recipient: Recipient, msg: dict, dlr_id: str):
if not recipient.email:
return
res = (
boto3.Session(
aws_access_key_id=self.key_id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ def validate_send(self, response: dict):
assert is_success(response.get("ResponseMetadata", {}).get("HTTPStatusCode", 500))

def client_send(self, sender: str, recipient: Recipient, msg: str, dlr_id: str):
if not recipient.phone_number:
return
smsattrs = {
"AWS.SNS.SMS.SenderID": {"DataType": "String", "StringValue": sender.replace(" ", "-")},
"AWS.SNS.SMS.SMSType": {"DataType": "String", "StringValue": "Promotional"},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ def client_send(self, sender: str, recipient: Recipient, msg: str, dlr_id: str):
if not rec:
return

if not rec[0]:
return

params: dict = {
"api_key": self.api_key,
"api_secret": self.api_secret,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ def ensure_credentials(self, extra_data):
assert len(self.url) > 0, "T2_PASSWORD is required"

def client_send(self, sender: str, recipient: Recipient, msg: str, dlr_id: str):
if not recipient.phone_number:
return
basic_auth = HTTPBasicAuth(self.username, self.password)
response = requests.post(
f"{self.url}{self.endpoint_one}",
Expand Down
9 changes: 9 additions & 0 deletions django_project_base/notifications/base/notification.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,15 @@ def _set_db(self):
"SETTINGS": sttgs,
}
self._extra_data["SETTINGS"] = settings
from dill import dumps as ddumps

setattr(
self._extra_data["SETTINGS"],
"IS_PHONE_NUMBER_ALLOWED_FUNCTION",
ddumps(
getattr(self._extra_data["SETTINGS"], "IS_PHONE_NUMBER_ALLOWED_FUNCTION", ""), fmode=True, recurse=True
),
)

def _ensure_channels(
self, channels: List[str], notification: DjangoProjectBaseNotification
Expand Down
12 changes: 12 additions & 0 deletions django_project_base/notifications/base/phone_number_parser.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
from typing import List

from django.core.cache import cache


class PhoneNumberParser:
@staticmethod
def is_allowed(phone_number: str) -> bool:
if (allowed_function := cache.get("IS_PHONE_NUMBER_ALLOWED_FUNCTION".lower(), "")) and allowed_function:
from dill import loads as dloads

return dloads(allowed_function)(phone_number)
return phone_number and len(phone_number) >= 8

@staticmethod
def valid_phone_numbers(candidates: List[str]) -> List[str]:
valid: List[str] = []
for number in candidates:
if not PhoneNumberParser.is_allowed(number):
continue
if number.startswith("+"):
valid.append(number.lstrip("+"))
continue
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging

from django import db
from django.core.cache import cache
from django.db import connections
from django.db.utils import load_backend
from django.utils import timezone
Expand Down Expand Up @@ -28,6 +29,12 @@ def make_send(self, notification: DjangoProjectBaseNotification, extra_data) ->
dw = backend.DatabaseWrapper(db_settings["SETTINGS"])
dw.connect()
connections.databases[db_connection] = dw.settings_dict
if (
(stgs := extra_data.get("SETTINGS"))
and (phn_allowed := getattr(stgs, "IS_PHONE_NUMBER_ALLOWED_FUNCTION", ""))
and phn_allowed
):
cache.set("IS_PHONE_NUMBER_ALLOWED_FUNCTION".lower(), phn_allowed, timeout=None)

already_sent_channels = set(
filter(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from django.test import TestCase

from django_project_base.notifications.base.phone_number_parser import PhoneNumberParser


class IsPhoneNumberValidTest(TestCase):
def test_is_phone_number_valid(self):
self.assertFalse(PhoneNumberParser.is_allowed("0903028"))
self.assertFalse(PhoneNumberParser.is_allowed("1919"))
self.assertTrue(PhoneNumberParser.is_allowed("03897234"))
self.assertTrue(PhoneNumberParser.is_allowed("0038631697001"))
self.assertTrue(PhoneNumberParser.is_allowed("+38676234567"))
1 change: 1 addition & 0 deletions django_project_base/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"name": "DEFAULT_SMS_SENDER_ID_SETTING_NAME",
"default": "",
},
{"name": "IS_PHONE_NUMBER_ALLOWED_FUNCTION", "default": ""},
)

USER_CACHE_KEY = "django-user-{id}"
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ natural
celery==5.2.7
django-redis-cache
pandas
dill==0.3.7
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ deps =
celery==5.2.7
django-redis-cache
git+https://github.com/dedayoa/sms-counter-python.git#egg=sms_counter
dill==0.3.7

commands =
python manage.py test
Expand Down
Loading