SLINKOV•Design
Поддержка и развитие Вашего сайта
ДМИТРИЙ СЛИНЬКОВ

Кастомизация Bitrix24 с помощью вебхуков

Битрикс24 — это мощная система, содержащая множество инструментов, таких как CRM, управление задачами и проектами, диск и календарь компании, бизнес-процессы, конструктор сайтов, автоматизация маркетинга и т.д. Но что делать, если этих функций недостаточно? Вебхуки могут дать вашему Битрикс24 буквально неограниченные возможности. Давайте посмотрим насколько легко вы сможете сделать такой вебхук для себя сами!

Что такое API вообще?!

Возможно вы слышали от консультантов по Bitrix24 такую фразу: "В Битриксе нету такой функции. Но мы сделаем вам вебхук!"

Вебхук для многих стал спасительной панацеей и губительным чортом в одном флаконе. Тем не менее, как я и говорил вам на русском языке в ютуб-канале «Прожарка инноваций», равно как и на английском языке в канале SLINKOV Design, не так страшен чорт, как его малюют.
С помощью вебхуков вы буквально можете делать следующее:
  1. Добавлять, изменять, удалять, импортировать, копировать или дублировать лиды, задачи, заказы, компании, контакты, инвойсы, элементы кастомных списков, статусы и стадии сделок.
  2. Добавлять, из менять, удалять кастомные поля, файлы, события в календаре.
  3. Создавать и изменять бизнес-процессы.
YouTube channel: SLINKOV Design
Dmitriy Slinkov: Bitrix24 – Customer revenue on the fly
Пример простой задачи выполнимой с помощью вебхука
Однажды один из моих клиентов спросил меня, можно ли трансформировать продукты из заказов в задания. Это заняло всего пару часов. Вебхук просто копирует все товарные позиции в задачи. Это имеет смысл, когда вы продаете услуги, которые должны стать задачами после принятия предложения.
Как это сделать, я расскажу в отдельном видео. Чтобы не пропустить его, пожалуйста, подпишитесь на мой канал YouTube «SLINKOV Design».
Давайте договоримся прямо на берегу этого поста:
1️⃣ Вебхуки — это просто скрипты, запускаемые с любого хостинга, которому вы доверяете и который полностью контролируете
2️⃣ Хостинг — это место, где вы обычно «держите» свои вебсайты (за исключением тех случаев, когда вы пользуетесь конструктором сайтов)
3️⃣ Вебхук — это не более чем веб-страница, которую ваш Битрикс24 запускает с помощью... (сюрприз!) адреса URL! Единственное отличие от вебхука от веб-старницы: первый уходит в глубокой программирование сразу, без особых HTML-прелюдий.
4️⃣ Всё, что я расскажу вам сегодня, вполне применимо к любой ИТ-системе!

Когда Стив Джобс показал миру первый iPhone, главным его открытием был не стеклянный сенсорный экран. Айфон открыл эру приложений. Сегодня у нас есть приложения практически для всего. Но! Когда у вас есть огромная вселенная приложений, вы упускаете возможность интегрировать их.
Представьте себе: приложение Angry Birds отправляет информацию о ваших достижениях в банк. Приложение банка оценивает вашу игровую продуктивность и предоставляет вам лучшие условия кредитования. Потому что вы ловкий геймер? Или потому, что вы настолько стабильны в этом мире, что у вас достаточно времени, чтобы играть в мобильные игры...
Смешно или нет, но сегодня мы видим еще один глобальный этап развития программного обеспечения — наступает эа API!

Возьмем к примеру CRM-системы. Все они с гордостью говорят: "Мы простые софтинки". И такая уловка делает свое дело: люди покупают, по-сути, мертвые системы. Но! Как только вы получаете доступ к приложению, вам сразу хочется его приспособить под себя. Подумайте об этом, когда в следующий раз вам придется выбирать CRM для своего бизнеса.
Если система предлагает API, это знак того, что вы всегда можете сделать ее лучше, кастомизировать и интегрировать такое приложение в вашу экосистему. Оно будет работать с другими вашими приложениями!
Используя API, можно интегрировать CRM с бухгалтерской системой, с системой обработки заказов и даже… с системами ваших деловых партнеров!

