14  /  36

REST для SMS

Просмотров: 6090 (Статистика ведётся с 06.02.2017)

Универсальный механизм отправки сообщений

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

Авторам интеграций с SMS-провайдерами рекомендуется перевести свои приложения на новый REST, чтобы у пользователей не было проблем с установкой на бесплатном тарифе. И, несмотря на прозрачность вызовов существующих провайдеров для бизнес-процессов и роботов CRM, лучше работать с методами REST для службы сообщений. Тем более, что только эти методы позволят не только отправлять SMS, но и сообщать Битрикс24 о статусе отправленных сообщений. Этот статус пользователи видят прямо в карточке CRM (а в будущем увидят и в отчетах инструментов CRM-маркетинга).

Рассмотрим практический пример того, как можно быстро сделать интеграцию с SMS-провайдером.

Скачать архив примера:


Для начала

Станьте технологическим партнером 1С-Битрикс. Для этого достаточно заполнить анкету: указать общую информацию, а также данные для дальнейшей авторизации в партнерском кабинете.

Обратите внимание на поле Код партнера - это префикс, который будет подставляться в дальнейшем в символьный код, идентифицирующий ваши решения в нашем каталоге. Если взять в качестве примера решение по интеграции со Stripe (https://www.bitrix24.ru/apps/?app=integrations24ru.stripe), то integrations24ru является как раз этим кодом партнера (разработчика решения), а код stripe является кодом конкретного решения, который вы укажите в дальнейшем при заполнении формы регистрации решения.

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

После заполнения анкеты вы сразу получите доступ в партнерский кабинет [link=]https://partners.1c-bitrix.ru/personal/[/link]. Для создания решения, которое в дальнейшем может быть опубликовано в каталоге Приложения24 необходимо в партнерском кабинете перейти по цепочке Кабинет партнера > Приложения24 для Битрикс24 > Добавить приложение. В открывшейся форме необходимо заполнить 5 обязательных полей.

Описание обязательных полей (Нажмите на плюсик)

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

Версии приложения

В отличие от локальных приложений, тиражные решения состоят из версий. Каждая версия в дальнейшем подается на модерацию. (При модерации версии проверяется и карточка приложения). На этапе разработки и тестирования модерация не нужна, вы сами занимаетесь разработкой и доведением своего решения до полнофункционального состояния, включая тестовые установки на своих Битрикс24, и только потом подаете решение на модерацию.

Добавим первую версию приложения. Перейдите на закладку Версии и нажмите Добавить новую версию. В открывшейся форме заполните базовые поля, укажите необходимые для приложения права (для нашего примера нужны права на управление пользователями), а также URL текущего примера, размещенного на вашем сервере:

Нажмите на рисунок, чтобы увеличить

Про URL приложения

В поле Права укажите, что приложению нужен доступ к модулю Сервис сообщений . Битрикс24 в этом случае будет сам вызывать наш провайдер из нужных точек в интерфейсе: из бизнес-процессов, из роботов CRM, из карточки CRM и так далее.

Остается только указать номер версии и указать что-нибудь в описании версии. (Когда дело дойдет до подачи на модерацию, здесь нужно будет вводить реальный осмысленный текст с описанием функционала версии). Галочку Отправить на модерацию сейчас не включайте. Сохраните версию.


Общая логика приложения

Приложение регистрирует в конкретном Битрикс24 некий обработчик. Когда пользователь (или автоматический процесс) на стороне Битрикс24 хочет отправить SMS, он дергает этот обработчик и передает в него текст и номер телефона получателя. Обработчик (зная параметры вызова API SMS-оператора) отправляет SMS. Вот такая простая схема:

В нашем примере, скрипт install.php запросит у пользователя параметры для подключения API SMS-оператора и сохраняет их на своей стороне в привязке к конкретному Битрикс24. В таблице БД, например. Этот же скрипт регистрирует так называемый "провайдер сообщений" в Битрикс24, обращаясь к соответствующему методу REST. Фактически, это и будет регистрацией обработчика, который реализуется в примере в файле handler.php по адресу https://mydomain.ru/sms/handler.php. Если регистрация прошла успешно, install.php должен завершить установку.

В дальнейшем приложение ожидает, когда Битрикс24 обратиться к нему:

Обращение произойдет, если пользователь, допустим, решит отправить SMS из карточки CRM. В этом случае, handler.php получит целую кучу данных в массиве $_REQUEST:

requestArray
(
    [module_id] => crm
    [bindings] => Array
        (
            [0] => Array
                (
                    [OWNER_TYPE_ID] => 1
                    [OWNER_ID] => 5783
                )

        )

    [properties] => Array
        (
            [phone_number] => +9172012345
            [message_text] => тест
        )

    [type] => SMS
    [code] => fastsms
    [message_id] => e35864edce3eaad987d32f8955c1177b
    [message_to] => +9172012345
    [message_body] => тест
    [ts] => 1513177809
    [auth] => Array
        (
            [access_token] => x4o81wfl4g57qur2u8sjrlcha76zn0tj
            [expires_in] => 3600
            [scope] => messageservice
            [domain] => restapi.bitrix24.ru
            [server_endpoint] => https://oauth.bitrix.info/rest/
            [status] => F
            [client_endpoint] => https://restapi.bitrix24.ru/rest/
            [member_id] => da45a03b265edd8787f8a258d793cc5d
            [user_id] => 1
            [application_token] => 127acc1c34feccc4da8fbf5020856f12
        )

)

Нас интересует:

  • адресат message_to,
  • текст сообщения message_body,
  • внутренний идентификатор сообщения message_id, который потребуется для того, чтобы в дальнейшем отдельно сообщать в Битрикс24 о статусе доставки,
  • параметры авторизации в массиве auth для работы с REST Битрикс24.

Обработчик, получив данные о сообщении, должен:

  1. обратиться к API SMS провайдера, чтобы отправить сообщение,
  2. запомнить id-сообщения и привязку к конкретному Битрикс24 где-то у себя в некой очереди.

Можно и не запоминать, но тогда приложение не сможет во всей полноте реализовать хорошие пользовательские сценарии. Так как статус доставки SMS-сообщения становится известным только через некоторое время (иногда это могут быть часы), мы не сможем прямо из handler.php тут же сообщить в Битрикс24 о результате доставки. Приложению придется делать это отдельно, и для этого в архиве примера есть файл statuses.php. Подразумевается, что какой-то менеджер заданий обращается к этому файлу с некой периодичностью и этот скрипт «смотрит» на очередь отправленных SMS и по каждому из них пытается узнать статус доставки, обращаясь к API SMS-провайдера:

О результатах он сообщает в Битрикс24, и удаляет из очереди обработанные сообщения.


Установка приложения без публикации

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

При установке в интерфейсе Битрикс24 будет вызван install.php, который выведет интерфейс для ввода некого ключа API. В зависимости от конкретного SMS-провайдера параметры авторизации будут отличаться, так что в своем приложении интерфейс вам нужно будет подзаточить под конкретный случай.

Нажмите на рисунок, чтобы увеличить

Нажмите “Сохранить”, приложение будет считаться установленным (о техническом завершении - ниже), и Битрикс24 автоматически откроет уже основной интерфейс приложения app.php. В архиве примера этот интерфейс не сильно отличается от интерфейса установки и должен «подхватывать» сохраненные параметры авторизации SMS-провайдера. Но, поскольку это просто «заготовка» для приложения, а не работающая интеграция с конкретным провайдером, то мы увидим просто форму для ввода ключа.


Волшебный код

Начнем с install.php. Когда Битрикс24 показывает во фрейме скрипт приложения (это касается как скрипта установки, так и основного скрипта приложения), то он передает в массив $_REQUEST все необходимые для OAuth 2.0 параметры авторизации. Следовательно, мы их можем схватить и сохранить на стороне приложения для дальнейшего использования. Именно это и происходит в коде при формировании hidden-полей:

<fo rm id="sms-settings">
    <input type="hidden" name="save" value="Y">
    <input type="hidden" name="access_token" value="<?=$_REQUEST['AUTH_ID'];?>">
    <input type="hidden" name="refresh_token" value="<?=$_REQUEST['REFRESH_ID'];?>">
    <input type="hidden" name="domain" value="<?=$_REQUEST['DOMAIN'];?>">
    <input type="hidden" name="member_id" value="<?=$_REQUEST['member_id'];?>">
    <div class="form-group">
        <label for="sms_token">Укажите API-ключ для интеграции с FastSMS</label>
        <input type="text" class="form-control" name="sms_token" id="sms_token" placeholder="FastSMS API token">
    </div>
    <button type="submit" class="btn btn-primary btn-lg btn-save">Сохранить</button>
</form>

Далее, мы делаем обработчик onsubmit, который позволит перехватить нажатие на кнопку "Сохранить".

$('#sms-settings').submit(function(e){

    e.preventDefault();
    // 1. сохраняем данные авторизации на стороне приложения, чтобы в
    // дальнейшем использовать их для отправки смс


    // 2. прописываем обработчик для провайдера
    var params = {
        CODE: 'fastsms',
        TYPE: 'SMS',
        HANDLER: 'https://mydomain.ru/sms/handler.php',
        NAME: 'Провайдер FastSMS.ru',
        DESCRIPTION: 'Провайдер FastSMS.ru'
    };

    BX24.callMethod(
        'messageservice.sender.add',
        params,
        function(result)
        {
            if(result.error())
                alert("Error: " + result.error());
            else {
                // Обработчик для провайдера прописан успешно

                // 3. заканчиваем процедуру установки на стороне Битрикс24
                BX24.installFinish();
            }
        }
    );
});

В этом обработчике можно прописать свой механизм сохранения нужных параметров. А далеезарегистрируйте тот самый обработчик, обращаясь для этого к методу messageservice.sender.add. Если регистрация прошла успешно, мы вызываем метод installFinish, который сообщает Битрикс24 об успешном завершении установки.

Обратите внимание, что мы в данном случае обращаемся к REST Битрикс24 из JavaScript как для добавления провайдера сообщений, так и для завершения процедуры установки. Со статусами сообщений мы в дальнейшем будем работать, обращаясь к REST API из PHP.

В app.php все то же самое, та же форма настроек, та же обработка события onsumbit, в которой вам придется писать свой код сохранения настроек и параметров авторизации. Но тут уже нет никакого installFinish, потому что приложение уже установлено:

$('#sms-settings').submit(function(e){

    e.preventDefault();
    // сохраняем данные авторизации на стороне приложения, чтобы в
    // дальнейшем использовать их для отправки смс


});

Код в handler.php. В примере просто сохраняется то, что нам передает Битрикс24 в лог:

writeToLog($_REQUEST, 'request');
print_r($_REQUEST); 

Но вы можете здесь обращаться к API провайдера SMS, инициируя отправку SMS теми средствами, которые вам предоставит оператор. Пример содержимого массива $_REQUEST есть выше.

Самое сложое находится в файле statuses.php. Подразумевается, что этот файл будет вызываться с некой периодичностью и он должен уметь обращаться к некой очереди, которую вы должны сделать самостоятельно. И получая из этой очереди информацию об отправленных SMS-сообщениях, он должен дергать API SMS-провайдера, получать от него статус доставки и передавать его обратно в Битрикс24. Для этого придется в очереди запоминать как ID-сообщения, который присылает Битрикс24, так и соответствующий ему ID-сообщения на стороне SMS-оператора. Посмотрим на код:

include ('rest.php');

// скрипт, который работает с заданной периодичностью, проверяет статусы отправленных
// сообщений и передает эту информацию в Битрикс24

// 1. логика обработки одного сообщения из очереди

// откуда из базы получаем идентификатор оотправленного сообщения - это id, который
// нам передал Битрикс24 в обработчик handler.php
$bx24_message_id = 'e35864edce3eaad987d32f8955c1177b';

// находим запись о соответствующем Битрикс24 в сохраненных данных
// для аутентификации по OAuth 2.0, которые мы сохраняли в install.php или app.php
$bx24_domain = 'restapi.bitrix24.ru';
$bx24_access_token = 'x4o81wfl4g57qur2u8sjrlcha76zn0tj';
$bx24_refresh_token = 'g06ete91nmfa14ew5s2gt432l4in6q6h';

// берем через API провайдера информацию о статусе сообщения и выбираем соответствующий
// ему статус в Битрикс24: delivered, undelivered, failed
$status = 'delivered';

// 2. сообщаем Битрикс24 о статусе сообщения
$result = restCommand ('messageservice.message.status.update',
   array(
      'CODE' => 'fastsms',
      'message_id' => $bx24_message_id,
      'status' => $status
   ),
   array(
      'access_token' => $bx24_access_token,
      'refresh_token' => $bx24_refresh_token,
      'domain' => $bx24_domain
   ),
   true
);

echo "<pre>"; print_r($result); echo "</pre>";

if (isset($result['error'])) {
   // что-то пошло не так, анализируем ошибку и реагируем на нее
}

Представим, что на каждом шаге цикла обработки очереди мы получили из очереди $bx24_message_id, потом вытащили оттуда же название домена Битрикс24 $bx24_domain и токены $bx24_access_token и $bx24_refresh_token. Домен и access_token нам нужны, чтобы обратиться к REST Битрикс24. Это простой HTTP-запрос, в котором указывается домен Битрикс, название нужного метода (в нашем случае это метод messageservice.message.status.update для обновления статуса доставки), параметры метода и токен авторизации access_token.

А вот с токеном авторизации могут возникнуть сложности. Дело в том, что access_token живет только 60 минут. Поскольку SMS-сообщения нам могут прийти в любой момент, в том числе и раз в неделю, то может оказаться, что сохраненный нами access_token уже устарел.

Если быть точным, то в обработчик передается совершенно новый access_token пользователя, который отправляет SMS из интерфейса Битрикс24. Но если говорить про очередь обработки статуса сообщения, то он все равно может успеть перестать быть валидным к моменту, как мы до соответствующего сообщения доберемся. Поэтому на стороне приложения хранится refresh_token – он актуален целый месяц, и он позволяет в любой момент в течение этого периода запрашивать новый access_token без участия пользователя. Заодно при этом обновляя и сам refresh_token. Напишите скрипт, который будет ежедневно пробегаться по сохраненным refresh_token, брать те из них, которые получены 29 дней назад, и запрашивать для них обновление вместе с access_token.

Как можно обращаться к REST, одновременно обновляя токены при необходимости? Используйте этот же механизм просто для обновления refresh_token. У нас есть файл rest.php. Начинается он с двух констант: CLIENT_ID и CLIENT_SECRET. Значения для этих констант Такая пара ключей действует на всех Битрикс24, на которых потом будет устанавливаться ваше приложение. вам нужно взять из карточки приложения:

Используйте функцию restCommand. Она получает название нужного метода REST, параметры для этого метода, массив с данными аутентификации (токены авторизации и домен Битрикс24), а также ключ $authRefresh.

Дальше формируется http-запрос:

$queryUrl = "https://".$auth["domain"]."/rest/".$method;
$queryData = http_build_query(array_merge($params, array("auth" => $auth["access_token"])));

и обращаемся к нему при помощи функций по работе с curl:

$result = curl_exec($curl);

Если наш access_token в этот момент уже невалидный, то в этом случае обращение к REST вернет нам ошибку. Ошибка обрабатывается и если параметр authRefresh задан в true (в архиве примера он именно такой), то тут же прозрачно обновляются токены, обращаясь к функции restAuth. Эта функция тоже обращается к REST, но не просто REST Битрикс24, а к методам непосредственно сервера аутентификации OAuth 2.0.

$queryUrl = 'https://oauth.bitrix.info/oauth/token/';
$queryData = http_build_query($queryParams = array(
   'grant_type' => 'refresh_token',
   'client_id' => CLIENT_ID,
   'client_secret' => CLIENT_SECRET,
   'refresh_token' => $auth['refresh_token']
));

При этом сервер использует те же самые константы CLIENT_ID и CLIENT_SECRET. Если все прошло успешно, то нужно сохранить на стороне приложения новые токены, а затем уже, с новым актуальным access_token, снова вызвать messageservice.message.status.update. Для сохранения токенов в примере сделана заготовка в виде вызова некой функции saveParams($auth).

Используйте стандартную заготовку в виде архива примера, адаптируйте к реальному оператору SMS и публикуйте решения в каталоге Приложения24.


6
Курсы разработаны в компании «1С-Битрикс»

Если вы нашли неточность в тексте, непонятное объяснение, пожалуйста, сообщите нам об этом в комментариях.
Развернуть комментарии