test

🧩 Syntax:
<?php
// This is a code block
// This code is for demonstration purposes only and may not run or compile as expected
// Use it at your own risk

// Require the ReactPHP and clue/reactphp-ami libraries
require 'vendor/autoload.php';

// Define the SecureCall class
class SecureCall {

// Define the properties
private string $doctorPhone;
private string $patientPhone;
private int $warnTime;
private int $hangTime;
private Clue\React\Ami\Client $client;
private Clue\React\Ami\ActionSender $sender;
private string $patientChannel;
private string $doctorChannel;

// Define the constructor
public function __construct(string $doctorPhone, string $patientPhone, int $warnTime, int $hangTime) {
// Assign the parameters to the properties
$this->doctorPhone = $doctorPhone;
$this->patientPhone = $patientPhone;
$this->warnTime = $warnTime;
$this->hangTime = $hangTime;

// Create a new Factory instance
$factory = new Clue\React\Ami\Factory();

// Create a new Client instance and connect to the Asterisk server
$factory->createClient('user:secret@localhost')->then(function (Clue\React\Ami\Client $client) {
// Assign the client to the property
$this->client = $client;

// Create a new ActionSender instance
$this->sender = new Clue\React\Ami\ActionSender($client);

// Call the patient number
$this->callPatient();
});
}

// Define the callPatient method
private function callPatient() {
// Try to originate a call to the patient number using the ActionSender instance
try {
// Create an action with the parameters
$action = new Clue\React\Ami\Protocol\Action([
'Action' => 'Originate',
'Channel' => 'SIP/' . $this->patientPhone,
'Context' => 'default',
'Exten' => 's',
'Priority' => 1,
'CallerID' => 'SecureCall',
'Async' => true,
'Variable' => [
'__SECURECALL' => true,
'__DOCTORPHONE' => $this->doctorPhone,
'__WARNTIME' => $this->warnTime,
'__HANGTIME' => $this->hangTime
]
]);

// Send the action and get a promise for the response
$promise = $this->sender->request($action);

// Handle the response when it arrives
$promise->then(function (Clue\React\Ami\Protocol\Response $response) {
// Check if the call was answered
if ($response->getFieldValue('Response') == 'Success' &&
($response->getFieldValue('Reason') == '4' ||
strpos($response->getFieldValue('Message'), 'Originate successfully queued') !== false)) {
// Get the patient channel from the response
if ($response->hasField('Channel')) {
// Use the Channel field if available (Asterisk 1.8+)
$this->patientChannel = $response->getFieldValue('Channel');
} else {
// Use the SIP channel name otherwise (Asterisk 1.6-)
$this->patientChannel = 'SIP/' . $this->patientPhone . '-' . substr($response->getActionId(), -4);
}

// Call the doctor number
$this->callDoctor();
} else {
// Call an web api and send status
$this->callWebApi('patient_not_answered');
}
});
} catch (Exception $e) {
// Handle any errors that may occur when sending the action
echo 'Error: ' . $e->getMessage() . PHP_EOL;
}
}
// Define the callDoctor method
    private function callDoctor() {
        // Try to originate a call to the doctor number using the ActionSender instance
        try {
            // Create an action with the parameters
            $action = new Clue\React\Ami\Protocol\Action([
                'Action' => 'Originate',
                'Channel' => 'SIP/' . $this->doctorPhone,
                'Context' => 'default',
                'Exten' => 's',
                'Priority' => 1,
                'CallerID' => 'SecureCall',
                'Async' => true,
                'Variable' => [
                    '__SECURECALL' => true,
                    '__PATIENTPHONE' => $this->patientPhone,
                    '__WARNTIME' => $this->warnTime,
                    '__HANGTIME' => $this->hangTime
                ]
            ]);

            // Send the action and get a promise for the response
            $promise = $this->sender->request($action);

            // Handle the response when it arrives
            $promise->then(function (Clue\React\Ami\Protocol\Response $response) {
                // Check if the call was answered
                if ($response->getFieldValue('Response') == 'Success' &&
                    ($response->getFieldValue('Reason') == '4' ||
                        strpos($response->getFieldValue('Message'), 'Originate successfully queued') !== false)) {
                    // Get the doctor channel from the response
                    if ($response->hasField('Channel')) {
                        // Use the Channel field if available (Asterisk 1.8+)
                        $this->doctorChannel = $response->getFieldValue('Channel');
                    } else {
                        // Use the SIP channel name otherwise (Asterisk 1.6-)
                        $this->doctorChannel = 'SIP/' . $this->doctorPhone . '-' . substr($response->getActionId(), -4);
                    }

                    // Bridge the patient and doctor channels
                    $this->bridgeChannels();
                } else {
                    // Call an web api and send status
                    $this->callWebApi('doctor_not_answered');
                }
            });
        } catch (Exception $e) {
            // Handle any errors that may occur when sending the action
            echo 'Error: ' . $e->getMessage() . PHP_EOL;
        }
    }

    // Define the bridgeChannels method
    private function bridgeChannels() {
        // Try to bridge the patient and doctor channels using the ActionSender instance
        try {
            // Create an action with the parameters
            $action = new Clue\React\Ami\Protocol\Action([
                'Action' => 'Bridge',
                'Channel1' => $this->patientChannel,
                'Channel2' => $this->doctorChannel,
                'Tone' => true
            ]);

            // Send the action and get a promise for the response
            $promise = $this->sender->request($action);

            // Handle the response when it arrives
            $promise->then(function (Clue\React\Ami\Protocol\Response $response) {
                // Check if the channels were bridged successfully
                if ($response->getFieldValue('Response') == 'Success') {
                    // Call an web api and send status
                    $this->callWebApi('call_bridged');
                } else {
                    // Call an web api and send status
                    $this->callWebApi('bridge_failed');
                }
            });
        } catch (Exception $e) {
            // Handle any errors that may occur when sending the action
            echo 'Error: ' . $e->getMessage() . PHP_EOL;
        }
    }

    // Define the callWebApi method
    private function callWebApi($status) {
        // TODO: Implement this method to call an external web api and send the status of the call
        echo "Call status: " . $status . PHP_EOL;
    }
}

// Create a new SecureCall instance with some parameters
$secureCall = new SecureCall('1234567890', '0987654321', 60, 120);