Начало работы

В данной статье мы рассмотрим основные шаги, которые нам необходимо сделать, чтобы начать разрабатывать интеграцию с API чатов.

Чтобы приступить к интеграции вам потребуется:

  • Активный аккаунт amoCRM. Можно зарегистрировать аккаунт с пробным периодом на сайте https://www.amocrm.ru
  • Зарегистрированный канал чатов для использования в API чатов.
  • Открытый публичный endpoint на вашем сервере, куда будут приходить уведомления о новых сообщениях из интерфейса amoCRM

Оглавление

Регистрация канала

В рамках amoCRM за управление чатами, каналами, сообщениями отвечает API Чатов.
За управление сделками, контактами, задачами и другими сущностями, в том числе источниками отвечает непосредственно сама платформа amoCRM.

По-умолчанию, мы считаем, что канал представляет собой подключение одного типа чата (WhatsApp, Viber, Facebook, Онлайн-чат на cайт и другие)
и позволяет возможность передавать сообщения между amoCRM и конечной чат-платформой через интеграцию.

Для регистрации канала для API чатов, вам необходимо оставить заявку в техническую поддержку.
Вы можете оставить заявку одним из способов:

  • Наши страницы в соц. сетях
  • Из вашего аккаунта amoCRM через обращение в техническую поддержку

Изначально канал регистрируется, как приватный, то есть доступный в ограниченном количестве аккаунтов.
После реализации интеграции, его можно сделать публичным, чтобы появилась возможность подключать его и в другие аккаунты.

Для регистрации канала потребуются следующие данные и ответы на вопросы:

  1. Название сервиса, с которым вы планируете разрабатывать интеграцию. Название должно состоять из латинских символов и не
    должно начинаться с цифры. Название сервиса будет отображаться вместе с SVG иконкой в социальном профиле, то
    есть под именем контакта, созданного с помощью данного канала чата.
  2. Webhook URL, на который будут присылаться сообщения из amoCRM. URL должен быть вида [https://domain.com/location/:scope_id]().
    Маркер :scope_id будет динамически подставляться системой. С его помощью вы сможете идентифицировать,
    из какого аккаунта пришло сообщение.
  3. В начале разработки необходимо предоставить список аккаунтов (ID аккаунтов), которым будет разрешена работа с новым каналом.
  4. Необходима ли вам поддержка функции "Написать первым"?
  5. Нужна ли поддержка временного окна? (Мы считаем, что вне временного окна возможность написать сообщение пользователю ограничена)
    1. Временное окно (в секундах)
    2. Нужно ли отображать выбор шаблона после окончания временного окна (функционал доступен только на .com аккаунтах)
  6. E-mail для связи в случае возникновения ошибок.
  7. SVG иконка вашего канала. Иконка должна иметь форму круга или вписываться в круг. Размер 14х14px
  8. client_uuid интеграции, которая будет работать с API чатов
  9. Код виджета интеграции, которая будет работать с API чатов и API источников
  10. Планируете ли вы тиражировать решение на всех пользователей amoCRM?
    1. Есть ли уже подобное решение в amoCRM?
    2. Если подобное решение есть, в чем уникальность вашего?

В ответ вам будут предоставлены параметры доступа к API чатов и параметры бота зарегистрированного канала.

Срок рассмотрения заявки 1-3 рабочих дня.

Пример параметров доступа к API онлайн-чатов

Параметр Пример
Символьный код канала amo.ext.some_code
ID канала a4490ccc-5d7f-11e7-907b-a6006ad3dba0
Секретный ключ da39a3ee5e6b4b0d3255bfef95601890afd80709
Список аккаунтов, для которых одобрено подключения канала 11223344 (somesubdomain)
11334455 (somesubdomain2)

Пример параметры бота зарегистрированного канала

Параметр Тип Описание
id string Идентификатор участника чата на стороне amoCRM
client_id string Идентификатор участника чата на стороне интеграции
name string Название бота

После регистрации канала вы можете начать разработку вашей интеграции.

Авторизация

Авторизация в API Чатов отличается от той авторизации, которая используется в других методах API amoCRM.
Для работы с API Чатов не нужно передавать Access Token,
но необходимо во все запросы включать следующие заголовки:

  • Date
  • Content-Type
  • Content-MD5
  • X-Signature
Заголовок Описание
Date Дата и время формирования запроса, подпись будет действительна 15 минут от даты формирования запроса
Content-Type Тип данных запроса, на данный момент поддерживается только application/json
Content-MD5 Для тела запроса необходимо рассчитать md5 хеш и в заголовке указывать в нижнем регистре. При этом важно иметь ввиду, что тело запроса обсчитывается как поток байт, без учета окончания json разметки, и если в конце есть "n" или пробелы они тоже будут учитываться.
Для GET запросов, md5 тоже необходимо рассчитать, даже если ничего не передается в теле запроса (получится md5 от пустой строки)
X-Signature Подпись запроса. Формируется строка из названия метода (GET/POST) в верхнем регистре и значений (как указаны в запросе без изменений) заголовков путем объединения через "n". Значения заголовков идут в определенном порядке. В общем случае если заголовок отсутствует, вместо него указывается пустая строка.
Далее к строке добавляем запрашиваемый путь из url без протокола и домена (без GET параметров).

Получившуюся строку обсчитываем по HMAC-SHA1, а в качестве секрета используем секрет канала, полученный при регистрации. Получившийся хеш в нижнем регистре указываем в заголовке X-Signature

Формирование подписей и заголовков

Как уже было сказано ранее, все запросы должны иметь ряд заголовков, в том числе X-Signature, в значении которого находится SHA1 хэш от тела запроса, подписанный секретным ключом.
Использование секретного ключа позволяет проверить целостность полезных данных и их происхождение.

Пример формирования запроса на PHP:

<?php

$secret = '5a44c5dff55f3c15a4cce8d7c4cc27e207c7e189';
$method = 'POST';
$contentType = 'application/json';
$date = date(DateTimeInterface::RFC2822);
$path = '/v2/origin/custom/f90ba33d-c9d9-44da-b76c-c349b0ecbe41/connect';

$url = "https://amojo.amocrm.ru" . $path;

$body = [
    'account_id' => 'af9945ff-1490-4cad-807d-945c15d88bec',
    'title' => 'ScopeTitle', //Название вашего канала, отображаемое пользователю
    'hook_api_version' => 'v2',
];
$requestBody = json_encode($body);
$checkSum = md5($requestBody);

$str = implode("n", [
    strtoupper($method),
    $checkSum,
    $contentType,
    $date,
    $path,
]);

$signature = hash_hmac('sha1', $str, $secret);

$headers = [
    'Date' => $date,
    'Content-Type' => $contentType,
    'Content-MD5' => strtolower($checkSum),
    'X-Signature' => strtolower($signature),
];

$curlHeaders = [];
foreach ($headers as $name => $value) {
    $curlHeaders[] = $name . ": " . $value;
}

echo $method . ' ' . $url . PHP_EOL;
foreach ($curlHeaders as $header) {
    echo $header . PHP_EOL;
}
echo PHP_EOL . $requestBody . PHP_EOL;

$curl = curl_init();
curl_setopt_array($curl, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 5,
    CURLOPT_CUSTOMREQUEST => $method,
    CURLOPT_POSTFIELDS => $requestBody,
    CURLOPT_HTTPHEADER => $curlHeaders,
]);