Термины, которые полезно знать

Что ж, как только вы решились вступить в эру API, с высокой вероятностью вы начнете натыкаться на следующие термины:
Но самое важное, что вам нужно знать сегодня — это JavaScript Object Notation file. JSON. JSON - это универсальный формат данных с минимальным количеством типов значений: строки, числа, булевые переменные, списки, объекты и null. Хотя такая нотация и является подмножеством JavaScript, такие типы данных представлены во всех распространенных языках программирования. И это делает JSON хорошим кандидатом для передачи данных через языковые барьеры.

Типичный JSON может выглядеть вот так:
JavaScript Object Notation file (JSON)
Если вы бегло пробежитесь по его тексту, то сразу обнаружите его читабельность. Посмотрите — это же просто Интернет-заказ! Не видите?
Окей, у меня для вас хорошая новость: вам не нужно писать такой файл самостоятельно!
Задача намного-намного проще.
Но давайте же перейдем от теории к практике?!

Погружение в Bitrix24 и JSON

Позвольте показать вам несколько слайдов моей презентации, в которой я описываю как Битрикс24, вебхук и JSON работают вместе аки команда Формулы-1.
Вот тут (картинка над этим абзацем) представлены участники: Bitrix24, Интернет и вебхук.
В Битрикс24 есть специальная форма, где мы указываем специальный входящий (inbound) вебхук. Вы можете найти его по следующему пути: Developer resources \ Other \ Inbound webhook.

Здесь и далее интерфейс Битрикс24 представлен на английском языке. Просто мне так удбнее. Надеюсь и вы быстро разберетесь))
Скопируйте этот URL и вставьте его в скрипт своего вебхука. Вот ровно так, как представлено на слайде ниже:
В скрипте вебхука вы вводите этот URL ручками. Он будет использоваться для отправки на него вашего JSON-файла. Цифра после '/rest/' — ID пользователя. Всё это означает, что ваш вебхук, словно живое существо, будет работать только от имени конкретного юзерского профиля. Я рекомендую вам использовать в таких случаях ID вашего супер-админа.
Снова смотрим в форму и в поле "permissions" выбираем CRM, Task или другие модули, которым вы доверяете работу с вебхуком.

А теперь слайд о том, как будут коммуницировать друг с другом ваш вебхук и Bitrix24:
Представьте, что вебхуку нужно узнать среднюю температуру в Париже, а у вашего же Битрикс24 такая информация есть.
Вебхук отправит JSON-файл, содержащий [{"city": "Paris", "units": "C"}] в Битрикс24, используя секретный URL, который мы описали выше. И немедленно получит ответ, подобный этому: [{ "low": "16", "high": "23"}].
Круто?
Мы рассмотрели ситуацию, когда инициатива на стороне вебхука. Вы захотели узнать температуру — вы спрашиваете об этом в любое удобное для вас время. Но как насчет того, чтобы получать оповещение ровно в тот момент, когда температура изменилась? Или поднялась выше «максимума». Для таких ситуаций в Битрикс24 есть еще одна форма прямо рядом с формой Inbound webhook.
Вы можете найти ее по следующему пути: Ресурсы разработчика \ Другое \ Исходящий webhook (Developer resources \ Other \ Outbound webhook).
В фроме очень похожей на ту, что ниже, прописываем URL вашего вебхука.
Следующая по важности штука тут — это поле "Events" (событие). Например, в одном из своих видео, я рассказывал вам про вычисление Customer Revenue. Вебхук, который это делает, очень удобно вызывать через событие "Invoice Status Updated".

Это не единственное место, где вы можете указать событие вызывающее вебхук.

Есть еще:
  1. Automation rules в CRM
  2. Automation rules в Задачах и Проектах
  3. Этапы процессов.
Во всех этих местах вы можете указывать не только сам вебхук, но и некоторые параметры к нему!

Пример: вы хотите проверять какой тип Email-адреса вам оставляют лиды. Рабочий или личный. Вы успешно написали для этого правильный скрипт и поместили его URL в Automation rules стадии пайплайна «Вернувшиеся на сайт». Чтобы вызвать вебхук, вы можете добавить к его URL-у Email-адрес. Прямо как тут:
Не трудно заметить, что 'email' и 'responsible' это переменные, которые можно таким образом легко передать «внутрь» скрипта для дальнейшего использования.

