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);