Как формируются поля заголовка и тип скачиваемого файла
Если пароля нет
Response.ContentType:='audio/mpeg'
Если в запросе указать параметр save=1 то
Response.ContentType:='application/octet-stream';
Response.CustomHeaders.Add('Content-Disposition=attachment; filename='+DName+'.mp3');
Если при настройке записи клиент указа пароль шифрования
Response.ContentType:='application/x-zip-compressed';
Если в запросе указать параметр save=1 то
Response.ContentType:='application/octet-stream';
Response.CustomHeaders.Add('Content-Disposition=attachment; filename='+DName+'.zip');
Этот пример позволяет скачать несколько свежих записей, им можно скачивать и много записей, но это займет очень много времени Все необходимые пояснения даны в текстах комментариев.
#!/usr/bin/env python3
import shutil
import requests
import datetime
# Это переменные для запроса звонков и их записей. см. Описание тут https://wiki.sipnet.ru/index.php?title=API_для_интеграции_с_CRM
payload = {'operation': 'calls', # Метод который возвращает статистику звонков и ссылки на записи.
'D1': '00/00/2000', # Если не правильная дата, то сегодня
'D2': '00/00/2000', # Если не правильная дата, то сегодня
'sipuid': '<Login>', # Тут логин или SIP-ID укажите
'password': '<Password>', # Тут конечно пароль нужен
'format': '2' # Это формат возвращаемых данных. Нам очень Json понравился
}
# Это URL запроса статистики
url = 'https://api.sipnet.ru/cgi-bin/Exchange.dll/sip_balance'
# Теперь определим лимит числа скачиваемых файлов. Если это Maxgetfiles=0, то файлы не скачиваются
Maxgetfiles = 10
response= requests.post(url, data=payload)
if response.status_code == requests.codes.ok:
dictionary=response.json()
del response
if dictionary["Result"]:
# нам уже доступна структура данных ответа. Если хотите, напечатайте ее.
# print ("Структура ответа ", dictionary.keys())
if 'calls' in dictionary.keys():
# нам уже доступна структура данных самого звонка. Если хотите, напечатайте ее.
# print ("Структура звонков ", dictionary["calls"][1].keys())
# print ("Структура [1] ", dictionary["calls"][1])
# Далее цикл для обхода всех полученых звонков и печати отчета по ним.
# Для вывода звонков от начала дня к текущему моменту
# for i in dictionary["calls"]:
for i in reversed(dictionary["calls"]):
if 'phone' in i.keys():
print ("======================================================================================================")
print (i["cid"], '',"Дата= " ,i["gmt"],"Номер= ",i["phone"], "АОН= ", i["cli"], "Длительность= ", i["duration"])
print (str(datetime.datetime.utcnow()))
else:
print ("Странный звонок у него нет номера B")
if 'url' in i.keys():
# Это URL файла с записью разговора.
print (i["url"])
# Проверяем, не исчерпан ли лимит скачивания файлов
if Maxgetfiles>0:
# Скачаем и сохраним все обнаруженные записи имя сохраненного файла состоит из cid звонка.
response = requests.get(i["url"], stream=True)
if response.status_code == requests.codes.ok:
FileName = str(i["gmt"])+"_"+str(i["phone"])
if response.headers['Content-Type'] == 'audio/mpeg':
FileName = FileName+".mp3"
else:
FileName = FileName+".zip"
FileName = FileName.replace('/', '-').replace(':', '-')
with open(FileName, 'wb') as out_file:
shutil.copyfileobj(response.raw, out_file)
del response
Maxgetfiles -= 1
else:
print ("Запись не скачалась. Получили код ", response.status_code)
else:
print ("Лимит скачивания исчерпан")
break
else:
print ("Нет MP3 записи этого звонка")
else:
print ("Результат нормальный, но Нет звонков")
else:
print ("Что-то пошло не так. Плохой результат получили ", dictionary["Result"])
else:
print ("Совсем плохо. Получили код ", response.status_code)
Это пример немного сложнее, но зато позволяет скачать около 1500 записей за пару минут.
#!/usr/bin/env python3
import shutil
import requests
import datetime
from multiprocessing import Pool
# Это переменные для запроса звонков и их записей. см. Описание тут https://wiki.sipnet.ru/index.php?title=API_для_интеграции_с_CRM
payload = {'operation': 'calls', # Метод который возвращает статистику звонков и ссылки на записи.
'D1': '00', # Если не правильная дата, то сегодня
'D2': '00', # Если не правильная дата, то сегодня
'sipuid': '<SIPID>', # Тут логин или SIP-ID укажите
'password': '<Password>', # Тут конечно пароль нужен
'format': '2' # Это формат возвращаемых данных. Нам очень Json понравился
}
# Это URL запроса статистики
url = 'https://api.sipnet.ru/cgi-bin/Exchange.dll/sip_balance'
# Теперь определим лимит числа скачиваемых файлов. Если это Maxgetfiles=0, то файлы не скачиваются
# Не работает в многопотоковом варианте.
#Maxgetfiles = 10
# Описываем процедуру скачивания записи разговора
def create_MP3file(callinfo):
if 'phone' in callinfo.keys():
print ("======================================================================================================")
print (callinfo["cid"], '',"Дата= " ,callinfo["gmt"],"Номер= ",callinfo["phone"], "АОН= ", callinfo["cli"], "Длительность= ", callinfo["duration"])
print ("Время в момент скачивания файла: ", str(datetime.datetime.utcnow()))
if 'url' in callinfo.keys():
# Это URL файла с записью разговора.
print (callinfo["url"])
# Скачаем и сохраним все обнаруженные записи имя сохраненного файла состоит из cid звонка.
response = requests.get(callinfo["url"], stream=True)
if response.status_code == requests.codes.ok:
FileName = str(callinfo["gmt"])+"_"+str(callinfo["phone"])
if response.headers['Content-Type'] == 'audio/mpeg':
FileName = FileName+".mp3"
else:
FileName = FileName+".zip"
FileName = FileName.replace('/', '-').replace(':', '-')
with open(FileName, 'wb') as out_file:
shutil.copyfileobj(response.raw, out_file)
del response
else:
print ("Запись не скачалась. Получили код ", response.status_code)
else:
print ("Нет MP3 записи этого звонка")
else:
print ("Странный звонок у него нет номера B")
# Это основной метод, который получает список звонков и запускает многопотоковое скачивание
if __name__ == '__main__':
print ("Начало исполнения: ", str(datetime.datetime.utcnow()))
# Это создание пула исполнителей, которые будут скачивать записи
# Число исполнителей нужно выбирать под компьютер, на котором выполняется. У меня 1500 записей скачались менее чем за 2 минуты
pool = Pool(10)
# Запрос статистики со ссылками на файлы записи разговоров
response = requests.post(url, data=payload)
if response.status_code == requests.codes.ok:
dictionary=response.json()
del response
# Начинаем анализ того, что получили
if dictionary["Result"]:
# нам уже доступна структура данных ответа. Если хотите, напечатайте ее.
# print ("Структура ответа ", dictionary.keys())
if 'calls' in dictionary.keys():
# нам уже доступна структура данных самого звонка. Если хотите, напечатайте ее.
# print ("Структура звонков ", dictionary["calls"][1].keys())
# print ("Структура [1] ", dictionary["calls"][1])
# Далее запуск массового многопоточного скачивания записей всех полученых звонков.
pool.map(create_MP3file, dictionary["calls"])
pool.close()
pool.join()
else:
print ("Результат нормальный, но Нет звонков")
else:
print ("Что-то пошло не так. Плохой результат получили ", dictionary["Result"])
else:
print ("Совсем плохо. Получили код ", response.status_code)
# Печатаем время завершения работы и выходим.
print ("Конец исполнения: ", str(datetime.datetime.utcnow()))
Записи разговоров нужны не только для доказательства правоты и "на всякий случай". Бывает необходимо анализировать разговоры и их качество на регулярной основе.
Конечно, прослушивать разговоры может ответственный сотрудник, но гораздо интереснее когда разговоры анализируются специальными аналитическими центрами. Так можно выявить гораздо больше проблем и вовремя принять меры для улучшения работы вашей команды.
На пути реализации такой интеграции с аналитическим службами возникает проблема с безопасностью. Для работы предыдущих скриптов требуется логин и пароль от аккаунтов, а передавать их третьей стороне крайне не желательно.
Ниже приведем пример кода скрипта, который авторизуется не через логин и пароль, а через, специально для этого предназначенный, ключ API.
#!/usr/bin/env python3
import shutil
import requests
import datetime as dt
# Это переменные для запроса звонков и их записей. см. описание по ссылкам ниже
# https://newapi.sipnet.ru/apidoc.pdf (Ранее https://wiki.sipnet.ru/index.php?title=API_для_интеграции_с_CRM)
# URL основной операции имеет вид https://newapi.sipnet.ru/api.php?operation=getrec& apikey=
# Определим лимит числа скачиваемых файлов. Если это Maxgetfiles=0, то файлы не скачиваются
Maxgetfiles = 10
# Это URL запроса статистики и его основные параметры
URL = 'https://newapi.sipnet.ru/api.php'
# Создадим массив с параметрами запроса.
payload = {'operation': 'calls', # Метод который возвращает статистику звонков и ссылки на записи.
'apikey': 'fdde2154-4ca5-4ad8-7de3-07affa5c4ca3', # Ключ авторизации по API получить в панели администратора ВАТС.
'showchild': '1', # Если указан 1 то звонки выводятся и с дочерних аккаунтов.
'D1': '01-02-2019', # Если не правильная дата, то сегодня
'D2': '03-02-2019', # Если не правильная дата, то сегодня
'format': 'json' # Это формат возвращаемых данных. Нам очень Json понравился
}
# Напечатаем исходные данные, на всякий случай.
print("===============================================")
print(URL)
print(payload)
print(Maxgetfiles)
print("===============================================")
# Запрашиваем статистику звонков и начинаем разбор полученного.
response= requests.post(URL, data=payload)
if response.status_code == requests.codes.ok:
dictionary=response.json()
# нам уже доступна структура данных ответа. Если хотите, напечатайте ее.
# print ("Структура ответа ", dictionary.keys())
del response
if dictionary["status"] != 'error':
if 'calls' in dictionary.keys():
# нам уже доступна структура данных самого звонка. Если хотите, напечатайте ее.
# print ("Структура звонков ", dictionary["calls"][1].keys())
# print ("Структура [1] ", dictionary["calls"][1])
# Далее цикл для обхода всех полученных звонков и печати отчета по ним.
# Статистика обрабатывается от момента запроса к началу дня
# Для вывода звонков от начала дня к текущему моменту
# for i in dictionary["calls"]:
for i in reversed(dictionary["calls"]):
if 'Phone' in i.keys():
print ("======================================================================================================")
print (i["CID"], '', i["Account"], '', i['Direction'], '\n', "Дата= " , i["GMT"], "Номер= ", i["Phone"], "АОН= ", i["CLI"], "Длительность= ", i["Duration"])
else:
print ("Странный звонок у него нет номера B")
if 'URL' in i.keys():
# Обнаружен URL файла с записью разговора.
print (i["URL"])
# Проверяем, не исчерпан ли лимит скачивания файлов
if Maxgetfiles>0:
# Скачаем и сохраним все обнаруженные записи имя сохраненного файла состоит из cid звонка.
response = requests.get(i["URL"], stream=True)
if response.status_code == requests.codes.ok:
# Тут мы формируем имя файла записи разговора, данные берем из массива с описанием параметров звонка
FileName = str(int(dt.datetime.strptime(i["GMT"], '%d.%m.%Y %H:%M:%S').timestamp()))+"_"+i["CLI"]+"_"+i["Phone"]+"_"+i['Direction']
# Определяем тип скаченного файла и выбираем нужное расширение имени файла
if response.headers['Content-Type'] == 'audio/mpeg':
FileName = FileName+".mp3"
else:
FileName = FileName+".zip"
FileName = FileName.replace('/', '-').replace(':', '-')
# Сохраняем скаченный файл с нужным именем.
with open(FileName, 'wb') as out_file:
shutil.copyfileobj(response.raw, out_file)
del response
Maxgetfiles -= 1
else:
print ("Запись не скачалась. Получили код ", response.status_code)
else:
print ("Лимит скачивания исчерпан")
break
else:
print ("Нет MP3 записи этого звонка")
else:
print ("Результат нормальный, но Нет звонков")
else:
print ("Что-то пошло не так. Плохой результат получили ")
print ("Статус ответа ", dictionary["status"])
print ("Ошибка ", dictionary["errorCode"], dictionary["errorMessage"])
else:
print ("Совсем плохо. Получили код ", response.status_code)