Чтобы завершить картину, посмотрим на последний слайд моей презентации:
Событие порождает вызов вебхука.
Вебхук отправляет JSON-запрос и получает в обратку JSON-ответ.
Вуаля ;)

Что дальше?

Выберите себе язык программирования. Я вот, недолго думая, выбрал PHP. Чтобы писать скрипты для своих вебхуков, я использую приложение Visual Studio app. Кстати, все необходимые линки на приложения, скрипты и проч. я поместил в описании к этому видео.

Чтобы не писать JSON самому, я нашел неплохую библиотеку. Теперь я могу запросто использовать простую семантику типа «добавить», «изменить», «удалить», чтобы оперировать данными Битрикс24. Тестовый скрипт и библиотеку вы найдете там же — под видео.

Ну что, срипт готов, да? Теперь его нужно где-нибудь захостить.
Очевидно, что если вы пишете свой код на PHP, вам понадобится хостер, который может предоставить вам сервер с интерпретатором PHP.
Единственное предостережение из моего опыта: не используйте бесплатный хостинг. Бесплатный значит бесплатный — вы никогда не знаете, сколько вам придется ждать, пока веб-хук действительно начнет действовать.
Что еще? Найдите себе любимый FTP-клиент и используйте его для задач:
1. Перенос вебхуков на сервер.
2. Скачивание логов с сервера.

Что вебхуки могут и чего не могут

Если интересно, посмотрите на мой англоязычный YouTube-канал. Там, время от времени, я помещаю рассказы о кастомизациях Битрикс24.
Вебхук помогает мне и моей команде интегрировать Bitrix24 с Prestashop, SAP SuccessFactors, Shopify, Microsoft Dynamics AX... но этот список бесконечен!

Посморите список того, что я лично сделал для своих клиентов всего за один месяц с помощью вебхуков:
  • Автоматизация обработки лидов: прогрев «холодных» лидов с помощью сложного бизнес-процесса.
  • Интеграция Bitrix24 с таблицами Google Sheets и с Google Data Studio.
  • Создание различных дэшбордов для мультивалютного анализа продаж.
  • Трансформация продуктов в задачи.
  • Автоматическое создание проектов/групп при переходе Сделки в определенную стадию.
  • Закрытие проектов с автоматической генерацией процедур, оповещениями клиентов и выставлением счета.
  • Онбординг лидов.
  • Система спорадических и периодических выставлений счетов, трансляция задач в сделки и инвойсы.

И теперь самое интересное про данный список: за два (!) месяца до написания данной статьи у меня не было абсолютно никакого опыта ни с PHP, ни с хостингами, FTP и проч. Как так получилось? Один разработчик-фрилансер сделал для меня часть заказа (один вебхук из семи необходимых) и… исчез. Чтобы выполнить взятые на себя обязательства перед клиентом, мне пришлось делать всё самому. Всё это не означает, что я типа мега-крут. Смысл в другом: вы тоже можете сделать нечто похожее своими руками!

Что вебхуки не могут делать:
  1. Изменять интерфейс (нельзя сделать новую форму, например)
  2. Что-либо «за пределами API (например, вы не можете получить доступ к комментариям в Сделках просто потому, что этих комментариев нет в API Битрикс24)
  3. Готовить кофе или чай!

Краткий обзор вышесказанного

Итак, на пути к собственному первому вебхуку у вас есть всего шесть препятствий:

  1. Найти хостинг
  2. Решить какие события будут вызывать ваш вебхук
  3. Найти библиотеку
  4. Написать скрипт
  5. Использовать FTP-клиент.
[точка!]

Полезные дополнения

Video "How to import companies, contacts, and deals into Bitrix24"

Post "Bitrix24: conversion of Products to Tasks webhook"

Исходник вебхука "The PHP script calculates payments from the customer whose invoice just has been paid | Bitrix24". То была ссылка на GitHub, ну а сам код, на всякий случай, есть еще и тут:

