-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathfreepbx-click-to-call.php
113 lines (96 loc) · 4.19 KB
/
freepbx-click-to-call.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<?php
/**
* FreePBX Click-to-Call PHP Script
* Adapted from Alisson Pelizaro's version: https://github.com/alissonpelizaro/Asterisk-Click-to-Call
* Provides input validation, JSON results, and improved readability.
* Provides pjsip support and error handling.
* This script is intended to be used with FreePBX and Asterisk for click-to-call functionality.
*/
// Configuration settings
$config = [
'host' => '127.0.0.1',
'port' => 5038, // Default AMI port
'user' => 'admin', // AMI username
'secret' => 'MYSECRETPASS', // AMI password
'callerIdTemplate' => 'CTR Plugin (%s)',
'context' => 'from-internal',
'waitTime' => 30,
'priority' => 1,
'maxRetry' => 2,
];
// Retrieve and sanitize request parameters
$extension = isset($_REQUEST['exten']) ? trim($_REQUEST['exten']) : '';
$number = isset($_REQUEST['number']) ? trim(strtolower($_REQUEST['number'])) : '';
// Initialize result array
$result = [
'Success' => true,
'ValidInput' => true,
'Description' => '',
'Technology' => '',
'OriginateResponse' => '',
];
// Validate input parameters
if (!preg_match('/^\\+?[0-9]+$/', $number)) {
$result = setError($result, "Invalid number format: %s", $number);
}
if (!preg_match('/^[0-9]+$/', $extension)) {
$result = setError($result, "Invalid extension format: %s", $extension);
}
// Check if request is from a local IP address
if ($result['Success'] && filter_var($_SERVER["REMOTE_ADDR"], FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
$result = setError($result, "Unauthorized IP address: %s", $_SERVER["REMOTE_ADDR"]);
}
// Establish socket connection and authenticate
if ($result['Success']) {
$socket = stream_socket_client("tcp://{$config['host']}:{$config['port']}", $errno, $errstr);
if (!$socket) {
$result = setError($result, "Socket connection failed: %s (%s)", $errstr, $errno);
} else {
$authRequest = "Action: Login\r\nUsername: {$config['user']}\r\nSecret: {$config['secret']}\r\nEvents: off\r\n\r\n";
fwrite($socket, $authRequest);
usleep(200000);
$authResponse = fread($socket, 4096);
if (strpos($authResponse, 'Success') === false) {
$result = setError($result, "Authentication failed");
} else {
// Fetch technology from Asterisk extension database
$dbGetRequest = "Action: DBGet\r\nFamily: DEVICE\r\nKey: $extension/tech\r\n\r\n";
fwrite($socket, $dbGetRequest);
usleep(200000);
$dbGetResponse = fread($socket, 4096);
if (preg_match('/Val: (\w+)/', $dbGetResponse, $matches)) {
$tech = strtoupper($matches[1]);
$result['Technology'] = $tech; // Add technology to result JSON
} else {
$result = setError($result, "Failed to retrieve technology for extension: %s", $extension);
}
if ($result['Success']) {
// Originate call with retrieved technology
$originateRequest = "Action: Originate\r\nChannel: $tech/$extension\r\nWaitTime: {$config['waitTime']}\r\nCallerId: " . sprintf($config['callerIdTemplate'], $number) . "\r\nExten: $number\r\nContext: {$config['context']}\r\nPriority: {$config['priority']}\r\nAsync: yes\r\n\r\n";
fwrite($socket, $originateRequest);
usleep(200000);
$originateResponse = fread($socket, 4096);
$result['OriginateResponse'] = $originateResponse;
if (strpos($originateResponse, 'Success') !== false) {
$result['Description'] = "Extension $extension is calling $number.";
} else {
$result = setError($result, "Call initiation failed");
}
}
// Logoff
fwrite($socket, "Action: Logoff\r\n\r\n");
}
fclose($socket);
}
}
// Helper function to set error
function setError($result, $message, ...$args) {
$result['Success'] = false;
$result['ValidInput'] = false;
$result['Description'] = vsprintf($message, $args);
return $result;
}
// Output JSON result
header('Content-Type: application/json');
echo json_encode($result, JSON_PRETTY_PRINT);
?>