Typical use-cases and scenarios example
We are still updating this page
Some data may be missing — we will fill it in shortly.
-
An incoming call to the PBX on a specific user's internal number should display the call card for the employee in Bitrix24, using the method telephony.externalcall.register.
-
An incoming call from an unknown number, not registered in the CRM, should enter a processing queue from the list of users who should answer incoming calls:
- Simultaneous queue: all employees who are not currently answering other calls will simultaneously see the call card when one of them starts answering the call, while the others will lose the card. First, we use
telephony.externalcall.registerfor the first in the queue, then telephony.externalcall.show for the others. - Sequential queue: each of the employees in the queue who are not currently answering other calls will see the call card for a certain period, 3-5-7 seconds. If the employee does not start answering the call, the card disappears, and the call is transferred to the next in line. First, we use
telephony.externalcall.registerfor the first in the queue, then telephony.externalcall.hide andtelephony.externalcall.showfor the next.
- Simultaneous queue: all employees who are not currently answering other calls will simultaneously see the call card when one of them starts answering the call, while the others will lose the card. First, we use
-
An incoming call from a known number is displayed as a call card in Bitrix24 for the manager responsible for the corresponding CRM entity. First,
telephony.externalcall.registerwithSHOW = 0, which will return eitherCREATED_LEADif the phone was not found in the CRM and a new lead was created, or a pair ofCRM_ENTITY_TYPEandCRM_ENTITY_IDindicating the found existing client. Simultaneously,CRM_ACTIVITY_IDis returned with the identifier of the new activity in the CRM, where the call will be recorded later. Knowing the identifier of the entity in the CRM, we can use CRM methods to get the identifier of the manager responsible for the client, transfer the call to them, and show them the call card usingtelephony.externalcall.show. -
An employee in Bitrix24 clicks on the phone number in the CRM interface. The application initiates an outgoing call to the specified number on the PBX side, triggering the event
onexternalcallstart, and the employee sees the call card usingtelephony.externalcall.register. -
The call is completed, either incoming or outgoing. The fact of the call and the recording are recorded in relation to the CRM entity using telephony.externalcall.finish. If at the time of call completion the recording is not yet ready on the PBX, instead of
telephony.externalcall.finish, we first simply hide the call card usingtelephony.externalcall.hide, and then, when the recording is ready, we calltelephony.externalcall.finish. -
An incoming call occurred on the PBX at a time when there was no connection between the PBX and Bitrix24 for some reason. After the connection is restored, information about the occurred call is recorded in Bitrix24, points 1-3, but without showing the call card – a sequential call of the methods
telephony.externalcall.registerwith the parameterSHOW = 0andtelephony.externalcall.finish.
Note
To ensure the recording is added to the call during the calling scenario, applications must pass CALL_LIST_ID that they receive in the event at the start of the call.
Example
<?php
/**
* Created by PhpStorm.
* User: sv
* Date: 01.11.16
* Time: 10:44
*/
// ini_set('display_errors','Off');
// forming the URL of our script for use in AJAX requests from the application interface
$script_url = ($_SERVER['SERVER_PORT'] == 443 ? 'https' : 'http') . '://' . $_SERVER['SERVER_NAME'] . (in_array($_SERVER['SERVER_PORT'],
array(80, 443)) ? '' : ':' . $_SERVER['SERVER_PORT']) . $_SERVER['SCRIPT_NAME'];
$appsConfig = array();
$b24domain = $_REQUEST['DOMAIN'];
// if we received an outgoing call event, then authorization is passed through the auth node in the request array
// but we only need the domain from there, we have already saved the authorization by this point
if (!empty($_REQUEST['auth'])) {
$b24domain = $_REQUEST['auth']['domain'];
}
$configFileName = '/config_' . trim(str_replace('.', '_', $b24domain)) . '.php';
echo getcwd().$configFileName."<br/>";
if (file_exists(getcwd() . $configFileName)) {
include_once getcwd() . $configFileName;
} else {
// saving tokens for the user setting up the application
$appsConfig = $_REQUEST;
saveParams($appsConfig);
// registering the outgoing call event
restCommand('event.bind', array(
"event" => 'ONEXTERNALCALLSTART',
"handler" => $script_url."?action=outcoming",
),
$b24domain, $appsConfig['AUTH_ID']);
/* test event to check the mechanism
restCommand('event.bind', array(
"event" => 'ONAPPTEST',
"handler" => $script_url."?action=test",
),
$b24domain, $appsConfig['AUTH_ID']);
*/
}
$action = $_REQUEST['action'];
// we just launched the application in the Bitrix24 interface
if ($action == '') {
?>
<html>
<head>
<meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="//api.bitrix24.com/api/v1/"></script>
</head>
<body>
<div class="form-group">
<label for="IncomingNumber">Incoming call number</label>
<input type="text" class="form-control" id="incomingNumber" placeholder="phone">
</div>
<div class="form-group">
<label for="user1">User 1</label>
<input type="text" class="form-control" id="user1" placeholder="user id" value="1">
</div>
<div class="form-group">
<label for="user2">User 2 (for call transfer)</label>
<input type="text" class="form-control" id="user2" placeholder="user id">
</div>
<a class="btn btn-default" href="#" role="button" id="incoming">Incoming</a>
<a class="btn btn-default" href="#" role="button" id="redirect">Redirect</a>
<a class="btn btn-default" href="#" role="button" id="drop">Drop</a>
<a class="btn btn-default" href="#" role="button" id="test">Event test</a>
<div id="debug"></div>
<?php
// if you're curious, you can see what authorization parameters Bitrix24 passes to the application script
// when the application is executed in a frame inside Bitrix24
//echo "<pre>";
//print_r($_REQUEST);
//echo "</pre>";
?>
<script>
$( "#incoming" ).on( "click", function( event ) {
// here we simulate the operation of an external PBX, in particular, receiving an incoming call
// hence AJAX, passing authorization parameters, etc.
// in real practice, REST telephony will be called from the PBX side, and there we have already saved
// authorization tokens (see $appsConfig) and we know which Bitrix24 to send the
// REST call to, which users to show the card to, etc.
auth = BX24.getAuth();
$.ajax({
url: "<?=$script_url?>",
data: {
action: 'incoming',
user1: $( "#user1" ).val(),
phone: $( "#incomingNumber" ).val(),
DOMAIN: auth['domain']
},
success: function( result ) {
$( "#debug" ).html( result );
}
});
});
$( "#redirect" ).on( "click", function( event ) {
auth = BX24.getAuth();
$.ajax({
url: "<?=$script_url?>",
data: {
action: 'redirect',
user1: $( "#user1" ).val(),
user2: $( "#user2" ).val(),
DOMAIN: auth['domain']
},
success: function( result ) {
$( "#debug" ).html( result );
}
});
});
$( "#drop" ).on( "click", function( event ) {
auth = BX24.getAuth();
$.ajax({
url: "<?=$script_url?>",
data: {
action: 'drop',
user1: $( "#user1" ).val(),
user2: $( "#user2" ).val(),
DOMAIN: auth['domain']
},
success: function( result ) {
$( "#debug" ).html( result );
}
});
});
/* initiating a test event on the server script side, nothing important
$( "#test" ).on( "click", function( event ) {
auth = BX24.getAuth();
$.ajax({
url: "<?=$script_url?>",
data: {
action: 'eventtest',
DOMAIN: auth['domain']
},
success: function( result ) {
$( "#debug" ).html( result );
}
});
});
*/
</script>
</body>
</html>
<?php } else {
switch ($action) {
case 'test': writeToLog(array('test' => $_REQUEST), 'telephony test event');
break;
case 'outcoming':
writeToLog(array('outcoming' => $_REQUEST), 'telephony event');
$result = restCommand('telephony.externalCall.register',
array(
"USER_ID" => $_REQUEST['data']['USER_ID'],
"PHONE_NUMBER" => $_REQUEST['data']['PHONE_NUMBER'],
"TYPE" => '1',
"CRM_CREATE" => 1
),
$b24domain, $appsConfig['AUTH_ID']);
$appsConfig['CALL'] = $result['result'];
saveParams($appsConfig);
break;
case 'eventtest':
writeToLog(array('eventtest' => $_REQUEST), 'test event call');
$result = restCommand('event.test',
array(
),
$b24domain, $appsConfig['AUTH_ID']);
echo "test event call";
break;
case 'incoming':
$result = restCommand('telephony.externalCall.register',
array(
"USER_ID" => $_REQUEST['user1'],
"PHONE_NUMBER" => $_REQUEST['phone'],
"TYPE" => '2',
"CRM_CREATE" => true
),
$b24domain, $appsConfig['AUTH_ID']);
$appsConfig['CALL'] = $result['result'];
saveParams($appsConfig);
echo "incoming <pre>";
print_r($appsConfig);
echo "</pre>";
break;
case 'redirect':
echo "redirect <pre>";
print_r($appsConfig);
echo "</pre>";
if ($appsConfig['CALL']['CALL_ID'] != '') {
$result = restCommand('telephony.externalCall.hide',
array(
"CALL_ID" => $appsConfig['CALL']['CALL_ID'],
"USER_ID" => $_REQUEST['user1']
),
$b24domain, $appsConfig['AUTH_ID']);
$result = restCommand('telephony.externalCall.show',
array(
"CALL_ID" => $appsConfig['CALL']['CALL_ID'],
"USER_ID" => $_REQUEST['user2']
),
$b24domain, $appsConfig['AUTH_ID']);
}
echo "redirected to ".$_REQUEST['user2'];
break;
case 'drop':
writeToLog(array('config' => $appsConfig), 'call is finishing');
if ($appsConfig['CALL']['CALL_ID'] != '') {
$result = restCommand('telephony.externalCall.finish',
array(
"CALL_ID" => $appsConfig['CALL']['CALL_ID'],
"USER_ID" => $_REQUEST['user1'],
"DURATION" => '120',
"STATUS_CODE" => '200',
"ADD_TO_CHAT" => true
),
$b24domain, $appsConfig['AUTH_ID']);
$appsConfig['CALL'] = $result['result'];
saveParams($appsConfig);
echo "finished <pre>";
print_r($appsConfig);
echo "</pre>";
writeToLog(array('request' => $_REQUEST, 'config' => $appsConfig), 'call is finished');
}
echo "dropped and saved";
break;
}
}
?>
/**
* Save application configuration.
*
* @param $params
*
* @return bool
*/
function saveParams($params) {
$config = "<?php\n";
$config .= "\$appsConfig = " . var_export($params, true) . ";\n";
$config .= "?>";
$configFileName = '/config_' . trim(str_replace('.', '_', $_REQUEST['DOMAIN'])) . '.php';
file_put_contents(getcwd() . $configFileName, $config);
return true;
}
/**
* Send rest query to Bitrix24.
*
* @param $method - Rest method, ex: methods
* @param array $params - Method params, ex: array()
* @param array $auth - Authorize data, ex: array('domain' => 'https://test.bitrix24.com', 'access_token' => '7inpwszbuu8vnwr5jmabqa467rqur7u6')
*
* @return mixed
*/
function restCommand($method, array $params = array(), $auth_domain, $access_token) {
$queryUrl = 'https://' . $auth_domain . '/rest/' . $method;
$queryData = http_build_query(array_merge($params, array('auth' => $access_token)));
writeToLog(array('URL' => $queryUrl, 'PARAMS' => array_merge($params, array("auth" => $access_token))), 'telephony send data');
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_POST => 1,
CURLOPT_HEADER => 0,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $queryUrl,
CURLOPT_POSTFIELDS => $queryData,
CURLOPT_VERBOSE => 1
));
$result = curl_exec($curl);
writeToLog(array('raw' => $result), 'telephony got data');
curl_close($curl);
$result = json_decode($result, 1);
return $result;
}
/**
* Write data to log file.
*
* @param mixed $data
* @param string $title
*
* @return bool
*/
function writeToLog($data, $title = '') {
$log = "\n------------------------\n";
$log .= date("Y.m.d G:i:s") . "\n";
$log .= (strlen($title) > 0 ? $title : 'DEBUG') . "\n";
$log .= print_r($data, 1);
$log .= "\n------------------------\n";
file_put_contents(getcwd() . '/tel.log', $log, FILE_APPEND);
return true;
}
?>
How to Use Examples in Documentation