Documentation

Main Scenarios and an Example

  1. Inbound call from PBX to an internal number of a specific user must display call details card to a Bitrix24 employee (Method telephony.externalcall.register).

  2. Inbound call from an unknown number (not registered in CRM) must be enqueued for processing (to list of users, responsible for inbound calls):
    • Simultaneous queue: call details card is displayed to all users that aren't responding to other calls at present moment. Displayed call details card disappears when one of such users/employees responds to this call (first telephony.externalcall.register for the first user in queue, then telephony.externalcall.show for the rest of users).
    • Sequential queue: call details card is displayed for a period of time (3-5-7 seconds) for each of queue employees that presently aren't responding to other calls. When an employee doesn't respond to this call, call details card disappears for this user, and the call is forwarded to the next employee in the queue (first telephony.externalcall.register for the first in queue, then telephony.externalcall.hide and telephony.externalcall.show for the subsequent user).

  3. Inbound call from a known (identifier) number is displayed as a call details card in Bitrix24 for a agent/manager, responsible for corresponding CRM object. (First telephony.externalcall.register with SHOW = 0, that returns either CREATED_LEAD in case, if the phone number wasn't found in CRM and a new lead was created, or returns both CRM_ENTITY_TYPE and CRM_ENTITY_ID indicating an existing customer.
    Simultaneously, returns CRM_ACTIVITY_ID with a new CRM activity identifier, registering this call. Now, you can use REST methods and use a known CRM object ID to get an ID for the agent responsible for the customer, forward the call to this agent and display the call details card to this agent via telephony.externalcall.show)

  4. Bitrix24 user clicks to a phone number in the CRM interface. The app initiates an outbound call to the specified number at the PBX (event onexternalcallstart and the user sees the call card telephony.externalcall.register).

  5. The call (inbound or outbound) has concluded. The call and the record are registered in the CRM object (telephony.externalcall.finish. You need to hide the call card (telephony.externalcall.hide) If the call record isn't ready when call finishes at the PBX. Only then, when the record is generated, you can call telephony.externalcall.finish).

  6. PBX registered an inbound call at the moment when there are no associations between PBX and Bitrix24 due to some reasons. After restoring the connection, information regarding the occurred call is registered in Bitrix24 (see. items 1-3, but without displayed call card - sequential calling of methods telephony.externalcall.register with the parameter SHOW = 0 and telephony.externalcall.finish.)

Note: the application must pass CALL_LIST_ID, received in call start events to add record to a call within a dialling scenario.

Example:

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

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

// generate URL for your script to be used in AJAX queries from app 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'];

// when receiving an inbound call event, the authorization is passed via auth node in the request array
// however, we need only the domain from this array; at this moment we have already saved the authorization details
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 {

    // save tokens for user, who installed the app
    $appsConfig = $_REQUEST;
    saveParams($appsConfig);

    // register the inbound call event
    restCommand('event.bind', array(
            "event" => 'ONEXTERNALCALLSTART',
            "handler" => $script_url."?action=outcoming",
        ),
        $b24domain, $appsConfig['AUTH_ID']);

    /* test event for checking the config
    restCommand('event.bind', array(
        "event" => 'ONAPPTEST',
        "handler" => $script_url."?action=test",
        ),
        $b24domain, $appsConfig['AUTH_ID']);
    */

}

$action = $_REQUEST['action'];

// we just launched 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">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>

<?
    // if you are interested, you can view, which auth parameters Bitrix24 passes to the app script
    // in case of app being executed inside Bitrix24 frame
    //echo "<pre>";
	//print_r($_REQUEST);
	//echo "</pre>";

?>
<script>
    $( "#incoming" ).on( "click", function( event ) {
        // here, we initiate the third-party PBX, specifically, for inbound calls
        // that's we use AJAX, passing auth parameters and etc.
        // in actual practice, telephony REST is called from PBX. We have saved details for PBX already
        // authorization tokens (see. $appsConfig$appsConfig) are already known to us, so we can determine to which Bitrix24 instance to send them
        // REST call, defining users to show the card details, 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 by server script (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;
}

?>


© «Bitrix24», 2001-2024