Compare commits
3 Commits
7c50e7b2e1
...
30aaa91474
Author | SHA1 | Date |
---|---|---|
|
30aaa91474 | |
|
db3926316c | |
|
b8dcb02ef1 |
|
@ -2,7 +2,7 @@ amqp==5.1.1
|
|||
asgiref==3.8.1
|
||||
async-timeout==4.0.2
|
||||
beautifulsoup4==4.12.3
|
||||
billiard==4.2.0
|
||||
billiard==4.2.1
|
||||
celery==5.4.0
|
||||
certifi==2021.10.8
|
||||
charset-normalizer==2.0.12
|
||||
|
@ -23,7 +23,7 @@ packaging==21.3
|
|||
persisting-theory==1.0
|
||||
phonenumbers==8.12.47
|
||||
prompt-toolkit==3.0.29
|
||||
psycopg2-binary==2.9.9
|
||||
psycopg2-binary==2.9.10
|
||||
pyparsing==3.0.8
|
||||
pypng==0.20220715.0
|
||||
python-dateutil==2.8.2
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
[isort]
|
||||
extend_skip=env
|
||||
line_length=88
|
||||
profile=black
|
||||
skip_gitignore=True
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
from datetime import datetime, timezone
|
||||
|
||||
import requests
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.utils.timezone import now
|
||||
|
||||
from ..exceptions import OutboundMessageError
|
||||
from ..message import Message, MessageType
|
||||
from .abc import Receiver as BaseReceiver
|
||||
from .abc import Sender as BaseSender
|
||||
|
||||
__all__ = ("Receiver", "Sender")
|
||||
|
||||
BASE_URL = "https://gateway.seven.io/api"
|
||||
|
||||
RESPONSE_CODES = {
|
||||
"100": "Sent",
|
||||
"101": "Message could not be sent",
|
||||
"201": "Invalid sender",
|
||||
"202": "Invalid recipient",
|
||||
"301": "Missing 'to' parameter",
|
||||
"305": "Invalid 'text' parameter",
|
||||
"401": "Parameter 'text' too long",
|
||||
"402": "Message has already been sent",
|
||||
"403": "Exceeded daily limit for recipient",
|
||||
"500": "Insufficient balance",
|
||||
"600": "Error while sending message",
|
||||
"900": "Authentication failed",
|
||||
"901": "Signature verification failed",
|
||||
"902": "Access denied",
|
||||
"903": "Request IP is not in allow list",
|
||||
}
|
||||
|
||||
|
||||
class Receiver(BaseReceiver):
|
||||
fetch = None
|
||||
|
||||
def handle(self, data, webhook_event, webhook_timestamp, **kwargs):
|
||||
if webhook_event != "sms_mo":
|
||||
return
|
||||
|
||||
yield Message(
|
||||
data["id"],
|
||||
recipient=data["system"],
|
||||
sender=data["sender"],
|
||||
text=data["text"],
|
||||
type=MessageType.INBOUND,
|
||||
created_at=datetime.fromtimestamp(data["time"], timezone.utc),
|
||||
)
|
||||
|
||||
|
||||
class Sender(BaseSender):
|
||||
def __init__(self):
|
||||
for setting in ("sevenio_api_key", "sevenio_sender"):
|
||||
try:
|
||||
settings.SMS_SETTINGS[setting]
|
||||
except KeyError:
|
||||
raise ImproperlyConfigured(
|
||||
f"'{setting}' must be set in SMS_SETTINGS for seven.io backend"
|
||||
)
|
||||
|
||||
sender = settings.SMS_SETTINGS["sevenio_sender"]
|
||||
sender_is_alnum = sender.isalnum()
|
||||
sender_is_num = sender.isnumeric()
|
||||
if (
|
||||
not sender_is_alnum
|
||||
or len(sender) > 16
|
||||
or not sender_is_num
|
||||
and len(sender) > 11
|
||||
):
|
||||
raise ImproperlyConfigured("invalid 'sevenio_sender' in SMS_SETTINGS")
|
||||
|
||||
self.client = requests.Session()
|
||||
self.client.headers["Accept"] = "application/json"
|
||||
self.client.headers["X-Api-Key"] = settings.SMS_SETTINGS["sevenio_api_key"]
|
||||
|
||||
self.sender = sender
|
||||
|
||||
def send(self, messages):
|
||||
for message in messages:
|
||||
data = {
|
||||
"from": self.sender,
|
||||
"label": message.key,
|
||||
"text": message.text,
|
||||
"to": message.recipient,
|
||||
}
|
||||
r = self.client.post(f"{BASE_URL}/sms", data=data)
|
||||
r.raise_for_status()
|
||||
|
||||
resp = r.json()
|
||||
|
||||
code = resp["success"]
|
||||
if code != "100":
|
||||
raise OutboundMessageError(
|
||||
RESPONSE_CODES.get(code, f"Unknown error: {code}")
|
||||
)
|
||||
|
||||
for m in resp["messages"]:
|
||||
if m["success"]:
|
||||
yield Message(
|
||||
m["label"],
|
||||
recipient=m["recipient"],
|
||||
sender=m["sender"],
|
||||
text=m["text"],
|
||||
type=MessageType.OUTBOUND,
|
||||
created_at=now(),
|
||||
)
|
Loading…
Reference in New Issue