Compare commits
No commits in common. "1369e0b88569c7009551798d79d16767b46107e0" and "3dc531b127106ca7821f77ba38a88f08ea0edca8" have entirely different histories.
1369e0b885
...
3dc531b127
35
.github/workflows/pythonpackage.yml
vendored
35
.github/workflows/pythonpackage.yml
vendored
@ -1,35 +0,0 @@
|
||||
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
|
||||
|
||||
name: Python package
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.5, 3.6, 3.7, 3.8]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
- name: Lint with flake8
|
||||
run: |
|
||||
pip install flake8
|
||||
# stop the build if there are Python syntax errors or undefined names
|
||||
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
|
||||
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
|
5
.gitignore
vendored
5
.gitignore
vendored
@ -24,10 +24,10 @@ lib
|
||||
lib64
|
||||
share
|
||||
pyvenv.cfg
|
||||
templates
|
||||
*.egg-info
|
||||
man
|
||||
include
|
||||
credentials.py
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
@ -44,6 +44,3 @@ htmlcov*
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode/
|
||||
|
||||
# Development
|
||||
templates/
|
2
setup.py
2
setup.py
@ -1,3 +1,5 @@
|
||||
import os
|
||||
import sys
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
with open("README.md", "r") as fh:
|
||||
|
3
templates/dir_init.j2
Normal file
3
templates/dir_init.j2
Normal file
@ -0,0 +1,3 @@
|
||||
@property
|
||||
def {{method_name}}(self):
|
||||
return self.{{subdir}}.{{method_name}}
|
7
templates/endpoint.j2
Normal file
7
templates/endpoint.j2
Normal file
@ -0,0 +1,7 @@
|
||||
class {{class_name}}():
|
||||
def __init__(self, base):
|
||||
self.method = "{{endpoint}}"
|
||||
self.base = base
|
||||
|
||||
def fetch(self, params={}):
|
||||
return self.base.request(self.method, params=params)
|
1
templates/import.j2
Normal file
1
templates/import.j2
Normal file
@ -0,0 +1 @@
|
||||
from voipms.api.{{category_name}}.{{method_name}} import {{class_name}}
|
1
templates/initialize.j2
Normal file
1
templates/initialize.j2
Normal file
@ -0,0 +1 @@
|
||||
self._{{method_name}} = None
|
66
templates/method_generator.py
Normal file
66
templates/method_generator.py
Normal file
@ -0,0 +1,66 @@
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
file_loader = FileSystemLoader('.')
|
||||
env = Environment(loader=file_loader)
|
||||
|
||||
print("Which category does this endpoint fall under?")
|
||||
subdir_index = int(input("1: accounts, 2: call_detail_records, 3: dids, 4: general, 5: voicemail: "))
|
||||
subdir = ("accounts", "call_detail_records", "dids", "general", "voicemail")[subdir_index - 1]
|
||||
|
||||
endpoint = input("endpoint name? ")
|
||||
method = input("method name? ")
|
||||
|
||||
filename = "../voipms/api/{}/{}.py".format(subdir, method)
|
||||
|
||||
template = env.get_template('endpoint.j2')
|
||||
method_split = method.split('_')
|
||||
class_name = ''.join((i.title() for i in method_split))
|
||||
output = template.render(endpoint=endpoint, class_name=class_name)
|
||||
|
||||
with open(filename, 'a') as file:
|
||||
file.writelines(output)
|
||||
|
||||
|
||||
|
||||
filename = "../voipms/api/{}/__init__.py".format(subdir)
|
||||
template = env.get_template('import.j2')
|
||||
method_split = method.split('_')
|
||||
class_name = ''.join((i.title() for i in method_split))
|
||||
output_import = template.render(method_name=method, class_name=class_name, category_name=subdir)
|
||||
|
||||
template = env.get_template('initialize.j2')
|
||||
output_init = template.render(method_name=method)
|
||||
|
||||
template = env.get_template('subdir_init.j2')
|
||||
output_property = template.render(method_name=method, class_name=class_name)
|
||||
|
||||
with open(filename, 'r') as file:
|
||||
contents = file.readlines()
|
||||
|
||||
pos = 0
|
||||
|
||||
for k, v in enumerate(contents):
|
||||
if v == "\n":
|
||||
contents.insert(k, output_import + "\n")
|
||||
pos = k
|
||||
break
|
||||
|
||||
for k, v in enumerate(contents[pos+2:], pos+2):
|
||||
if v == "\n":
|
||||
contents.insert(k, output_init + "\n")
|
||||
break
|
||||
|
||||
contents.append("\n\n" + output_property)
|
||||
|
||||
with open(filename, 'w') as file:
|
||||
file.writelines(contents)
|
||||
|
||||
|
||||
|
||||
filename = "../voipms/api/__init__.py"
|
||||
|
||||
template = env.get_template('dir_init.j2')
|
||||
output = template.render(subdir=subdir, method_name=method)
|
||||
|
||||
with open(filename, 'a') as file:
|
||||
file.writelines("\n\n" + output)
|
5
templates/subdir_init.j2
Normal file
5
templates/subdir_init.j2
Normal file
@ -0,0 +1,5 @@
|
||||
@property
|
||||
def {{method_name}}(self):
|
||||
if self._{{method_name}} is None:
|
||||
self._{{method_name}} = {{class_name}}(self.base)
|
||||
return self._{{method_name}}
|
@ -1,31 +0,0 @@
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
from unittest.mock import patch
|
||||
from voipms.api import Client
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import credentials
|
||||
|
||||
|
||||
def test_instantiation():
|
||||
username = credentials.username
|
||||
password = credentials.password
|
||||
|
||||
client = Client(username, password)
|
||||
return client
|
||||
|
||||
|
||||
@patch('voipms.api.general.balance')
|
||||
def test_make_get_request(mock_requests):
|
||||
mock_response_obj = MagicMock()
|
||||
mock_response_obj.json = {"test": "test"}
|
||||
mock_response_obj.status_code = 200
|
||||
mock_requests.get.return_value = mock_response_obj
|
||||
|
||||
username = credentials.username
|
||||
password = credentials.password
|
||||
|
||||
client = Client(username, password)
|
||||
|
||||
res = client.registration_status.fetch()
|
||||
assert res == {"test": "test"}
|
@ -1,12 +1,13 @@
|
||||
import os
|
||||
import platform
|
||||
import json
|
||||
import requests
|
||||
|
||||
from voipms.base.exceptions import VoipException
|
||||
|
||||
|
||||
class Client(object):
|
||||
def __init__(self, username=None, password=None):
|
||||
|
||||
self.username = username or os.environ.get('VOIPMS_ACCOUNT_USER')
|
||||
self.password = password or os.environ.get('VOIPMS_API_TOKEN')
|
||||
self.api_base = "https://voip.ms/api/v1/rest.php"
|
||||
@ -16,6 +17,7 @@ class Client(object):
|
||||
|
||||
self.auth = (self.username, self.password)
|
||||
|
||||
# Domains
|
||||
self._accounts = None
|
||||
self._call_detail_records = None
|
||||
self._dids = None
|
||||
|
@ -1,7 +1,6 @@
|
||||
from voipms.api.accounts.subaccount import Subaccount
|
||||
from voipms.api.accounts.registration_status import RegistrationStatus
|
||||
|
||||
|
||||
class Accounts():
|
||||
def __init__(self, base):
|
||||
self._subaccount = None
|
||||
|
@ -3,9 +3,9 @@ from voipms.api.call_detail_records.records import Records
|
||||
from voipms.api.call_detail_records.rates import Rates
|
||||
from voipms.api.call_detail_records.termination_rates import TerminationRates
|
||||
|
||||
|
||||
class CallDetailRecords():
|
||||
def __init__(self, base):
|
||||
|
||||
self.base = base
|
||||
self._billing = None
|
||||
self._records = None
|
||||
|
@ -1,7 +1,6 @@
|
||||
from voipms.api.dids.search import Search
|
||||
from voipms.api.dids.sms import SMS
|
||||
|
||||
|
||||
class DIDs():
|
||||
def __init__(self, base):
|
||||
self._search = None
|
||||
|
@ -4,7 +4,6 @@ from voipms.api.general.transaction_history import TransactionHistory
|
||||
from voipms.api.general.countries import Countries
|
||||
from voipms.api.general.languages import Languages
|
||||
|
||||
|
||||
class General():
|
||||
def __init__(self, base):
|
||||
self._balance = None
|
||||
|
@ -1,6 +1,5 @@
|
||||
from voipms.api.voicemail.messages import Messages
|
||||
|
||||
|
||||
class Voicemail():
|
||||
def __init__(self, base):
|
||||
self._messages = None
|
||||
|
@ -1,5 +1,6 @@
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import sys
|
||||
|
||||
class VoipException(Exception):
|
||||
def __init__(self, err_code=""):
|
||||
@ -10,23 +11,20 @@ class VoipException(Exception):
|
||||
'account_with_dids': 'The Account has DIDs assigned to it.',
|
||||
'api_not_enabled': 'API has not been enabled or has been disabled',
|
||||
'api_limit_exceeded': 'API requests limit per minute has been reached',
|
||||
'cancel_failed': "The cancellation wasn't completed.",
|
||||
'can_have_only_one_profile_without_pin': 'The conference can just have one profile member without pin',
|
||||
'cancel_failed': "The cancellation wasn't completed.", 'can_have_only_one_profile_without_pin': 'The conference can just have one profile member without pin',
|
||||
'conference_member_relation_not_found': 'There is no relation between the profile member and the conference.',
|
||||
'did_in_use': 'DID Number is already in use',
|
||||
'duplicated_pin': 'The given pin has been duplicated',
|
||||
'error_deleting_msg': 'Error when deleting message',
|
||||
'error_moving_msg': 'Error when move the voicemail message to folder',
|
||||
'existing_did': "You can't set a callback to an existing VoIP.ms DID number",
|
||||
'exceeds_file_size': 'The file exceeds the limite size allowed.',
|
||||
'existing_did': "You can't set a callback to an existing VoIP.ms DID number", 'exceeds_file_size': 'The file exceeds the limite size allowed.',
|
||||
'forwards_exceeded': 'Your account is limited to 4 forward entries',
|
||||
'invalid_account': 'This is not a valid account',
|
||||
'invalid_address': 'Address is missing or the format is invalid.',
|
||||
'invalid_admin': 'This is not a valid admin',
|
||||
'invalid_agent_ring_timeout': 'This is not a valid Agent ring time out value',
|
||||
'invalid_allowedcodecs': 'One of the codecs provided is invalidFormat and Values: ulaw;g729;gsm;all',
|
||||
'invalid_attachid': "The given ID is invalid or doesn't exist.",
|
||||
'invalid_announce_join_leave': 'This is not a valid "Announce join leave"',
|
||||
'invalid_attachid': "The given ID is invalid or doesn't exist.", 'invalid_announce_join_leave': 'This is not a valid "Announce join leave"',
|
||||
'invalid_announce_only_user': 'This is not a valid "Announce only user"',
|
||||
'invalid_announce_position_frequency': 'This is not a valid Announce position frequency',
|
||||
'invalid_announce_round_seconds': 'This is not a valid "Announce round seconds"',
|
||||
@ -56,10 +54,7 @@ class VoipException(Exception):
|
||||
'invalid_conference': 'This is not a valid Conference ID',
|
||||
'invalid_countryid': 'This is not a valid Country ID',
|
||||
'invalid_city': 'City is missing or the format is invalid.',
|
||||
'invalid_country': (
|
||||
'Country is missing or the format is invalid, must be in format ISO 3166-1 alpha-2, '
|
||||
'example: US, CA, etc. (You can use the values returned by the method getCountries)'
|
||||
),
|
||||
'invalid_country': 'Country is missing or the format is invalid, must be in format ISO 3166-1 alpha-2, example: US, CA, etc. (You can use the values returned by the method getCountries)',
|
||||
'invalid_credentials': 'Username or Password is incorrect',
|
||||
'invalid_date': 'This is not a valid dateFormat is: yyyy-mm-dd',
|
||||
'invalid_datetime': 'This is not a valid datetimeFormat is: yyyy-mm-dd hh:mm:ss',
|
||||
@ -110,9 +105,7 @@ class VoipException(Exception):
|
||||
'invalid_ip_iax2': 'Do not provide an IP address for IAX2',
|
||||
'invalid_ivr': 'This is not a valid IVR',
|
||||
'invalid_jitter_buffer': 'This is not a valid "jitter buffer" value',
|
||||
'invalid_join_empty_type': "This is not a valid 'JoinWhenEmpty' Type for a Queue",
|
||||
'invalid_join_announcement': "This is not a valid 'Join Announcement' Type for a Queue",
|
||||
'invalid_language': 'This is not a valid LanguageShould be: es/en/fr',
|
||||
'invalid_join_empty_type': "This is not a valid 'JoinWhenEmpty' Type for a Queue", 'invalid_join_announcement': "This is not a valid 'Join Announcement' Type for a Queue", 'invalid_language': 'This is not a valid LanguageShould be: es/en/fr',
|
||||
'invalid_lastname': 'Lastname is missing or the format is invalid.',
|
||||
'invalid_listened': 'This is not a valid Listened value',
|
||||
'invalid_location': 'This is not a valid Location',
|
||||
@ -137,24 +130,15 @@ class VoipException(Exception):
|
||||
'invalid_number_us': 'You have entered a USA number (not valid in this portability process).',
|
||||
'invalid_number_fax': 'The Fax number can not be ported into our network',
|
||||
'invalid_number_exist': 'The number is already in our network',
|
||||
'invalid_numbermembers': (
|
||||
'The element format of multiple data is not correct '
|
||||
'or it size does not match with other elements'
|
||||
),
|
||||
'invalid_numbermembers': 'The element format of multiple data is not correct or it size does not match with other elements',
|
||||
'invalid_order': 'This is not a valid "order" value',
|
||||
'invalid_package': 'This is not a valid Package',
|
||||
'invalid_password': (
|
||||
'This is not a valid password, Voicemail: Must be 4 Digits, '
|
||||
'SubAccounts: More than 6 chars, Must Contain Alphanumeric and !#$%&/()=?*[]_:.,{}+-'
|
||||
),
|
||||
'invalid_password': 'This is not a valid passwordVoicemail: Must be 4 DigitsSubAccounts: More than 6 chars, Must Contain Alphanumeric and !#$%&/()=?*[]_:.,{}+-',
|
||||
'invalid_password_auth': 'Do not provide a Password for IP Authentication',
|
||||
'invalid_password_lessthan_8characters_long': 'This is not a valid password (Less than 8 characters long)',
|
||||
'invalid_password_missing_uppercase': 'This is not a valid password (Missing upper case character)',
|
||||
'invalid_password_missing_lowercase': 'This is not a valid password (Missing lower case character)',
|
||||
'invalid_password_ilegal_characters': (
|
||||
'This is not a valid password (Allowed characters: '
|
||||
'Alphanumeric and ! # $ % & / ( ) = ? * [ ] _ : . , { } + -)'
|
||||
),
|
||||
'invalid_password_ilegal_characters': 'This is not a valid password (Allowed characters: Alphanumeric and ! # $ % & / ( ) = ? * [ ] _ : . , { } + -)',
|
||||
'invalid_password_missing_number': 'This is not a valid password (Missing a number)',
|
||||
'invalid_pause': 'This is not a valid Pause',
|
||||
'invalid_payment': 'This is not a valid Payment',
|
||||
@ -168,8 +152,7 @@ class VoipException(Exception):
|
||||
'invalid_province': 'This is not a valid Province',
|
||||
'invalid_provider_name': 'You must provide the service provider name',
|
||||
'invalid_provider_account': 'You must provide your account # with the current provider',
|
||||
'invalid_portingid': "The given ID is invalid or doesn't exist.",
|
||||
'invalid_porttype': 'Must provide a valid port type.',
|
||||
'invalid_portingid': "The given ID is invalid or doesn't exist.", 'invalid_porttype': 'Must provide a valid port type.',
|
||||
'invalid_port_status': 'The status code is invalid. (You can use the values returned by the method getListStatus)',
|
||||
'invalid_quantity': 'This is not a valid quantity',
|
||||
'invalid_query': 'This is not a valid Query',
|
||||
@ -198,10 +181,7 @@ class VoipException(Exception):
|
||||
'invalid_recording_sound_participants_unmuted': '"participants unmuted" is not a valid recording',
|
||||
'invalid_report_hold_time_agent': 'This is not a valid Report hold time agent',
|
||||
'invalid_resellerclient': 'This is not a valid Reseller Client',
|
||||
'invalid_resellernextbilling': (
|
||||
'This is not a valid Reseller Next Billing date, '
|
||||
'date should not be set in the past.'
|
||||
),
|
||||
'invalid_resellernextbilling': 'This is not a valid Reseller Next Billing date, date should not be set in the past.',
|
||||
'invalid_resellerpackage': 'This is not a valid Reseller Package',
|
||||
'invalid_response_timeout': 'This is not a valid ResponseTimeOut',
|
||||
'invalid_retry_timer': 'This is not a valid Retry timer',
|
||||
@ -235,10 +215,7 @@ class VoipException(Exception):
|
||||
'invalid_timecondition': 'This is not a valid Time Condition',
|
||||
'invalid_timeout': 'This is not a valid timeout',
|
||||
'invalid_timerange': 'This is not a valid Timer Range',
|
||||
'invalid_timezone': (
|
||||
'This is not a valid TimezoneCDR and resellerCDR: '
|
||||
'Must be numericVoicemail: Values from getTimezone'
|
||||
),
|
||||
'invalid_timezone': 'This is not a valid TimezoneCDR and resellerCDR: Must be numericVoicemail: Values from getTimezone',
|
||||
'invalid_type': 'This is not a valid Type',
|
||||
'invalid_to_number': 'This is not a valid destination number',
|
||||
'invalid_username': 'This is not a valid Username',
|
||||
@ -251,7 +228,7 @@ class VoipException(Exception):
|
||||
'invalid_urgent': 'This is not valid urgent value',
|
||||
'invalid_zip': 'Zip Code is missing or the format is invalid.',
|
||||
'ip_not_enabled': 'This IP is not enabled for API use',
|
||||
'limit_reached': 'You have reached the maximum number of messages allowed per day.',
|
||||
'limit_reached': 'You have reached the maximum number of messages allowed per day.- SMS limit using the API.- Fax limit applies using any method.',
|
||||
'max_phonebook': 'Your account is limited to 8 SIP, IAX or SIP URI members',
|
||||
'member_already_included': 'The member has been included already',
|
||||
'members_exceeded': 'You have reached the maximum allowed entries for the Phonebook',
|
||||
@ -307,19 +284,13 @@ class VoipException(Exception):
|
||||
'missing_folder': 'folder was not provided',
|
||||
'missing_forwarding': 'Forwarding was not provided',
|
||||
'missing_id': 'ID was not provided',
|
||||
'missing_if_announce_position_enabled_report_estimated_hold_time': (
|
||||
"'If announce position enabled report "
|
||||
"estimated hold time' type was not provided"
|
||||
),
|
||||
'missing_internationalroute': 'International Route was not provided',
|
||||
'missing_if_announce_position_enabled_report_estimated_hold_time': "'If announce position enabled report estimated hold time' type was not provided", 'missing_internationalroute': 'International Route was not provided',
|
||||
'missing_ip': 'You need to provide an IP if you select IP Authentication Method',
|
||||
'missing_ip_h323': 'You must enter an IP Address for H.323',
|
||||
'missing_ivr': 'IVR was not provided',
|
||||
'missing_join_when_empty': "'JoinWhenEmpty' type was not provided",
|
||||
'missing_language': 'Language was not provided',
|
||||
'missing_join_when_empty': "'JoinWhenEmpty' type was not provided", 'missing_language': 'Language was not provided',
|
||||
'missing_lastname': 'Lastname was not provided',
|
||||
'missing_leave_when_empty': "'LeaveWhenEmpty' type was not provided",
|
||||
'missing_listened': 'Listened code was not provided',
|
||||
'missing_leave_when_empty': "'LeaveWhenEmpty' type was not provided", 'missing_listened': 'Listened code was not provided',
|
||||
'missing_location': 'Location was not provided',
|
||||
'missing_lockinternational': 'Lock International was not provided',
|
||||
'missing_mailbox': 'Mailbox was not provided',
|
||||
@ -349,9 +320,7 @@ class VoipException(Exception):
|
||||
'missing_query': 'Query was not provided',
|
||||
'missing_recording': 'Recording was not provided',
|
||||
'missing_report_hold_time_agent': 'Report hold time agent was not provided',
|
||||
'missing_resellerclient': "Provide a Reseller Client or don't provide a Reseller Package",
|
||||
'missing_resellerpackage': "Provide a Reseller Package or don't provide a Reseller Client",
|
||||
'missing_response_timeout': 'ResponseTimeOut was not provided',
|
||||
'missing_resellerclient': "Provide a Reseller Client or don't provide a Reseller Package", 'missing_resellerpackage': "Provide a Reseller Package or don't provide a Reseller Client", 'missing_response_timeout': 'ResponseTimeOut was not provided',
|
||||
'missing_ringgroup': 'Ring group was not provided',
|
||||
'missing_ring_inuse': 'Ring in use was not provided',
|
||||
'missing_ring_strategy': 'Ring strategy was not provided',
|
||||
@ -389,10 +358,7 @@ class VoipException(Exception):
|
||||
'no_base64file': 'File not encoded in base64',
|
||||
'no_callback': 'There are not Callbacks',
|
||||
'no_callhunting': 'There are no Call Huntings',
|
||||
'no_callstatus': (
|
||||
'No Call Status was provided. One of the following parameters needs to be set to "1": '
|
||||
'answered, noanswer, busy, failed'
|
||||
),
|
||||
'no_callstatus': 'No Call Status was provided.One of the following parameters needs to be set to "1": answered, noanswer, busy, failed',
|
||||
'no_cdr': 'There are no CDR entries for the filter',
|
||||
'no_change_billingtype': 'Imposible change DID billing plan',
|
||||
'no_client': 'There are no Clients',
|
||||
@ -417,8 +383,7 @@ class VoipException(Exception):
|
||||
'no_sms': 'There are no SMS messages',
|
||||
'no_timecondition': 'There are no Time Conditions',
|
||||
'note_toolong': 'The note exceeds character size limit',
|
||||
'order_failed': "The order wasn't completed.",
|
||||
'provider_outofservice': 'One of our providers is out of service',
|
||||
'order_failed': "The order wasn't completed.", 'provider_outofservice': 'One of our providers is out of service',
|
||||
'recording_in_use_did': 'You have a DID using this Recording',
|
||||
'recording_in_use_queue': 'You have a Calling Queue using this Recording',
|
||||
'recording_in_use_ivr': 'You have an IVR using this Recording',
|
||||
@ -427,9 +392,7 @@ class VoipException(Exception):
|
||||
'repeated_ip': 'You already have a Subaccount using this IP and Protocol',
|
||||
'reserved_ip': 'This is a reserved IP used by VoIP.ms or other Companies',
|
||||
'same_did_billingtype': 'The Billing Type provided and DID billing type are the same',
|
||||
'sipuri_in_phonebook': "This SIPURI can't be deleted, it is mapped in the phonebook",
|
||||
'sent_fail': "The Fax Message it wasn't send.",
|
||||
'sms_toolong': 'The SMS message exceeds 160 characters',
|
||||
'sipuri_in_phonebook': "This SIPURI can't be deleted, it is mapped in the phonebook", 'sent_fail': "The Fax Message it wasn't send.", 'sms_toolong': 'The SMS message exceeds 160 characters',
|
||||
'sms_failed': 'The SMS message was not sent',
|
||||
'tls_error': 'Theres was a TLS error, please try later.',
|
||||
'Unable_to_purchase': 'Unable to purchase DIDs',
|
||||
@ -449,6 +412,7 @@ class VoipException(Exception):
|
||||
return "API Call failed as: {}".format(err_desc)
|
||||
|
||||
|
||||
|
||||
class VoipRestException(VoipException):
|
||||
def __str__(self):
|
||||
return self.err_code or "<empty message>"
|
Loading…
Reference in New Issue
Block a user