API запрос для добавления звонков с хранением данных на S3

Для безопасного хранения данных в облачной системе можно использовать S3 совместимое хранилище. Такое есть у Yandex Cloud, AWS, selcdn и других провайдеров IaaS. При этом Qolio может иметь возможность проигрывать записи, которые хранятся в приватных бакетах. Для этого нужно настроить хранилище в вашем провайдере и прислать нам следующие данные:

  • Ссылку на вашу интеграцию

  • AWS_ACCESS_KEY_ID - Yandex или AWS S3 key, берется из кабинета IaaS.

  • AWS_SECRET_KEY - Yandex или AWS S3 secret берется из кабинета IaaS.

  • AWS_REGION - регион S3, в котором хранятся записи. Для Yandex S3 это значение всегда равно "ru-central1"

  • AWS_BUCKET_NAME - имя бакета S3, где лежат звонки

  • AWS_S3_ENDPOINT - endpoint самого S3, например для Yandex S3 он всегда такой "https://storage.yandexcloud.net"

Далее в документе будет рассказано, как написать скрипт, который будет выгружать эти данные

Пример выгрузки записей в S3

Для успешной работы Qolio должен принимать данные о телефонных звонках через API по http(s). Для упрощения работы используется "Custom HTTP интеграция", подробности о которой можно почитать тут.

В Qolio необходимо передавать следующие данные о звонках:

  • ID оператора в системе (operator_id) - это идентификатор оператора в системе, с которым связан звонок.

  • Длительность (duration) и направление звонка (direction)

  • Номер звонящего клиента (client_phone_number)

  • Uuid - идентификатор звонка (должен быть уникальным в системе)

  • URL Ссылку на запись разговора (media_url), по которой можно получить доступ к записи разговора. Эта ссылка будет передаваться в плеер сервиса Qolio после того, как будет подписана на стороне S3.

media_url в данном случае является ссылкой временного доступа которая генерируется с помощью s3 клиента. В текущем примере интеграции подразумевается что файл предварительно загружается на s3 совместимое хранилище (Yandex Cloud) и для его загрузки в Qolio cоздается ссылка временного доступа (presigned url)

Пример media_url: https://storage.yandexcloud.net/naumen-records/records/2021/05/21/telephony_1_piu_732460.mp3

Также есть возможность расширить набор этих данных через поле metacontent (custom_fields). Подробности можно прочитать в статье про Custom HTTP интеграцию.

Скрипт для загрузки телефонных звонков в Qolio

Важно! - Скрипт написан для python 2.7 Для версии Python 3+ будут отличаться импорты pip пакетов

