passerelle/passerelle/apps/twilio/models.py

92 lines
3.4 KiB
Python

# passerelle - uniform access to multiple data sources and services
# Copyright (C) 2020 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import requests
from django.db import models
from django.utils.translation import gettext_lazy as _
from requests.auth import HTTPBasicAuth
from passerelle.sms.models import SMSResource
from passerelle.utils.jsonresponse import APIError
class TwilioSMSGateway(SMSResource):
hide_description_fields = ['account_sid']
account_sid = models.CharField(verbose_name=_('Account Sid'), max_length=64)
auth_token = models.CharField(verbose_name=_('Auth Token'), max_length=64)
class Meta:
verbose_name = 'Twilio'
db_table = 'sms_twilio'
TEST_DEFAULTS = {
'create_kwargs': {
'account_sid': 'ACxxx',
'auth_token': 'yyy',
},
'test_vectors': [
{
'status_code': 400,
'response': 'my error message',
'result': {
'err': 1,
'err_desc': 'Twilio error: some destinations failed',
'data': [
['+33688888888', 'Twilio error: my error message'],
['+33677777777', 'Twilio error: my error message'],
],
},
},
{
'status_code': 201,
'result': {
'err': 0,
'data': None,
},
},
],
}
URL = 'https://api.twilio.com/2010-04-01/Accounts'
def send_msg(self, text, sender, destinations, **kwargs):
"""Send a SMS using the Twilio provider"""
# from https://www.twilio.com/docs/usage/requests-to-twilio
# set destinations phone number in E.164 format
# [+][country code][phone number including area code]
numbers = []
for dest in destinations:
numbers.append('+' + dest[2:])
destinations = numbers
url = '%s/%s/Messages.json' % (TwilioSMSGateway.URL, self.account_sid)
auth = HTTPBasicAuth(self.account_sid, self.auth_token)
results = []
for dest in destinations:
params = {'Body': text, 'From': sender, 'To': dest}
try:
resp = self.requests.post(url, params, auth=auth)
except requests.RequestException as exc:
raise APIError('Twilio error: POST failed, %s' % exc)
else:
if resp.status_code != 201:
results.append('Twilio error: %s' % resp.text)
else:
results.append(0)
if any(results):
raise APIError('Twilio error: some destinations failed', data=list(zip(destinations, results)))
# credit consumed is unknown