Documentation

Main User Scenarios and Example

  1. Inbound call to PBX to an internal number of a specific user shall show a call ID screen to a respective user in Bitrix24 (Method telephony.externalcall.register).

  2. Inbound call from an unknown caller ID (not registered in CRM) shall go into processing queue (a list of users responsible for answering inbound calls):
    • Concurrent queue: the call ID screen is shown to all available employees at once. As soon as any employee answers the call, all the other information windows are hidden (first call telephony.externalcall.register on the first person in the queue, then call telephony.externalcall.show on other persons).
    • Sequential queue: call ID screen is shown for a defined period of time (3-5-7 seconds) to each of the available employees in the queue, who are not answering other calls at the moment. If an employee fails to answer the call within time allotted, the call ID screen hides and the call redirected to the next employee in the queue (first telephony.externalcall.register for the first person in the queue, then telephony.externalcall.hide and telephony.externalcall.show for the subsequent one).

  3. Inbound call from a known caller ID shows the call ID screen in Bitrix24 to the manager, responsible for corresponding CRM object. (First, call telephony.externalcall.register with SHOW = 0, which will return either CREATED_LEAD if the telephone was not found in CRM and a new lead was created, or a couple CRM_ENTITY_TYPE and CRM_ENTITY_ID with indication of the found existing client.
    The method will also return the CRM_ACTIVITY_ID if returned with the new activity ID in CRM, to which the call will be subsequently attached. By knowing the object ID in CRM, the manager ID, who is responsible for the client, can be retrieved via REST methods used to work with CRM. The call can be forwarded to this manager and to display the call ID screen to him/her, telephony.externalcall.show)

  4. An employee clicks on a phone number in the Bitrix24 CRM interface. The application initiates an outbound call to the specified number at the side of PBX (event onexternalcallstart, call ID screen is displayed to the employee, telephony.externalcall.register).

  5. When a call is completed (inbound or outbound), the call and the record are registered in the connection to the CRM object (telephony.externalcall.finish. If the call recording is still being processed by that moment, then instead of telephony.externalcall.finish, hide the call ID screen via calling telephony.externalcall.hide first. Then, only after the record is ready, call telephony.externalcall.finish).

  6. For some reasons, an inbound call occurred on the PBX side at the moment, when there is no link between PBX and Bitrix24. After the connection is re-established, the information about the performed call is registered in Bitrix24 (see. 1-3) but without showing the call ID screen – by sequentially calling the following methods telephony.externalcall.register with SHOW = 0 and telephony.externalcall.finish.)

Note. To add the record to the call within the call list scenario, the application shall pass CALL_LIST_ID which will be returned to them in the call start event.

Example:

<?php
/**
 * Created by PhpStorm.
 * User: sv
 * Date: 01.11.16
 * Time: 10:44
 */

// ini_set('display_errors','Off');

// generate url of our script to 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 an event was received from the inbound call, then the authorization is passed via the auth node in the request array
// however, only the domain is required from this data; to this time, we already have saved the authorization
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 {

    // we save only tokens of the user, who installed the application
    $appsConfig = $_REQUEST;
    saveParams($appsConfig);

    // register the outbound 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 have to launch the application in 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">Inbound 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>

<?
    // if you are interested, you can check, which authorization parameters are passed by Bitrix24 to the application script 
    // if the app is created in the frame inside Bitrix24 
    //echo "<pre>";
	//print_r($_REQUEST);
	//echo "</pre>";

?>
<script>
    $( "#incoming" ).on( "click", function( event ) {
        // here, we are imitating the work of an external PBX, specifically, the scenario of receiving an inbound call
        // that is why AJAX, passing of authorization parameters and etc.
        // in actuality, telephony REST will be called from the side of PBX, and there, we have already saved  
        // authorization tokens (see. $appsConfig$appsConfig) and already know, to which Bitrix24 account a REST call should be sent,
        // to which users the call ID screen should be displayed and 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 );
            }
        });
    });
    /* initiation of a text event on the side of server script, there is 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>
<? } 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;
}

?>


User Comments

User comments are not part of official documentation. Use information provided by other users in the comments at your own risk.

The User Comments section is not to be used as a feature discussion board. Only registered users can post comments. Your comment will be visible once it has been approved by the moderator.
© «Bitrix Inc.», 2001-2021, «Bitrix Inc.», 2021