Настройка REST роботов (действий) через приложение (встройку)
Описание
С версии 20.0.600 модуля Бизнес-процессы появилась возможность настраивать робота/действие, используя интерфейс приложения. Реализована стандартным механизмом встройки rest.placement.
Реализация на примере приложения
Рассмотрим реализацию на конкретном примере приложения (полный код приложения представлен в следующем табе страницы).
В нашем примере приложение добавляет робота, у которого есть 2 параметра типа Строка:
var params = { 'CODE': 'robot', 'HANDLER': 'http://handler.com', 'AUTH_USER_ID': 1, 'NAME': 'Пример робота-встройки', 'USE_PLACEMENT': 'Y', 'PLACEMENT_HANDLER': 'http://handler.com', 'PROPERTIES': { 'string': { 'Name': 'Параметр 1', 'Type': 'string' }, 'stringm': { 'Name': 'Параметр 2', 'Type': 'string', 'Multiple': 'Y', 'Default': ['value 1', 'value 2'] }, } }; BX24.callMethod( 'bizproc.robot.add', params, function(result) { if(result.error()) alert("Ошибка: " + result.error()); } );
Для того, чтобы параметры можно было настраивать через приложение, при добавлении робота передаем параметры USE_PLACEMENT=Y
и обработчик PLACEMENT_HANDLER
.
Останется написать обработчик встройки, задача которого отрисовать параметры и сохранить их значения. Для этого в обработчик в PLACEMENT_OPTIONS
мы передаем данные:
- code — код вашего робота при регистрации
- activity_name — идентификатор действия в шаблоне бизнес-процесса
- properties — список свойств и их описание
- current_values — текущие значения свойств
- document_type — тип документа, над которым идет настройка
- document_fields — список полей документа
- template — список доступных полей шаблона (в коробке Битрикс24 доступно с версии 24.200.0)
Для параметра
template
доступны элементы:- parameters — список параметров шаблона
- variables — список переменных шаблона
- constants — список констант шаблона
- global_variables — список глобальных переменных
- global_constants — список глобальных констант
- return_activities — список действий (роботов), которые генерируют дополнительные результаты
При этом, структура свойств в этих списках приведена к единому формату и представляет из себя структуру:
{ Id: строка, идентификатор (код) свойства Type: строка, идентификатор типа свойства Name: строка, название Description: строка, описание Multiple: булевое, множественное свойство или нет Required: булевое, обязательное свойство или нет Options: смешанное. Зависит от типа свойства Settings: список настроек. Зависит от типа свойства Default: смешанное. Значение по умолчанию для свойства }
Список
return_activities
состоит из списка действий, которые возвращают результаты и их свойства. Имеет структуру:{ Id: строка, идентификатор действия в шаблоне Type: строка, тип действия Title: строка, название действия в шаблоне Return: список, доступные свойства }
В приложение все это приходит так:
Array ( [code] => robot [activity_name] => A72788_31169_37133_27365 [properties] => Array ( [string] => Array ( [NAME] => Параметр 1 [TYPE] => string ) [stringm] => Array ( [NAME] => Параметр 2 [TYPE] => string [MULTIPLE] => Y [DEFAULT] => Array ( [0] => value 1 [1] => value 2 ) ) ) [current_values] => Array ( [string] => 1 [stringm] => Array ( [0] => 2 ) ) [document_type] => Array ( [0] => crm [1] => CCrmDocumentDeal [2] => DEAL ) [document_fields] => Array ( [ID] => Array ( [Name] => ID [Type] => int [Filterable] => 1 [Editable] => [Required] => [BaseType] => int ) [TITLE] => Array ( [Name] => Название [Type] => string [Filterable] => 1 [Editable] => 1 [Required] => 1 [BaseType] => string ) [...] ) [template] => Array ( [parameters] => Array ( ) [variables] => Array ( [0] => Array ( [Id] => Approver [Type] => user [Name] => Утверждающий [Description] => [Multiple] => 1 [Required] => [Options] => [Settings] => [Default] => ) ) [constants] => Array ( [0] => Array ( [Id] => Manager [Type] => user [Name] => Кто утверждает [Description] => директор или заместитель [Multiple] => 1 [Required] => 1 [Options] => [Settings] => [Default] => Array ( [0] => user_4 ) ) ) [global_variables] => Array ( [0] => Array ( [Id] => Variable1666332520655 [Type] => user [Name] => test u [Description] => [Multiple] => 1 [Required] => [Options] => [Settings] => [Default] => Array ( [0] => user_1 ) ) ) [global_constants] => Array ( [0] => Array ( [Id] => Constant1666332578194 [Type] => user [Name] => test u 1 [Description] => [Multiple] => [Required] => [Options] => [Settings] => [Default] => user_1 ) ) [return_activities] => Array ( [0] => Array ( [Id] => A71026_84473_24610_19894 [Type] => LogActivity [Title] => Запись в отчет [Return] => Array ( [0] => Array ( [Id] => Report [Name] => Отчет [Type] => string ) ) ) [1] => Array ( [Id] => A58853_60082_34258_61777 [Type] => ApproveActivity [Title] => Утверждение [Return] => Array ( [0] => Array ( [Id] => TaskId [Name] => ID [Type] => int ) [1] => Array ( [Id] => Comments [Name] => Комментарии [Type] => string ) [2] => Array ( [Id] => VotedCount [Name] => Сколько проголосовало [Type] => int ) [3] => Array ( [Id] => TotalCount [Name] => Сколько должно проголосовать [Type] => int ) [4] => Array ( [Id] => VotedPercent [Name] => Процент проголосовавших [Type] => int ) [5] => Array ( [Id] => ApprovedPercent [Name] => Процент утвердивших [Type] => int ) [6] => Array ( [Id] => NotApprovedPercent [Name] => Процент отклонивших [Type] => int ) [7] => Array ( [Id] => ApprovedCount [Name] => Количество утвердивших [Type] => int ) [8] => Array ( [Id] => NotApprovedCount [Name] => Количество отклонивших [Type] => int ) [9] => Array ( [Id] => LastApprover [Name] => Последний голосовавший [Type] => user ) [10] => Array ( [Id] => LastApproverComment [Name] => Комментарий последнего голосовавшего [Type] => string ) [11] => Array ( [Id] => UserApprovers [Name] => Утвердили пользователи [Type] => user ) [12] => Array ( [Id] => Approvers [Name] => Утвердили пользователи (текст) [Type] => string ) [13] => Array ( [Id] => UserRejecters [Name] => Отклонили пользователи [Type] => user ) [14] => Array ( [Id] => Rejecters [Name] => Отклонили пользователи (текст) [Type] => string ) [15] => Array ( [Id] => IsTimeout [Name] => Автоматическое отклонение [Type] => int ) ) ) ) ) )
Осталось сделать верстку и научиться сохранять параметры непосредственно в Робота.
Для этого мы используем функцию setPropertyValue
, которая доступна нам через BX24.placement.call.
BX24.placement.call( 'setPropertyValue', {string: 'test string'} )
В качестве параметров передаются ID свойства и значения. Можно передавать несколько значений свойств, например:
BX24.placement.call( 'setPropertyValue', {string: 'test string', stringm: ['test2', 'test3']} )
Далее пользователь сохраняет робота как обычно.
Так это выглядит в Роботах:
А так в дизайнере бизнес-процессов:
Примечание: Белая область — встройка (фрейм приложения).
Полный код приложения
<?php header('Content-Type: text/html; charset=UTF-8'); $protocol = $_SERVER['SERVER_PORT'] == '443' ? 'https' : 'http'; $host = explode(':', $_SERVER['HTTP_HOST']); $host = $host[0]; define('BP_APP_HANDLER', $protocol.'://'.$host.explode('?', $_SERVER['REQUEST_URI'])[0]); ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> <script src="//api.bitrix24.com/api/v1/"></script> <?if (!isset($_POST['PLACEMENT']) || $_POST['PLACEMENT'] === 'DEFAULT'):?> <h1>Робот-встройка</h1> <div class="container-fluid"> <div class="container-fluid"> <h2>Робот</h2> <button onclick="installRobot();" class="btn btn-primary">Установить</button> – <button onclick="uninstallRobot();" class="btn btn-danger">Удалить</button> </div> <hr/> <div class="container-fluid"> <button onclick="getList();" class="btn btn-light">Получить список установленных роботов</button> </div> </div> <script type="text/javascript"> document.body.style.display = 'none'; BX24.init(function() { document.body.style.display = ''; }); function installRobot() { var params = { 'CODE': 'robot', 'HANDLER': '<?=BP_APP_HANDLER?>', 'AUTH_USER_ID': 1, 'NAME': 'Пример робота-встройки', 'USE_PLACEMENT': 'Y', 'PLACEMENT_HANDLER': '<?=BP_APP_HANDLER?>', 'PROPERTIES': { 'string': { 'Name': 'Параметр 1', 'Type': 'string' }, 'stringm': { 'Name': 'Параметр 2', 'Type': 'string', 'Multiple': 'Y', 'Default': ['value 1', 'value 2'] }, } }; BX24.callMethod( 'bizproc.robot.add', params, function(result) { if(result.error()) alert("Ошибка: " + result.error()); else alert("Успешно"); } ); } function uninstallRobot() { BX24.callMethod( 'bizproc.robot.delete', { 'CODE': 'robot' }, function(result) { if(result.error()) alert('Ошибка: ' + result.error()); else alert("Успешно"); } ); } function getList() { BX24.callMethod( 'bizproc.robot.list', {}, function(result) { if(result.error()) alert("Ошибка: " + result.error()); else alert("Коды установленных роботов: " + result.data().join(', ')); } ); } </script> <?php else:?> <form name="props" class="container-fluid"> <?php $options = json_decode($_POST['PLACEMENT_OPTIONS'], true); foreach ($options['properties'] as $id => $property) { $multiple = isset($property['MULTIPLE']) && $property['MULTIPLE'] === 'Y'; $val = (array) $options['current_values'][$id]; if (!$val) { $val[] = ''; } if ($multiple) { $val[] = ''; } $name = $multiple ? $id.'[]' : $id; ?> <div class="form-group"> <label><?=htmlspecialchars($property['NAME'])?>:</label> <?foreach ($val as $v):?> <p><input name="<?=$name?>" value="<?=htmlspecialchars((string)$v)?>" class="form-control" onchange="setPropertyValue('<?=$id?>', this.name, <?=(int)$multiple?>)"></p> <?endforeach;?> </div> <? } ?> <script> function setPropertyValue(name, inputName, multiple) { var form = new FormData(document.forms.props); var value = multiple? form.getAll(inputName) : form.get(inputName); var params = {}; params[name] = value; BX24.placement.call( 'setPropertyValue', params ) } </script> </form> <?php endif;?> </body> </html>
Пользовательские комментарии
Мы будем рады, если разработчики добавят свои комментарии по практическому использованию методов системы.Для этого нужно всего лишь авторизоваться на сайте
Но помните, что Пользовательские комментарии, несмотря на модерацию, не являются официальной документацией. Ответственность за их использование несет сам пользователь.
Также Пользовательские комментарии не являются местом для обсуждения функционала. По подобным вопросам обращайтесь на форумы.