<?php

    ini_set("log_errors", 1);
    ini_set("error_log", "./php-error.log");

    writeToLog($_REQUEST, 'incoming'); //comment it when everything will be debugged
    // 
    // This webhook should be called by Bitrix24 event '
    // Go to Your portal \ Developer resources \ Other \ Outbound webhook
    // or like it shown on the following screenshot: https://cloud.mail.ru/public/EmPS/BNuEV3s3p
    // 
    //=== CONSTANTS zone
    //
    define("UFRAS", "UF_CRM_XXXXXXXXX"); // The system name of custome field

    //=== VALIDATION & INITIALIZATION zone
    //Validates Webhook params and fill variables by Webhook params
    
    require __DIR__ . '/vendor/autoload.php';
    
    use \App\Bitrix24\Bitrix24API; // The library https://github.com/andrey-tech/bitrix24-api-php
    
    $webhookURL = 'https://[yourURLfromBitrix24]/';
    
    $bx24 = new Bitrix24API($webhookURL);
    
    $InvoiceID = $_REQUEST['data']['FIELDS']['ID'];
    
    //=== WORKING zone
    
    $InvoiceFields = $bx24->getInvoice($InvoiceID); //Get Invoice fields. 
    
    //If the Invoicee not just paid, then exit from the Webhook
    if ($InvoiceFields['PAYED'] != 'Y') {
        file_put_contents(getcwd() . '/hook.log', "\nInvvoice " . $InvoiceFields['ID'] . " is not paid \n", FILE_APPEND);
        exit;
    }
    
    if (!$Company) exit; //If no Company in Invoicee, exit.
    
    $Company = $InvoiceFields['UF_COMPANY_ID'];
    if (!$Company) exit; //If no Contact in Invoicee, exit.
    
    $CompanyFields = $bx24->getCompany($Company);
    
    //Which year is today?
    $CurrentYear = date("Y");
    $HappyThisYearString = $CurrentYear . '-01-01';
    $HappyThisYearTime = strtotime($HappyThisYearString);
    
    //=== WORKING ZONE
    
    //Summarize only this company's Invoice Amounts
    //First, let's get filtered invoices into an array
    $getInvoiceListGeneratorObject = $bx24->getInvoiceList(['ID' => 'ASC'],
    ['UF_COMPANY_ID' => $Company, 'PAYED' => 'Y'],
    ['ID', 'PRICE', 'DATE_PAYED', 'UF_DEAL_ID'],);
    //Invoice amounts into Array
    $InvoiceArray = array();
    foreach ($getInvoiceListGeneratorObject as $value) {
        $InvoiceArray = array_merge($InvoiceArray, $value);
    }
    
    //Summarize Invoice Amounts
    $m = count($InvoiceArray);
    if ($m == 0) {
        file_put_contents(getcwd() . '/hook.log', "\$no payments from this customer at all\n", FILE_APPEND);
        exit(json_encode(array('error' => 'no payments from this customer at all' )));
    }
    $RevenueCurrentYear = 0;
    for ($i = 0; $i < $m; $i++) {
        $t = strtotime($InvoiceArray[$i]['DATE_PAYED']);
        // file_put_contents(getcwd() . '/hook.log', "\n\$t = " . $t, FILE_APPEND);
        if ($t >= $HappyThisYearTime) {
            $RevenueCurrentYear += $InvoiceArray[$i]['PRICE'];
        }
    }
    if ($RevenueCurrentYear == 0) {
        file_put_contents(getcwd() . '/hook.log', "\n\$no payments from this customer this year\n", FILE_APPEND);
        exit(json_encode(array('error' => 'no payments from this customer this year' )));
    }
    
    $CompanyFields = $bx24->getCompany($Company);
    
    $bx24->updateCompany($Company, [UFRAS => $RevenueCurrentYear], ["REGISTER_SONET_EVENT" => "Y"]);
    
    //=== FUNCTIONS zone
    function writeToLog($data, $title = '') {
            $log = "\n------ max2SumInvoices.php ------------------\n";
            $log .= date("Y.m.d G:i:s") . "\n";
            // $log .= (strlen($title) > 0 ? $title : 'DEBUG') . "\n";
            // $log .= print_r($data, 1);
            file_put_contents(getcwd() . '/hook.log', $log, FILE_APPEND);
            return true;
    }