Для коннекта к S3 используется boto3 пакет (хорошо документированный клиент для aws сервисов для python https://github.com/boto/boto3)

#окружение для masOs
sudo easy_install pip
sudo pip install requests
python -m pip install nose
python -m pip install tornado
python -m pip install boto3

#не обязательно, но более удобная интерактивная консоль
python -m pip install IPython

Для запуска скрипта

python -m IPython tavabilko_ex.py
#tavabilko_ex.py

import boto3
import requests
import os
import botocore
import json

from urlparse import urlparse
from botocore.config import Config
from botocore.exceptions import ClientError

# Yandex s3 credentials
AWS_ACCESS_KEY_ID = "AWS_ACCESS_KEY_ID"
AWS_SECRET_KEY = "AWS_SECRET_KEY"
AWS_REGION = "ru-central1"
AWS_BUCKET_NAME = "AWS_BUCKET_NAME"
AWS_S3_ENDPOINT = "https://storage.yandexcloud.net"

# DealApp integration credentials
INTEGRATION_URL="https://api.prod1.qolio.ru/api/v1/integrations/07c43d06-f1b9-4e59-b9a9-4fe73b41886c/phone_calls"
AUTHORIZATION_TOKEN="bfcece7e7736f4612781d3709df30bae717b90e82ecaefecb3cbdf5bd902536ba4cb2d09dc7456360b118a27285c9ffd615be93becb36564113d788617ee178f"

# url to upload file
UPLOAD_EXAMPLE = 'https://demo-records.s3.eu-central-1.amazonaws.com/News_Room_News.mp3'

def upload_file_to_aws_s3(url='', file_prefix='phone_call_ex'):
    file_url = ''
    # get the connection to Yandex S3 Bucket
    s3 = boto3.resource(
        's3',
        aws_access_key_id = AWS_ACCESS_KEY_ID,
        aws_secret_access_key = AWS_SECRET_KEY,
        region_name = AWS_REGION,
        endpoint_url=AWS_S3_ENDPOINT
    )
    
    response = requests.get(url)
    if response.status_code==200:
        raw_data = response.content
        url_parser = urlparse(url)
        file_name = os.path.basename(url_parser.path)
        key = file_prefix + "/" + file_name

        try:
            # write raw data to new file_name on the server
            with open(file_name, 'wb') as new_file:
                new_file.write(raw_data)
    
            # open the server file in read mode and upload to Yandex S3 Bucket.
            data = open(file_name, 'rb')
            s3.Bucket(AWS_BUCKET_NAME).put_object(Key=key, Body=data)
            data.close()
            
            # generate presigned URL for 1 hour access of uploaded file in Yandex S3 Bucket
            file_url = create_presigned_url(AWS_BUCKET_NAME, key)
        except Exception as e:
            print("Error in file upload %s." % (str(e)))
        
        finally:
            # close and remove file from server
            new_file.close()
            os.remove(file_name)
            print("Attachment Successfully save in S3 Bucket url %s " % (file_url))
    else:
        print("Cannot parse url")
    return file_url


def create_presigned_url(bucket_name, object_name, expiration=3600):
  
    #config = Config(signature_version=botocore.UNSIGNED)
    s3_client = boto3.client(
        's3',
        aws_access_key_id = AWS_ACCESS_KEY_ID,
        aws_secret_access_key = AWS_SECRET_KEY,
        region_name = AWS_REGION,
        endpoint_url=AWS_S3_ENDPOINT
    )

    try:
        response = s3_client.generate_presigned_url('get_object',
                                                    Params={'Bucket': bucket_name,
                                                            'Key': object_name},
                                                    ExpiresIn=expiration)
    except ClientError as e:
        print("Smth wrong: %s" % (str(e)))

    return response    


def send_phone_call_to_dealapp(phone_call_url):
  phone_call_are_sent_successfully = True
  headers = {'Content-Type': 'application/json', 'Authorization': AUTHORIZATION_TOKEN}

  serialized_phone_call = {
    "uid":                 "7b2331ca-adcb-4f15-811b-6b6cfddb2baf", 
    "operator_id":         "petr.petrov",
    "direction":           "incoming",
    "duration":            410.1,
    "started_at":          "2021-03-16T07:10:00.588Z",
    "client_phone_number": "+375334522453",
    "media_url":           phone_call_url
  }
  try:
    result = requests.post(url=INTEGRATION_URL, data=json.dumps(serialized_phone_call), headers=headers)
    if(result.status_code != 200):
        print("Phone call from url {} can not be sent to DealApp".format(phone_call_url))
        print(result.text, "Reason")
  except:
    phone_call_are_sent_successfully = False
    print("Can't connect to DealApp service")

  return phone_call_are_sent_successfully


def main():
  presigned_file_url = upload_file_to_aws_s3(UPLOAD_EXAMPLE)
  result = send_phone_call_to_dealapp(presigned_file_url)
  print("Upload to DealApp was successfull : {}".format(result))


if __name__ == '__main__':
    main()

В этом скрипте есть следующие константы:

Константы

INTEGRATION_URL - Значение AUTHORIZATION_TOKEN берется из модального диалога интеграции (Токен интеграции).

AUTHORIZATION_TOKEN - Значение INTEGRATION_URL берется из модального диалога интеграции (URL интегрируемого приложения).

AWS_ACCESS_KEY_ID = Yandex S3 key берется из кабинета Yandex Cloud. AWS_SECRET_KEY = Yandex S3 secret берется из кабинета Yandex Cloud. AWS_REGION = "ru-central1" (для Yandex S3 всегда такой) AWS_BUCKET_NAME = имя бакета Yandex S3, где лежит звонок AWS_S3_ENDPOINT = "https://storage.yandexcloud.net" (для Yandex S3 всегда такой)

Описаний функций скрипта

Last updated