$response = curl_exec($curl);
$err = curl_error($curl);
$info = curl_getinfo($curl);
curl_close($curl);
if ($err) {
    $result = "cURL Error #:" . $err;
} else {
    echo "Status: " . $info['http_code'] . PHP_EOL;
    echo $response . PHP_EOL;
}

Комментарий для действующих интеграций:
Ранее подпись запроса рассчитывалась по другой схеме, но она не позволяла авторизовать запросы без тела. Старая схема подписи продолжает действовать для существующих подключений и методов, в которых она использовалась.
Все новые методы, начиная с осени 2019, работают только с новой схемой подписи, которая была описана выше и мы рекомендуем обновить используемую подпись в существующих интеграциях.

Общие требования к запросам

  • Все запросы к API чатов необходимо производить на домен amojo.amocrm.ru или amojo.amocrm.com для аккаунтов в домене *.amocrm.com
  • Все запросы к API чатов должны иметь заголовки: Date, Content-Type, Content-MD5, X-Signature
  • Запрещено использовать секретный ключ в JS. Все запросы с использованием секрета должны выполняться только с backend части вашего приложения
  • Параметры передаются в теле запроса в формате JSON
  • API чатов имеет строгую типизацию, поэтому в описании параметров отражен ожидаемый тип аргумента. Обратите на это внимание.

Получение ID аккаунта в сервисе чатов

Для работы с конкретным аккаунтом в API Чатов, вам необходимо знать специальный строковый ID аккаунта в API Чатов,
он отличается от ID аккаунта, который используется в других методах API amoCRM.
Именно этот ID будет использоваться для подключения аккаунта к вашему каналу.

Получить его можно двумя способами:

  • В веб версии системы, с помощью скрипта Javascript
  • C помощью запроса к API amoCRM

Javascript

