Many countries are introducing different requirements for SMS senders to register and/or use alpha numeric ids, short codes or regional numbers or face being blocked. The changes in this PR will give us more flexibility by allowing us to map to different resources in Twilio based on the phone number we are trying to reach. For this first implementation the selection is made based on country code of the recipient. Verification and phone calls were given the same treatment although the immediate need is for SMS. Senders with no country code set can be used as catch-all defaults. This also falls back to the configured live settings/environment variables if not configured. Possible future additions: - Move through list of trying multiple senders before failing notification - Easily expanded to allow per-organization or per-user resources to let users and tenants configure their own Twilio - Add UI + replace live settings so users can configure their own settings - More selection criteria if needed TODO: - [x] Add+Fix Tests - [x] Verify changes are compatible with #1713
41 lines
1.5 KiB
Python
41 lines
1.5 KiB
Python
from django.db import models
|
|
from twilio.rest import Client
|
|
|
|
|
|
class TwilioAccount(models.Model):
|
|
name = models.CharField(max_length=100)
|
|
account_sid = models.CharField(max_length=64, null=False, blank=False, unique=True)
|
|
auth_token = models.CharField(max_length=64, null=True, default=None)
|
|
api_key_sid = models.CharField(max_length=64, null=True, default=None)
|
|
api_key_secret = models.CharField(max_length=64, null=True, default=None)
|
|
|
|
def get_twilio_api_client(self):
|
|
if self.api_key_sid and self.api_key_secret:
|
|
return Client(self.api_key_sid, self.api_key_secret, self.account_sid)
|
|
else:
|
|
return Client(self.account_sid, self.auth_token)
|
|
|
|
|
|
class TwilioSender(models.Model):
|
|
name = models.CharField(max_length=100, null=False, default="Default")
|
|
# Note: country_code does not have + prefix here
|
|
country_code = models.CharField(max_length=16, null=True, default=None)
|
|
account = models.ForeignKey(
|
|
"twilioapp.TwilioAccount", on_delete=models.CASCADE, related_name="%(app_label)s_%(class)s_account"
|
|
)
|
|
|
|
class Meta:
|
|
abstract = True
|
|
|
|
|
|
class TwilioSmsSender(TwilioSender):
|
|
# Sender for sms is phone number, short code or alphanumeric id
|
|
sender = models.CharField(max_length=16, null=False, blank=False)
|
|
|
|
|
|
class TwilioPhoneCallSender(TwilioSender):
|
|
number = models.CharField(max_length=16, null=False, blank=False)
|
|
|
|
|
|
class TwilioVerificationSender(TwilioSender):
|
|
verify_service_sid = models.CharField(max_length=64, null=False, blank=False)
|