В связи с тем, что мы научили Битрикс24 отправлять SMS не только из бизнес-процессов и роботов CRM, но заодно из карточки CRM (которая доступна везде, включая бесплатный тариф без бизнес-процессов), мы добавили соответствующий специальный REST для «служб сообщений». В первую очередь это сделано для интеграции с SMS, но вообще это универсальный механизм и в дальнейшем мы видим тут возможность отправки сообщений в произвольные источники.
Мы рекомендуем авторам интеграций с SMS-провайдерами перевести свои приложения на новый REST, чтобы у пользователей не было проблем с установкой на бесплатном тарифе. И вообще, несмотря на то, что мы стараемся прозрачно «пробрасывать» вызовы существующих провайдеров для бизнес-процессов и роботов CRM, лучше избавиться от этой прослойки и работать с нужными методами REST. Тем более, что только эти новые методы позволят вам не только отправлять SMS, но и сообщать Битрикс24 о статусе отправленных сообщений, чтобы этот статус пользователи видели прямо в карточке CRM (а в дальнейшем, и в отчетах инструментов CRM-маркетинга).
В этом материале я хочу рассказать и показать на
[spoiler]
Хочу сделать тиражное решения для Битрикс24!
Начать надо с того, чтобы стать технологическим партнером Битрикс24. Идем по
После заполнения анкеты вы сразу получите доступ в партнерский кабинет
Теперь можно добавить свое еще пока не существующее в техническом плане решение в кабинет. Поможет нам кнопка «Добавить приложение». В открывшейся форме надо будет заполнить описания (по крайней мере на русском языке) – на текущем этапе это может быть любой текст, главное просто заполнить обязательные поля. Не забудьте поставить галочку «Я ознакомился с правилами публикации приложений», а заодно и действительно почитать правила публикации – в дальнейшем, когда вы подадите свое решение на модерацию перед публикацией в каталоге, вам нужно знать, что оформление и функционал соответствуют нашим регламентам. Жмем кнопку «Сохранить»
Карточка приложения заполнена, но этого мало, потому что это просто описания. Теперь нам нужно перейти к технической стороне вопроса.
У каждого тиражного приложения для Битрикс24 есть версии, которые, собственно, уже и реализуют тот или иной нужный нам функционал. Именно функционал новых версий в конечном итоге будут проверять модераторы, поэтому если версия еще не полностью работоспособна, нет смысла подавать решение на модерацию.
Прежде, чем заполнять форму новой версии, обратимся к
Итак, нажмем на кнопку «Добавить новую версию». В открывшейся форме нам надо указать URL приложения. В нашем примере это будет
Далее, указываем, что нашему приложению нужен доступ к модулю «Сервис сообщений»
Больше нам ничего не нужно – Битрикс24 будет сам вызывать наш провайдер из нужных точек в интерфейсе: из бизнес-процессов, из роботов CRM, из карточки CRM, а в дальнейшем из прочих нужных и полезных, не побоимся этого слова, мест!
Остается только указать номер версии и указать что-нибудь в описании версии (еще раз напомню, что когда дело дойдет до подачи на модерацию, здесь нужно будет вводить реальный осмысленный текст с описанием функционала версии).
Галочку «Отправить на модерацию» сейчас не включаем! Нам еще нечего показать модераторам. Сохраняем версию. Пора переходить к глубокой магии!
Общая логика приложения
Для начала поймем, как нам вообще обустроить нашу интеграцию. В целом, процесс описывается просто – наше приложение регистрирует в конкретном Битрикс24 некий обработчик. Когда пользователь (или автоматический процесс) на стороне Битрикс24 хочет отправить SMS, он дергает этот обработчик и передает в него текст и номер телефона получателя. Наш обработчик (зная параметры вызова API SMS-оператора) отправляет SMS. Вот такая простая схема. Итак,
В нашем примере, скрипт install.php запросит у пользователя параметры для подключения API SMS-оператора и должен их где-то на своей стороне сохранить в привязке к конкретному Битрикс24. В таблице БД, например. Этот же скрипт должен зарегистрировать так называемый «провайдер сообщений» в Битрикс24, обращаясь к соответствующему методу REST. Фактически, это и будет регистрацией нашего обработчика, который реализуется в примере в файле handler.php по адресу
Дальше приложение ничего не делает. Лежит наш handler.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
Обработчик, получив данные о сообщении, должен, с одной стороны, обратиться к API SMS провайдера, чтобы отправить сообщение, а с другой стороны, запомнить 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-провайдера (для этого вам, вероятнее всего, придется в очереди запоминать как ID-сообщения, который присылает Битрикс24, так и соответствующий ему ID-сообщения на стороне SMS-оператора – вот какой ужас!), получать от него статус доставки и передавать его обратно в Битрикс24. Посмотрим на код:
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 пользователя, который отправляет 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); |
Эта функция тоже дергает 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. Если все прошло успешно, то нужно сохранить на стороне приложения новые токены (для этого в примере сделана заготовка в виде вызова некой функции saveParams($auth)), а затем уже с новым актуальным access_token мы снова делаем попытку вызова messageservice.message.status.update.
Вот, собственно, и вся магия. Берите