Данный способ может использоваться интеграцией с загруженным архивом.
Для получения ID аккаунта в сервисе чатов нужно выполнить следующий скрипт:

AMOCRM.constant('account').amojo_id

API

Идентификатор аккаунта в API Чатов можно также получить через API сделав GET запрос на метод
информации об аккаунте – /api/v4/account?with=amojo_id

Пример получения с использованием библиотеки amoCRM.

<?php
/**
 * Получение id аккаунта для работы с online чатами
 */

// composer require amocrm/amocrm-api-library

require __DIR__ . '/vendor/autoload.php';

$clientId = 'dbcb764d-b02d-4a3b-bc4d-25e1d80fdcad';
$clientSecret = 'BbL70GJrKcBlg8cag9VaXKxrzUnxiaPOG4XU3Sc6ddFj9GxOStKryI4wOK4g9kjo';
$redirectUri = 'https://example.com/sample-integration';
$baseDomain = 'subdomain.amocrm.ru';
$code = <<<EOF
def50200189...<код авторизации интеграции>...159f568
EOF;

$apiClient = new AmoCRMClientAmoCRMApiClient($clientId, $clientSecret, $redirectUri);
$apiClient->setAccountBaseDomain($baseDomain);
try {
    $accessToken = $apiClient->getOAuthClient()->getAccessTokenByCode($code);

    $apiClient->setAccessToken($accessToken);

    $account = $apiClient->account()->getCurrent([AmoCRMModelsAccountModel::AMOJO_ID]);
    echo "amojoId: " . $account->getAmojoId() . PHP_EOL;
} catch (Exception $e) {
    die((string)$e);
}

Пример выполнения кода:

amojoId: 52a350c1-b0e1-4e38-ab2e-125e5f046dfa

Получение ID пользователей в сервисе чатов

Для импорта истории сообщений или добавлении отправленных сообщений в стороннем приложении, вам может понадобиться информация о пользователях аккаунта amoCRM.
А точнее их идентификаторы в API чатов, так как они отличаются от ID, который используется в других методах API amoCRM.

Получить их можно двумя способами:

  • ID текущего авторизованного пользователя можно получить в веб версии системы, с помощью скрипта Javascript
  • C помощью запроса к API amoCRM

Javascript

Данный способ может использоваться интеграцией с загруженным архивом.
Для получения ID аккаунта в сервисе чатов нужно выполнить следующий скрипт:

AMOCRM.constant('user').amojo_id

API

Идентификаторы пользователей в API Чатов можно также получить через API сделав GET запрос на метод
получения списка пользователей – /api/v4/users?with=amojo_id

Пример получения с использованием библиотеки amoCRM.

<?php
/**
 * Получение id аккаунта для работы с online чатами
 */

// composer require amocrm/amocrm-api-library

require __DIR__ . '/vendor/autoload.php';

$clientId = 'dbcb764d-b02d-4a3b-bc4d-25e1d80fdcad';
$clientSecret = 'BbL70GJrKcBlg8cag9VaXKxrzUnxiaPOG4XU3Sc6ddFj9GxOStKryI4wOK4g9kjo';
$redirectUri = 'https://example.com/sample-integration';
$baseDomain = 'subdomain.amocrm.ru';
$code = <<<EOF
def50200189...<код авторизации интеграции>...159f568
EOF;

$apiClient = new AmoCRMClientAmoCRMApiClient($clientId, $clientSecret, $redirectUri);
$apiClient->setAccountBaseDomain($baseDomain);
try {
    $accessToken = $apiClient->getOAuthClient()->getAccessTokenByCode($code);

    $apiClient->setAccessToken($accessToken);

    $users = $apiClient->users()->get(null, [AmoCRMModelsUserModel::AMOJO_ID]);
    foreach ($users as $user) {
        echo "amojoId: " . $user->getAmojoId() . PHP_EOL;
    }
} catch (Exception $e) {
    die((string)$e);
}

Пример выполнения кода:

amojoId: 31fc2bea-902f-925c-6a3d-dcdac4766090

Подключение канала к аккаунту

Следующим шагом после авторизации и получения ID аккаунта в API чатов, вам необходимо подключить аккаунт к вашему каналу (связать аккаунт с каналом).

Чтобы подключить аккаунт к каналу чатов, вам необходимо отправить POST запрос,
передав в теле запроса amojo_id подключаемого аккаунта.
В ответ вы получите уникальный scope_id аккаунта для этого канала, который будет использоваться в дальнейшем при отправке сообщений.

Подробнее о методе подключения


После подключения канала к аккаунту разберем несколько вариантов интеграции в примерах по шагам