Интеграция с amoCRM по API
Уровень: сложно
В этой статье мы разберем интеграцию Jay Copilot с CRM на примере бизнес-кейса. В качестве CRM будем рассматривать amoCRM. Возможный бизнес-кейс:
 
- Менеджер находит информацию о тендере, создает сделку в CRM и загружает в нее нужные документы, например, описание объекта закупки.
- Запускается скрипт:
- обращается в CRM и получает URL документов.
- создает приложение для подготовки краткого содержания документов.
- в результате выполнения скрипта в сделку записывается примечание с кратким содержанием документов.
 
Таким образом, менеджеру не придется тратить время на изучение документов и поиск информации. Jay Copilot сделает это самостоятельно.
Преднастройки
- Python 3.
- Библиотека Requests для отправки запросов в сервисы.
- Функция для чтения токенов.
- Аккаунт в amoCRM.
- Токен для доступа к Jay Copilot API. Его можно получить у технической поддержки: support@just-ai.com.
- Необязательно: библиотека amocrm.v2 для работы с amoCRM. В примере будет использоваться Tokens, Lead.
Шаг 1. Написание функции для работы с запросами
Напишем функцию на Python для работы с HTTP-запросами:
import requests
def handle_response(response):
    if response.status_code == 200:
        return response.json()
    else:
        return response.text  
# Блок кода проверяет ответ от сервера после отправки запроса.
# Если все прошло хорошо (код ответа 200), то он возвращает данные этого ответа в формате JSON.
# Если что-то пошло не так (код ответа отличается от 200), то возвращает текст ответа, который может содержать информацию об ошибке.
def read_token_from_file(filename):
    with open(filename, 'r') as file:
        return file.read().strip()
# Блок кода для работы с токенами которые хранятся в файлах: открывает файл с указанным именем и читает из него информацию.
# Информация, которую он прочитал из файла, возвращается как результат работы функции.
# Все лишние пробелы в начале и конце строки удаляются.
Шаг 2. Создание сделки и получение токенов доступа в amoCRM
Создание сделки
- Авторизуйтесь в amoCRM и перейдите в раздел Сделки.
- В правом верхнем углу нажмите Создать сделку.
- Укажите название сделки и нажмите Создать.
- Перейдите на вкладку Файлы и загрузите в сделку нужные документы.
Получение токенов доступа
Для работы с API amoCRM нужно получить токены доступа:
- 
Авторизуйтесь в amoCRM и перейдите в раздел amоМаркет. 
- 
В правом верхнем углу нажмите и выберите Создать интеграцию:   
- 
Затем выберите Внешняя интеграция и укажите обязательные настройки: - Ссылка для перенаправления — можно указать https://app.jaycopilot.com/.
- Предоставить доступ.
- Название интеграции.
- Описание.
 
- Ссылка для перенаправления — можно указать 
- 
Нажмите Сохранить. После этого на вкладке Установленные у вас появится новая интеграция. Этот коннектор пока отключен. 
- 
Нажмите на вашу интеграцию и перейдите на вкладку Ключи и доступы, чтобы получить данные интеграции. Они понадобятся на следующем шаге.   
- 
Нажмите Установить, и коннектор будет готов к использованию. 
Теперь мы уже можем через API обращаться к нашей CRM-системе.
Шаг 3. Подготовка Python-приложения
Настройка авторизации
В документации amoCRM указано, что библиотека для авторизации в CRM поддерживается только для PHP. Но для демонстрации мы возьмем примеры на Python и готовую библиотеку amocrm-api.
Итак, давайте напишем приложение, которое будет обращаться как в amoCRM, так и в API Jay Copilot. Приложению нужно авторизоваться, и для этого мы возьмем метод с токенами из библиотеки для авторизации в amoCRM:
#     Данный блок кода предназначен для подключения к сервису amoCRM через API.
#     Переменные в начале кода — это уникальные ключи и адреса, которые нужны для того, чтобы программа могла войти в ваш аккаунт на сервисе amoCRM.
#     Библиотека amocrm.v2 помогает программе работать с этими ключами и авторизоваться в системе amoCRM.
#     Функция default_token_manager создает менеджер токенов, который используется для авторизации в amoCRM.
#     После выполнения кода программа сохранит два ключа доступа в файлы: access_token.txt и refresh_token.txt. 
#     Эти ключи будут использоваться для авторизации в amoCRM при следующих запросах к API.
subdomain="" # Поддомен
client_id="" # ID интеграции 
client_secret="" # Секретный ключ
redirect_url="" # URL, который указан в интеграции (в нашем примере https://app.jaycopilot.com/)
refresh_token ="" # Длинный код авторизации (действительный 20 мин.)
from amocrm.v2 import tokens
if __name__ == '__main__':
    tokens.default_token_manager( client_id, client_secret, subdomain, redirect_url, 
        storage=tokens.FileTokensStorage(), # По умолчанию FileTokensStorage
        )
    tokens.default_token_manager.init(refresh_token, skip_error=False) 
