# 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-or-baza-znanii/integracii/podklyuchenie-po-api/integraciya-po-api-dlya-ip-telefonii-i-chatov/api-zapros-dlya-dobavleniya-zvonkov-s-khraneniem-dannykh-na-s3.md).

В 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](https://storage.yandexcloud.net/naumen-records/records/2021/05/19/node_1_domain_1_nauss_0_1620293403_73360.mp3)

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

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

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

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

```bash
#окружение для 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
```

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

```bash
python -m IPython tavabilko_ex.py
```

```python
#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 всегда такой)

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

| Имя                            | Описание                                                                                                                                          |   |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- | - |
| main()                         | запускает скрипт                                                                                                                                  |   |
| upload\_file\_to\_aws\_s3()    | создает соединение через boto клиент к Yandex S3 сервису и загружает тестовый аудио файл в приватный бакет. возвращает ссылку на загруженный файл |   |
| create\_presigned\_url         | создает ссылку доступа к файлу , при указании expiration аргумента создает временную ссылку                                                       |   |
| send\_phone\_call\_to\_dealapp | принимает ссылку на телефонный звонок, преобразует в JSON и отправляет на сервис Qolio                                                            |   |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://wiki.qolio.ru/qolio-or-baza-znanii/integracii/podklyuchenie-po-api/integraciya-po-api-dlya-ip-telefonii-i-chatov/api-zapros-dlya-dobavleniya-zvonkov-s-khraneniem-dannykh-na-s3.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
