<?php
/**
 * Complete Telephony Event Handling Script for Bitrix24
 */

// Generate URL for your script to be used in AJAX queries from the 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 = isset($_REQUEST['DOMAIN']) ? $_REQUEST['DOMAIN'] : '';

// Get domain from auth array if available
if (!empty($_REQUEST['auth'])) {
    $b24domain = $_REQUEST['auth']['domain'];
}

$configFileName = '/config_' . trim(str_replace('.', '_', $b24domain)) . '.php';

// Load or save the configuration
if (file_exists(getcwd() . $configFileName)) {
    include_once getcwd() . $configFileName;
} else {
    $appsConfig = $_REQUEST;
    saveParams($appsConfig);

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

$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';

// Display the HTML form or handle the action
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>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" crossorigin="anonymous">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" crossorigin="anonymous">
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" 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>
    <div id="debug"></div>
    <script>
        $( "#incoming" ).on( "click", function( event ) {
            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(),
                    DOMAIN: auth['domain']
                },
                success: function( result ) {
                    $( "#debug" ).html( result );
                }
            });
        });
    </script>
    </body>
    </html>
    <?php
} else {
    switch ($action) {
        case 'outcoming':
            writeToLog(array('outcoming' => $_REQUEST), 'telephony event');
            $result = restCommand('telephony.externalCall.register',
                $b24domain, $appsConfig['AUTH_ID'], array(
                    "USER_ID" => $_REQUEST['data']['USER_ID'],
                    "PHONE_NUMBER"   => $_REQUEST['data']['PHONE_NUMBER'],
                    "TYPE" => '1',
                    "CRM_CREATE" => 1
                ));
            $appsConfig['CALL'] = $result['result'];
            saveParams($appsConfig);
            break;

        case 'incoming':
            $result = restCommand('telephony.externalCall.register',
                $b24domain, $appsConfig['AUTH_ID'], array(
                    "USER_ID" => $_REQUEST['user1'],
                    "PHONE_NUMBER"   => $_REQUEST['phone'],
                    "TYPE" => '2',
                    "CRM_CREATE" => true
                ));
            $appsConfig['CALL'] = $result['result'];
            saveParams($appsConfig);
            echo "incoming <pre>";
            print_r($appsConfig);
            echo "</pre>";
            break;

        case 'redirect':
            if ($appsConfig['CALL']['CALL_ID'] != '') {
                $result = restCommand('telephony.externalCall.hide',
                    $b24domain, $appsConfig['AUTH_ID'], array(
                        "CALL_ID" => $appsConfig['CALL']['CALL_ID'],
                        "USER_ID" => $_REQUEST['user1']
                    ));
                $result = restCommand('telephony.externalCall.show',
                    $b24domain, $appsConfig['AUTH_ID'], array(
                        "CALL_ID" => $appsConfig['CALL']['CALL_ID'],
                        "USER_ID" => $_REQUEST['user2']
                    ));
            }
            echo "redirected to " . $_REQUEST['user2'];
            break;

        case 'drop':
            if ($appsConfig['CALL']['CALL_ID'] != '') {
                $result = restCommand('telephony.externalCall.finish',
                    $b24domain, $appsConfig['AUTH_ID'], array(
                        "CALL_ID" => $appsConfig['CALL']['CALL_ID'],
                        "USER_ID" => $_REQUEST['user1'],
                        "DURATION"   => '120',
                        "STATUS_CODE" => '200',
                        "ADD_TO_CHAT" => true
                    ));
                echo "dropped and saved";
            }
            break;
    }
}

/**
 * Save application configuration.
 */
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.
 */
function restCommand($method, $auth_domain, $access_token, array $params = array()) {
    $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,
    ));
    $result = curl_exec($curl);
    writeToLog(array('raw' => $result), 'telephony got data');
    curl_close($curl);
    return json_decode($result, 1);
}

/**
 * Write data to log file.
 */
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;
}
?>