# Получение нового access token с использованием refresh token
def refresh_access_token():
    token_url = f'https://{subdomain}.amocrm.ru/oauth2/access_token'
    data = {
        'client_id': client_id,
        'client_secret': client_secret,
        'grant_type': 'refresh_token',
        'refresh_token': read_token_from_file('refresh_token.txt')
    }
    response = requests.post(token_url, data=data)
    return response.json().get('access_token')
# Формирование заголовка для запроса в amoCRM
headers = {
    'Content-Type': 'application/json',
    'Authorization': f'Bearer {read_token_from_file("access_token.txt")}'
}
Заполним параметры, где:
- client id— ID интеграции.
- client_secret— секретный ключ.
- subdomain— ваш домен. Указан в строке браузера до- .amocrm.ru/.
- redirect_url— ранее указанный адрес.
- tokens.default_token_manager.init(code=""— временный код авторизации.
Например:
if __name__ == '__main__':
    tokens.default_token_manager( client_id, client_secret, subdomain, redirect_url, 
        storage=tokens.FileTokensStorage(), # По умолчанию FileTokensStorage
        )
    tokens.default_token_manager.init(refresh_token, skip_error=False)
Запуск и тестирование приложения
Когда мы запустим код в первый раз, в папке проекта появятся файлы access_token.txt и refresh_token.txt.
После этого уже можно будет не обновлять каждый раз refresh_token, поэтому закомментируем его:
#    tokens.default_token_manager.init(refresh_token, skip_error=False) 
Когда авторизация прошла успешно, можно написать первый тестовый запрос. Давайте проверим, какие у нас есть сделки:
# Выполним простую проверку, чтобы убедиться, что мы получаем данные из amoCRM.
# Получим информацию о созданных сделках при помощи библиотеки amocrm.v2.
from amocrm.v2 import Lead
leads = Lead.objects.all()
for _ in leads:
    print(_.name, _.id)
Еще пример тестового запроса:
# Получение сущности сделки по ее ID.
# lead_id = 888423 — замените на реальный ID вашей сделки.
# lead = Lead.objects.all(object_id=lead_id)
# Возьмем первый объект из списка сделок
lead = list(Lead.objects.all())[0]
lead_id = lead.id
# Вывод основной информации о сделке
print("ID сделки:", lead.id)
print("Название сделки:", lead.name)
print("Создана:", lead.created_at)
print("Обновлена:", lead.updated_at)
print("Стоимость:", lead.price)
Получение информации о документах в сделке
Получим информацию о файлах в сделке amoCRM:
# Формируем URL для запроса, найдем файлы в сделке
url = f'https://{subdomain}.amocrm.ru/api/v4/leads/{lead_id}/files'
# Отпр авляем GET-запрос
response = requests.get(url, headers=headers)
response = handle_response(response)
response
В ответ получим список файлов в сделке:
{
  "_links": {
    "self": {
      "href": "https://hostname.amocrm.ru/api/v4/leads/1738915/files?limit=50"
    }
  },
  "_embedded": {
    "files": [
      {
        "file_uuid": "8ab921e7-40c1-4323-9849-e87f48c5d9ad",
        "id": 208995
      }
    ]
  }
}
Вернемся к нашему приложению и напишем следующие блоки кода:
# Получаем UUID файлов 
file_uuids = [file["file_uuid"] for file in response["_embedded"]["files"]]
file_uuids
# Получаем домен сервиса файлов 
url = f'https://{subdomain}.amocrm.ru/api/v4/account?with=drive_url'
response = requests.get(url, headers=headers)
response = handle_response(response)
drive_url = response['drive_url']
print(f"домен сервиса файлов: {drive_url}")
# Получаем ссылки на файлы по их UUID
files = []
url = drive_url + '/v1.0/files/'
for uuid in file_uuids:
    response = requests.get(url + uuid, headers=headers)
    response = handle_response(response)
    files.append({
        'name': response['name'],
        'url': response['_links']['download']['href']
    })
files
Этот блок кода должен вернуть в ответ имя и точный URL документа из сделки в amoCRM. Если все успешно, можно приступать к следующему шагу.
Шаг 4. Обращение к Jay Copilot и запись ответа в amoCRM
Подготовка к работе с API
Для рабо ты с API Jay Copilot понадобится токен доступа и базовый URL:
# Настроим доступ к API Jay Copilot
BASE_URL = 'https://app.jaycopilot.com/api/appsAdapter/' # Базовый URL production-окружения Jay Copilot 
API_KEY = read_token_from_file('jay_api_key.txt') # Токен доступа к API Jay Copilot
headers = {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'X-API-KEY': API_KEY
}
Этот блок кода не содержит токен для доступа к API.
Вы можете получить его у технической поддержки: support@just-ai.com.
Сохраните ваш токен в файле jay_api_key.txt в папке с проектом или укажите прямо в коде.
Необязательные шаги
Получение шаблонов приложений:
response = requests.get(BASE_URL + "templates/", headers=headers)
print(response)
response = handle_response(response)
print(str(response)[:500] + "<...>")
templates = response["templates"]
Просмотр списка шаблонов:
for (templateName, templateData) in templates.items():
        print(templateName + ": " + templateData["info"]["title"])
Просмотр настроек шаблона приложение «Краткое содержание»:
templateName = "summarizer"
templates[templateName]
Создание диалога с приложением
После того как мы получили URL документов, можно создать диалог с приложением «Краткое содержание» и запустить само приложение:
# Создадим диалог с приложением «Краткое содержание» и запустим приложение c первым файлом из сделки (без предварительной загрузки файлов по API).
body = {
    'app': {
        'template': 'summarizer',
        'params': {
            'language': 'Russian',
            'fields': 'Содержание',
            'sentences': 4,
            'documentToSummarize': [files[0]['url']]
        }
    }
}
response = requests.post(BASE_URL + "conversations/", headers=headers, json=body)
response = handle_response(response)
response
Далее:
# Запомним ID диалога и приложения
conversationId = response["id"]
appId = response["app"]["id"]
appId
# Сохраним ответ приложения из response в переменную summary и немного отформатируем его
summary = []
summary.append(files[0]["name"] + ":\n" + response["history"][0]["content"][0]["text"])
print(summary[0])
Получим краткое содержание документа.
Запись ответа в сделку amoCRM
Сейчас запишем полученное краткое содержание в сделку в amoCRM по API:
# Запишем ответ от Jay Copilot в примечание к нашей сделки
lead.notes(text="\n\n".join(summary)).save()
# Прочитаем записанное
list(lead.notes.objects.all())[-1]
Готово! Теперь в сделке в amoCRM есть примечание с кратким содержанием документа.