First running version
This commit is contained in:
commit
3e9e3cb9c7
|
@ -0,0 +1 @@
|
|||
config.php
|
|
@ -0,0 +1,13 @@
|
|||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar
|
||||
14 rue de Plaisance, 75014 Paris, France
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
// See README.md for asterisk ami configuration
|
||||
$ami_host = '127.0.0.1';
|
||||
$ami_port = '5038';
|
||||
$ami_user = 'user';
|
||||
$ami_pass = 'pass';
|
||||
|
||||
// Locales are in locale folder
|
||||
$lang = "en";
|
||||
|
||||
// Styles are in css folder
|
||||
$style = "gideonstar";
|
||||
|
||||
?>
|
|
@ -0,0 +1,59 @@
|
|||
:root {
|
||||
--red: #ff595e;
|
||||
--green: #8ac926;
|
||||
--yellow: #ffca3a;
|
||||
--blue: #1982c4;
|
||||
--purple: #6a4c93;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
background: black;
|
||||
color: white;
|
||||
font-family: Tahoma;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.offline {
|
||||
background: var(--red);
|
||||
}
|
||||
|
||||
.online {
|
||||
background: var(--green);
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: var(--yellow);
|
||||
font-size: 1.2em;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
list-style-type: none;
|
||||
margin-left: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
ul li.box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
margin: 2px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
|
||||
}
|
||||
|
||||
ul li:hover {
|
||||
outline: 1px solid white;
|
||||
font-size: 1.1em;
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
|
@ -0,0 +1,22 @@
|
|||
<?php include('config.php'); ?>
|
||||
<?php include('locale/' . $lang . '.php'); ?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de-de">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Asterisk Queue Manager</title>
|
||||
<link rel="stylesheet" href="css/<?php echo $style; ?>.css">
|
||||
<link rel="icon" type="image/png" href="img/favicon.png">
|
||||
<script src="js/app.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h2><?php echo $locale['phones']; ?>:</h2>
|
||||
<ul id="peers"></ul>
|
||||
|
||||
<h2><?php echo $locale['agents'] . ' ' . $locale['in_queue']; ?>:</h2>
|
||||
<ul id="queuemembers"></ul>
|
||||
|
||||
<h2><?php echo $locale['calls'] . ' ' . $locale['in_queue']; ?>:</h2>
|
||||
<ul id="queuecalls"></ul>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,117 @@
|
|||
var baseurl = (window.location.origin);
|
||||
|
||||
function get_data() {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', baseurl + '/php/ami_get.php', true);
|
||||
xhr.onreadystatechange = function() {
|
||||
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
|
||||
var response = JSON.parse(xhr.responseText);
|
||||
|
||||
//
|
||||
// SIPpeers
|
||||
//
|
||||
|
||||
var sippeers = response.sippeers;
|
||||
var dom_sippeers = document.getElementById('peers');
|
||||
|
||||
// Clear ul
|
||||
dom_sippeers.innerHTML = '';
|
||||
|
||||
for(var item in sippeers) {
|
||||
|
||||
// Create li
|
||||
var node = document.createElement('li');
|
||||
|
||||
// Add online or offline class
|
||||
if(sippeers[item] == '0') {
|
||||
node.classList.add('offline');
|
||||
}
|
||||
if(sippeers[item] == '1') {
|
||||
node.classList.add('online');
|
||||
}
|
||||
|
||||
// It's a box
|
||||
node.classList.add('box');
|
||||
|
||||
// Add text
|
||||
var text = document.createTextNode(item);
|
||||
node.appendChild(text);
|
||||
|
||||
// Add attributes
|
||||
node.setAttribute('section', 'sippeers');
|
||||
node.setAttribute('value', item);
|
||||
|
||||
// Make it clickable
|
||||
node.addEventListener('click', function() {
|
||||
var section = this.getAttribute('section');
|
||||
var value = this.getAttribute('value');
|
||||
|
||||
ami_set(section, value);
|
||||
});
|
||||
|
||||
// Add li to ul
|
||||
dom_sippeers.appendChild(node);
|
||||
}
|
||||
|
||||
//
|
||||
// QueueMembers
|
||||
//
|
||||
|
||||
var queuemembers = response.queuemembers;
|
||||
var dom_queuemembers = document.getElementById('queuemembers');
|
||||
|
||||
// Clear ul
|
||||
dom_queuemembers.innerHTML = '';
|
||||
|
||||
// Asterisk sorts the members the wrong way round
|
||||
queuemembers.reverse();
|
||||
|
||||
for(var item in queuemembers) {
|
||||
|
||||
// Create li
|
||||
var node = document.createElement('li');
|
||||
|
||||
// Queue members are always green (TODO: really?)
|
||||
node.classList.add('online');
|
||||
|
||||
// It's a box
|
||||
node.classList.add('box');
|
||||
|
||||
// Add text
|
||||
var text = document.createTextNode(queuemembers[item]);
|
||||
node.appendChild(text);
|
||||
|
||||
// Add attributes
|
||||
node.setAttribute('section', 'queuemembers');
|
||||
node.setAttribute('value', queuemembers[item]);
|
||||
|
||||
// Make it clickable
|
||||
node.addEventListener('click', function() {
|
||||
var section = this.getAttribute('section');
|
||||
var value = this.getAttribute('value');
|
||||
|
||||
ami_set(section, value);
|
||||
});
|
||||
|
||||
// Add li to ul
|
||||
dom_queuemembers.appendChild(node);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
function ami_set(section, value) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', baseurl + '/php/ami_set.php?s=' + section + '&v=' + value, true);
|
||||
xhr.send(null);
|
||||
get_data();
|
||||
}
|
||||
|
||||
// Run it once, because setInterval executes it _after_ the delay
|
||||
get_data();
|
||||
|
||||
// Run every second
|
||||
setInterval(get_data, 1000);
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
$locale = [
|
||||
'phones' => 'Telefone',
|
||||
'agent' => 'Agent',
|
||||
'agents' => 'Agenten',
|
||||
'call' => 'Anruf',
|
||||
'calls' => 'Anrufe',
|
||||
'in_queue' => 'in der Warteschlange'
|
||||
];
|
||||
|
||||
?>
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
$locale = [
|
||||
'phones' => 'Phones',
|
||||
'agent' => 'Agent',
|
||||
'agents' => 'Agents',
|
||||
'call' => 'Call',
|
||||
'calls' => 'Calls',
|
||||
'in_queue' => 'in Queue'
|
||||
];
|
||||
|
||||
?>
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
include('../config.php');
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
// Open socket to ami server
|
||||
$socket = fsockopen($ami_host, $ami_port);
|
||||
|
||||
// Login
|
||||
fputs($socket, "Action: Login\r\n");
|
||||
fputs($socket, "UserName: " . $ami_user . "\r\n");
|
||||
fputs($socket, "Secret: " . $ami_pass . "\r\n\r\n");
|
||||
|
||||
//
|
||||
// Action: SIPpeers -> $sippeers
|
||||
//
|
||||
|
||||
$sippeers = [];
|
||||
$extension = '';
|
||||
$extension_status = 0;
|
||||
|
||||
fputs($socket, "Action: SIPpeers\r\n\r\n");
|
||||
while(($data = fgets($socket, 8096)) != "Event: PeerlistComplete\r\n") {
|
||||
$pattern_extension = '/^ObjectName:\s(\d\d\d).*$/';
|
||||
if(preg_match_all($pattern_extension, $data, $match)) {
|
||||
$extension = $match[1][0];
|
||||
}
|
||||
|
||||
$pattern_ipaddress = '/^IPaddress.*$/';
|
||||
if(preg_match($pattern_ipaddress, $data)) {
|
||||
$pattern_onlinestatus = '/^IPaddress:\s(-none-).*$/';
|
||||
if(preg_match_all($pattern_onlinestatus, $data, $match)) {
|
||||
$extension_status = '0';
|
||||
} else {
|
||||
$extension_status = '1';
|
||||
}
|
||||
|
||||
$sippeers[$extension] = $extension_status;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Action: QueueStatus -> $queuemembers
|
||||
//
|
||||
// TODO: Status: x
|
||||
// 2 In Use
|
||||
// 6 Ringing
|
||||
|
||||
$queuemembers = [];
|
||||
|
||||
fputs($socket, "Action: QueueStatus\r\n");
|
||||
fputs($socket, "Queue: warteschlange\r\n\r\n");
|
||||
while(($data = fgets($socket, 8096)) != "Event: QueueStatusComplete\r\n") {
|
||||
$pattern_name = '/^Name.*$/';
|
||||
if(preg_match($pattern_name, $data)) {
|
||||
$pattern_extension = '/^Name:\sSIP\/(\d\d\d).*$/';
|
||||
if(preg_match_all($pattern_extension, $data, $match)) {
|
||||
array_push($queuemembers, $match[1][0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close socket
|
||||
fclose($socket);
|
||||
|
||||
//
|
||||
// Create JSON data package
|
||||
//
|
||||
|
||||
echo json_encode(
|
||||
array(
|
||||
'sippeers' => $sippeers,
|
||||
'queuemembers' => $queuemembers,
|
||||
),
|
||||
);
|
||||
|
||||
?>
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
include('../config.php');
|
||||
|
||||
// Read GET data
|
||||
|
||||
$section = $_GET['s'];
|
||||
$value = $_GET['v'];
|
||||
|
||||
// Open socket to ami server
|
||||
|
||||
$socket = fsockopen($ami_host, $ami_port);
|
||||
|
||||
// Login
|
||||
|
||||
fputs($socket, "Action: Login\r\n");
|
||||
fputs($socket, 'UserName: ' . $ami_user . "\r\n");
|
||||
fputs($socket, 'Secret: ' . $ami_pass . "\r\n\r\n");
|
||||
|
||||
//
|
||||
// Section: sippeers
|
||||
//
|
||||
|
||||
if($section == 'sippeers') {
|
||||
fputs($socket, "Action: QueueAdd\r\n");
|
||||
fputs($socket, 'Interface: SIP/' . $value . "\r\n");
|
||||
fputs($socket, "Queue: warteschlange\r\n\r\n");
|
||||
}
|
||||
|
||||
//
|
||||
// Section: queuemembers
|
||||
//
|
||||
|
||||
if($section == 'queuemembers') {
|
||||
fputs($socket, "Action: QueueRemove\r\n");
|
||||
fputs($socket, 'Interface: SIP/' . $value . "\r\n");
|
||||
fputs($socket, "Queue: warteschlange\r\n\r\n");
|
||||
}
|
||||
|
||||
// It seems that it needs some time to execute
|
||||
sleep(1);
|
||||
|
||||
// Close socket
|
||||
fclose($socket);
|
||||
|
||||
?>
|
Loading…
Reference in New Issue