REST automation rule (activities) setup via application (embedded)
Description
Starting from the Workflows module version 20.0.600 you configure automation rule/activity using application interface. It's implemented via standard embedding mechanism rest.placement.
Implementation via app example
Let's overview a specific example with an app (full app code is provided below).
In this example, application adds an automation rule/robot that has 2 String parameters:
var params = { 'CODE': 'robot', 'HANDLER': 'http://handler.com', 'AUTH_USER_ID': 1, 'NAME': 'Example of embedded automation rule', 'USE_PLACEMENT': 'Y', 'PLACEMENT_HANDLER': 'http://handler.com', 'PROPERTIES': { 'string': { 'Name': 'Parameter 1', 'Type': 'string' }, 'stringm': { 'Name': 'Parameter 2', 'Type': 'string', 'Multiple': 'Y', 'Default': ['value 1', 'value 2'] }, } }; BX24.callMethod( 'bizproc.robot.add', params, function(result) { if(result.error()) alert("Error: " + result.error()); } );
To be able to configure parameters using the application, you need to pass parameters USE_PLACEMENT=Y
and handler PLACEMENT_HANDLER
when adding an automation rule.
The remaining task is to compose an embedding handler that must render parameters and save their values. Pass the following data to the handler's PLACEMENT_OPTIONS
:
- code — your automation rule code upon registration
- activity_name — activity ID in workflow template
- properties — property list and description
- current_values — current property values
- document_type — configured document type
- document_fields — document field list
- template — list of available template fields (available in Bitrix24 Self-hosted starting from version 24.200.0)
The following elements are available for parameter
template
:- parameters — template parameter list
- variables — template variable list
- constants — template constant list
- global_variables — global variable list
- global_constants — global constants list
- return_activities — automation rules (activities) list that generate additional results
Additionally, these properties structure in lists are converted to a single format and has the following structure:
{ Id: property string, identifier (code) Type: property type string, identifier Name: string, name Description: string, description Multiple: boolean, multiple property or not Required: boolean, required property or not Options: mixed. Depends on property type Settings: settings list. Depends on property type Default: смешанное. Default value for property }
List
return_activities
consists of activity list that return results and properties. Has the following structure:{ Id: string, activity ID in template Type: string, activity type Title: string, activity name in template Return: list, available properties }
Inside the app this looks as follows:
Array ( [code] => robot [activity_name] => A72788_31169_37133_27365 [properties] => Array ( [string] => Array ( [NAME] => Parameter 1 [TYPE] => string ) [stringm] => Array ( [NAME] => Parameter 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] => Name [Type] => string [Filterable] => 1 [Editable] => 1 [Required] => 1 [BaseType] => string ) [...] ) [template] => Array ( [parameters] => Array ( ) [variables] => Array ( [0] => Array ( [Id] => Approver [Type] => user [Name] => Approver [Description] => [Multiple] => 1 [Required] => [Options] => [Settings] => [Default] => ) ) [constants] => Array ( [0] => Array ( [Id] => Manager [Type] => user [Name] => Approver [Description] => director or deputy [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] => Report entry [Return] => Array ( [0] => Array ( [Id] => Report [Name] => Report [Type] => string ) ) ) [1] => Array ( [Id] => A58853_60082_34258_61777 [Type] => ApproveActivity [Title] => Approval [Return] => Array ( [0] => Array ( [Id] => TaskId [Name] => ID [Type] => int ) [1] => Array ( [Id] => Comments [Name] => Comments [Type] => string ) [2] => Array ( [Id] => VotedCount [Name] => Voted [Type] => int ) [3] => Array ( [Id] => TotalCount [Name] => Total voters [Type] => int ) [4] => Array ( [Id] => VotedPercent [Name] => Voter percentage [Type] => int ) [5] => Array ( [Id] => ApprovedPercent [Name] => Approved percentage [Type] => int ) [6] => Array ( [Id] => NotApprovedPercent [Name] => Declined percentage [Type] => int ) [7] => Array ( [Id] => ApprovedCount [Name] => Approved count [Type] => int ) [8] => Array ( [Id] => NotApprovedCount [Name] => Rejected count [Type] => int ) [9] => Array ( [Id] => LastApprover [Name] => Voted last [Type] => user ) [10] => Array ( [Id] => LastApproverComment [Name] => Last voter comment [Type] => string ) [11] => Array ( [Id] => UserApprovers [Name] => Users approved [Type] => user ) [12] => Array ( [Id] => Approvers [Name] => Users approved (text) [Type] => string ) [13] => Array ( [Id] => UserRejecters [Name] => Users rejected [Type] => user ) [14] => Array ( [Id] => Rejecters [Name] => Users rejected (text) [Type] => string ) [15] => Array ( [Id] => IsTimeout [Name] => Automatic decline [Type] => int ) ) ) ) ) )
What remains is to create layout and learn how to save parameters directly in automation rules.
For this, use the function setPropertyValue
, available via BX24.placement.call.
BX24.placement.call( 'setPropertyValue', {string: 'test string'} )
Property ID and values are passed as parameters. You can pass several property values, for example:
BX24.placement.call( 'setPropertyValue', {string: 'test string', stringm: ['test2', 'test3']} )
Then user saves automation rule, as usual пользователь сохраняет робота как обычно.
Full app code
<?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>Embedded automation rule</h1> <div class="container-fluid"> <div class="container-fluid"> <h2>Automation rule</h2> <button onclick="installRobot();" class="btn btn-primary">Install</button> – <button onclick="uninstallRobot();" class="btn btn-danger">Delete</button> </div> <hr/> <div class="container-fluid"> <button onclick="getList();" class="btn btn-light">Get list of installed automation rules</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': 'Embedded automation rule example', 'USE_PLACEMENT': 'Y', 'PLACEMENT_HANDLER': '<?=BP_APP_HANDLER?>', 'PROPERTIES': { 'string': { 'Name': 'Parameter 1', 'Type': 'string' }, 'stringm': { 'Name': 'Parameter 2', 'Type': 'string', 'Multiple': 'Y', 'Default': ['value 1', 'value 2'] }, } }; BX24.callMethod( 'bizproc.robot.add', params, function(result) { if(result.error()) alert("Error: " + result.error()); else alert("Successul"); } ); } function uninstallRobot() { BX24.callMethod( 'bizproc.robot.delete', { 'CODE': 'robot' }, function(result) { if(result.error()) alert('Error: ' + result.error()); else alert("Successful"); } ); } function getList() { BX24.callMethod( 'bizproc.robot.list', {}, function(result) { if(result.error()) alert("Error: " + result.error()); else alert("Installed automation rule codes: " + 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>