Last active
September 3, 2018 11:59
-
-
Save satels/a0a0e5612588248f3659e94d75a6bf24 to your computer and use it in GitHub Desktop.
Языки программирования: Python, Ruby. Создание звонка через API calltools.ru и получение результата на PostBack url
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import requests | |
| # Полная и актуальная документация по API: https://calltools.ru/guide_api | |
| CALLTOOLS_PUBLIC_KEY = 'test_public_key' | |
| CALLTOOLS_BASE_URL = 'https://calltools.ru' | |
| CALLTOOLS_TIMEOUT = 30 | |
| class CallToolsException(Exception): | |
| pass | |
| def create_call(campaign_id, phonenumber, text=None, speaker='Tatyana'): | |
| ''' | |
| Создание звонка на прозвон с генерацией ролика | |
| :type campaign_id: int | |
| :type phonenumber: str | |
| :type text: str|None | |
| :type speaker: str | |
| :rtype: dict | |
| ''' | |
| resp = requests.get(CALLTOOLS_BASE_URL + '/lk/cabapi_external/api/v1/phones/call/', { | |
| 'public_key': CALLTOOLS_PUBLIC_KEY, | |
| 'phone': phonenumber, | |
| 'campaign_id': campaign_id, | |
| 'text': text, | |
| 'speaker': speaker, | |
| }, timeout=CALLTOOLS_TIMEOUT) | |
| ret = resp.json() | |
| if ret['status'] == 'error': | |
| raise CallToolsException(ret['data']) | |
| return ret | |
| def check_status(campaign_id, phonenumber=None, call_id=None, | |
| from_created_date=None, to_created_date=None, | |
| from_updated_date=None, to_updated_date=None): | |
| ''' | |
| Получение статуса звонка по номеру телефона или по call_id (ID звонка) | |
| :type campaign_id: int | |
| :type phonenumber: str|None | |
| :type call_id: int|None | |
| :type from_created_date: str|None | |
| :type to_created_date: str|None | |
| :type from_updated_date: str|None | |
| :type to_updated_date: str|None | |
| :rtype: dict | |
| ''' | |
| if phonenumber: | |
| url = '/lk/cabapi_external/api/v1/phones/calls_by_phone/' | |
| elif call_id: | |
| url = '/lk/cabapi_external/api/v1/phones/call_by_id/' | |
| else: | |
| raise ValueError('check_status required call_id or phonenumber') | |
| resp = requests.get(CALLTOOLS_BASE_URL + url, { | |
| 'public_key': CALLTOOLS_PUBLIC_KEY, | |
| 'phone': phonenumber, | |
| 'call_id': call_id, | |
| 'campaign_id': campaign_id, | |
| 'from_created_date': from_created_date, | |
| 'to_created_date': to_created_date, | |
| 'from_updated_date': from_updated_date, | |
| 'to_updated_date': to_updated_date, | |
| }, timeout=CALLTOOLS_TIMEOUT) | |
| ret = resp.json() | |
| if ret['status'] == 'error': | |
| raise CallToolsException(ret['data']) | |
| return ret | |
| def remove_call(campaign_id, phonenumber=None, call_id=None): | |
| ''' | |
| Удаление номера из прозвона | |
| :type campaign_id: int | |
| :type phonenumber: str|None | |
| :type call_id: int|None | |
| :rtype: dict | |
| ''' | |
| if not phonenumber and not call_id: | |
| raise ValueError('remove_call required call_id or phonenumber') | |
| resp = requests.get(CALLTOOLS_BASE_URL + '/lk/cabapi_external/api/v1/phones/remove_call/', { | |
| 'public_key': CALLTOOLS_PUBLIC_KEY, | |
| 'phone': phonenumber, | |
| 'call_id': call_id, | |
| 'campaign_id': campaign_id, | |
| }, timeout=CALLTOOLS_TIMEOUT) | |
| ret = resp.json() | |
| if ret['status'] == 'error': | |
| raise CallToolsException(ret['data']) | |
| return ret | |
| # Статусы звонка | |
| ATTEMPTS_EXCESS_STATUS = 'attempts_exc' | |
| USER_CUSTOM_STATUS = 'user' | |
| NOVALID_BUTTON_STATUS = 'novalid_button' | |
| COMPLETE_FINISHED_STATUS = 'compl_finished' | |
| COMPLETE_NOFINISHED_STATUS = 'compl_nofinished' | |
| DELETED_CALL_STATUS = 'deleted' | |
| IN_PROCESS_STATUS = 'in_process' | |
| HUMAN_STATUSES = [ | |
| (IN_PROCESS_STATUS, 'В процессе'), | |
| (USER_CUSTOM_STATUS, 'Пользовательский IVR'), | |
| (ATTEMPTS_EXCESS_STATUS, 'Попытки закончились'), | |
| (COMPLETE_NOFINISHED_STATUS, 'Некорректный ответ'), | |
| (COMPLETE_FINISHED_STATUS, 'Закончен удачно'), | |
| (NOVALID_BUTTON_STATUS, 'Невалидная кнопка'), | |
| (DELETED_CALL_STATUS, 'Удалён из прозвона'), | |
| ] | |
| # Статусы дозвона | |
| DIAL_STATUS_WAIT = 0 | |
| DIAL_STATUS_FAILED = 1 | |
| DIAL_STATUS_HANGUP = 2 | |
| DIAL_STATUS_RING_TIMEOUT = 3 | |
| DIAL_STATUS_BUSY = 4 | |
| DIAL_STATUS_ANSWER = 5 | |
| DIAL_STATUS_ROBOT1 = 6 | |
| DIAL_STATUS_ROBOT2 = 7 | |
| DIAL_STATUS_NOVALID_BTN = 8 | |
| DIAL_STATUS_UNKNOWN = 9 | |
| DIAL_STATUS_WED = 10 | |
| DIAL_STATUS_USERSTOPLIST = 11 | |
| DIAL_STATUS_GLOBALSTOPLIST = 12 | |
| DIAL_STATUS_WED_WAIT = 13 | |
| DIAL_STATUS_ITSELF_EXC = 14 | |
| DIAL_STATUS_REMOVE = 15 | |
| DIAL_STATUSES = [ | |
| (DIAL_STATUS_WAIT, 'Ожидание вызова (звонка еще нет)'), | |
| (DIAL_STATUS_FAILED, 'Ошибка при вызове абонента'), | |
| (DIAL_STATUS_HANGUP, 'Абонент сбросил звонок'), | |
| (DIAL_STATUS_RING_TIMEOUT, 'Не дозвонились'), | |
| (DIAL_STATUS_BUSY, 'Абонент занят'), | |
| (DIAL_STATUS_ANSWER, 'Абонент ответил'), | |
| (DIAL_STATUS_ROBOT1, 'Ответил автоответчик'), | |
| (DIAL_STATUS_ROBOT2, 'Ответил автоответчик'), | |
| (DIAL_STATUS_NOVALID_BTN, 'Невалидная кнопка'), | |
| (DIAL_STATUS_WED, 'Завершен без действия клиента'), | |
| (DIAL_STATUS_UNKNOWN, 'Неизвестный статус'), | |
| (DIAL_STATUS_USERSTOPLIST, 'Пользовательский стоп-лист'), | |
| (DIAL_STATUS_GLOBALSTOPLIST, 'Глобальный стоп-лист'), | |
| (DIAL_STATUS_WED_WAIT, 'Абонент ответил, но продолжительности разговора не достаточно для фиксации результата в статистике'), | |
| (DIAL_STATUS_ITSELF_EXC, 'Номер абонента совпадает с CallerID'), | |
| (DIAL_STATUS_REMOVE, 'Номер удалён из прозвона'), | |
| ] | |
| # Примеры использование postback в django: | |
| class PostBackForm(forms.Form): | |
| ct_campaign_id = forms.IntegerField() | |
| ct_phone = PhoneNumberField() # See https://github.com/stefanfoulis/django-phonenumber-field | |
| ct_call_id = forms.IntegerField() | |
| ct_completed = forms.DateTimeField(required=False) | |
| ct_status = forms.CharField(required=False) | |
| ct_dial_status = forms.IntegerField() | |
| ct_button_num = forms.IntegerField(required=False) | |
| ct_duration = forms.FloatField(required=False) | |
| def calltools_postback(request): | |
| form = PostBackForm(request.GET or None): | |
| if form.is_valid(): | |
| CallToolsPostBackResult.objects.create(**form.cleaned_data) | |
| return HttpResponse('OK') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment