Skip to content

opravdin/amohook

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Обработчик Webhooks от AmoCRM

Что делает эта библиотека

Она позволяет с легкостью обрабатывать WebHooks от AmoCRM без необходимости писать большое количество логики проверок сущности хука и события, а также наличия различных переменных в теле запроса. Просто сфокусируйтесь на обработке, а разбор данных доверьте этому классу.

Установка

composer require opravdin/amohook

Использование

В AmoCRM задать точку входа для ваших хуков (URL обработчика). Можно выбрать только необходимые события или все сразу.

Метод 1. Использование цепочки вызова

Настройка воронки обработки вебхука. Регистрируйте 3 вида обработчиков

  1. Непосредственный обработчик хука - подходит для логики обработки
  2. Обработчик ошибок - вызывается когда первая группа завершается с исключением. Могут прервать дальнейшую работу обработчиков.
  3. Финишные обработчики - запускаются когда каждый обработчик из 1 группы завершает работу. Получают во входных параметро
use Opravdin\AmoHook\AmoHook;
// Удобно подключить константы с событиями и сущностями:
use Opravdin\AmoHook\Events;
use Opravdin\AmoHook\Entities;

// Для Laravel удобнее применить $request->all() вместо $_POST
AmoHook::build($_POST) 
    ->register('any', 'any', function ($payload) {
        // Вызовется для любой сущности при любом событии, подходит для отладки и логгирования приходящих данных
        Log::debug("Action: {$payload['action']} on entity {$payload['entity']}");
    })
    ->register(
        ['contacts', 'companies'], ['update', 'add'], function ($payload) {
        /**
         * Вызывается только для контактов и компаний при обновлении и добавлении
         * Для register первые 2 параметра могут быть как строками, так и наборами строк. 
         * При этом обработчик будет выполнен если произойдет любое из указанных события с любой указанной сущностью
         */
    })
    ->register([Entities::COMPANY, Entities::CONTACT], [Events::ADD, Events::UPDATE], function ($payload) {
        // Этот обработчик запустится при тех же условиях, что и предыдущий
    })

    // Можно подключить методы для обработки ошибок (один или несколько)
    ->onError(function ($exception, $payload, $entity, $action) {
        // Этот код выполнится при возникновении исключения при обработке
        Log::error("Произошла ошибка при обработке хука: ".$exception->getMessage());

        /**
         * $exception - возникшее исключение
         * $payload - данные, аналогичные передаваемым в обработчик
         * $entity, $action - сущность и событие, в контексте которых выполнялась обработка хука
         */

        // Завершить выполнение обработчиков (вернуть значение === true)
        // Все остальные onError все еще будут выполнены, а также after
        // Другие onError не смогут предотвратить отмену работы остальных обработчиков
        return true;

        // Продолжить выполнение других обработчиков (любое значение !== true)
        return false; 
    })

    // Выполнить после каждого обработчика (можно несколько)
    ->after(function ($result, $payload) {
        // $result - результаты работы
        // $payload - событие, по которому была работа
    })
    // Запустить цепочку
    ->handle();

Регистрируйте сразу несколько действий/сущностей при помощи массивов или передавайте строки для выборочной регистрации. Метод получит событие как параметр вызова.

содержимое $payload, передаваемого в обработчики:

  • entity - название сущности в соответствие с хуком амо (кроме компаний, они обрабатываются как companies)
  • action - название события (например, add или update)
  • data - тело события. Включает в себя все данные из хука по данному событию (id, name и так далее). Эквивалентно $request['сущность']['событие'][0]
[
    'entity' => 'contacts', 
    'action' => 'update',
    'data' => [
        // Содержимое хука, например
        'id' => 123, 
        'name' => 'Иван Иванов',
        // ...и так далее
    ]
]

Метод 2. Получение данных в упрощенной форме

Самый простой вариант использования: получение обработанного массива данных с выделенным типом сущности и события. Массив содержит сущности, аналогичные $payload из метода выше

use Opravdin\AmoHook\AmoHook;

// Использование без фреймворков
$raw = $_POST;
$data = (new AmoHook($_POST))->get();
foreach ($data as $event) {
    echo "Action: {$data['action']} on entity {$data['entity']}";
}

// Или через build
$raw = $_POST;
$data = AmoHook::build($raw)->get();

// Использование с Laravel Request
$content = $request->all();
$data = AmoHook::build($content)->get();

Вы можете изучить тесты (tests) для изучения работы класса

Обработка ошибок и отладка

По умолчанию класс скрывает все происходящие внутри обработчиков ошибки т.к. amoCRM отключает WebHooks если количество ошибок за короткий промежуток времени превысит определенный порог. Поэтому для отслеживания ошибок и отладки настоятельно рекомендуется добавить хотя бы один логгирующий обработчик onError. Альтернативно, можно заставить библиотеку принудительно выводить ошибки, вызвав setErrorThrowing(true) перед handle()

Отслеживание времени работы обработчика

При работе amoCRM ожидает ответ от сервера в течение не более чем 2 секунд. Длительный ответ с точки зрения amoCRM эквивалентен ошибочному коду возврата, что также ведет к отключению хука. Для замера времени можно использовать следующую конструкцию:

$time = -microtime(true);
// Логика обработки хуков
// AmoHook::build(...)->...->handle();
$time += microtime(true);
if ($time >= 1.5) {
    Log::warning("Обработка хука заняла более 1.5 секунд! ".$time);
}
// return ответ с кодом 200

Примечание: этот способ измерения не совсем точный т.к. не учитывает реальное время начала обработки запроса, см ссылку

Доступные сущности и события

Все сущности и события именуются согласно их названию в Webhooks AmoCRM (leads, contacts и update, add и т.д.). Стоит отметить, что библиотека корректно различает контакты и компании: contacts и companies соответственно. Дополнительно можно использовать any для определения сущностей и событий для методов обратного вызова.
Для упрощения работы все наименования сущностей и событий были вынесены

Внесение вклада

Я с удовольствием приму ваши комментарии, предложения и доработки в Issues или Pull requests :)

About

Makes your AmoCRM Webhooks looks pretty

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages