ARI Stasis

Обсуждаем, спрашиваем, помогаем в настройке VoIP

ARI Stasis

Сообщение dimondack » 14 ноя 2019, 11:45

Написал свой обработчик Dialer.
Сначала писал для браузера, а потом понял что такой функционал должен работать на сервере.

Проверял на локальных звонках и from trunk.

..............
Звонок из транка
прилетает сообщение

Код: Выделить всё
 
{"type":"StasisStart","timestamp":"2019-11-10T07:24:50.448+0300","args":[],"channel":{"id":"1573359889.6562","name":"SIP/rtk1-000002fd","state":"Up","caller":{"name":"81237894526","number":"+71237894526"},"connected":{"name":"","number":""},"accountcode":"","dialplan":{"context":"rtk1","exten":"1703","priority":3},"creationtime":"2019-11-10T07:24:49.941+0300","language":"ru"},"asterisk_id":"00:24:54:2a:e1:27","application":"dialer"}


и как было бы хорошо что б этот "id":"1573359889.6562" канала А
я бы сам назначал.... , как я это делаю с номером канала В и номером бриджа

Это позволило бы избежать циклов и не перебирать элементы класса...


Вот контекст
Код: Выделить всё
[local-or-from-trunk]
exten => _X.,1,Noop('*********************')
same  => n,Noop(****** ${CHANNEL} ****** )
same  => n,Answer()
same  => n,Stasis(dialer)
same  => n,HangUp()

exten => 123,1,Noop('*********TEST  PLAY************')
same  => n,Noop(****** ${CHANNEL} ****** )
same  => n,Answer()
same  => n,Stasis(dialer)
same  => n,HangUp()

exten => 444,1,Noop('**********TEST STOP*******')
same  => n,Noop(****** ${CHANNEL} ****** )
same  => n,Answer()
same  => n,Stasis(dialer)
same  => n,HangUp()


..............
А вот дальше буду думать как в браузер события выводить.
Может свой CRM получиться..


Спасибо
Помог Ваш пример и статья
https://github.com/subnetsRU/asterisk/tree/master/conference
http://subnets.ru/blog/?p=5416

Ну и интернет конечно.
Вложения
dialer.zip
Dialer
(286.56 Кб) Скачиваний: 2301
Нас определяет то, что мы делаем.
Аватара пользователя
dimondack
посетитель
 
Сообщения: 104
Зарегистрирован: 21 янв 2015, 13:00

Re: ARI Stasis

Сообщение dimondack » 29 ноя 2019, 16:44

Почти получилось.
.......

код оператора 'SIP/1703'
Код: Выделить всё
  const CHAR_RETURN = 13;
  const socket = new WebSocket('ws://192.168.88.25:9088');
  const oper = 'SIP/1703';
 
/*
  const writeLine = text => {
    const line = document.createElement('div');
    line.innerHTML = `<p>${text}</p>`;
  };
*/
  socket.onopen = () => {
    writeLine('connected');
   var x = JSON.stringify( { type: 'Reg', number:oper});
   socket.send(x);
  };

  socket.onclose = () => {
    writeLine('closed');
  };

var pic_answer = 'images/answer_green.gif';
var pic_ring = 'images/ring_blue.gif';
var pic_wait = 'images/wait_call.gif';

  socket.onmessage = event => {
     var m=JSON.parse(event.data);
   
   switch(m.showcase){
   
   case 'StasisStart':
   if(document.getElementById(m.bridge_number) != null){break;}
   
   sshow_ticket(m,pic_ring);

   break;
   
   case 'Dial_RING':
   break;
   
   case 'Playback_Wait':
   
   break;
   
   case 'Dial_ANSWER':
   
if(document.getElementById(m.bridge_number) == null){
   sshow_ticket(m,pic_answer);
   var tabl3 =document.getElementById('tabl3' + m.bridge_number);
    cells = tabl3.getElementsByTagName('td');
   cells[1].innerHTML='<img class="image_answer" id="image_answer_' + m.bridge_number +  '" onclick="del_ch(this.id)" src="' + pic_answer +'" />';
   
   break;}
      
         if(oper == m.endp_tech){
   
   var tabl3 =document.getElementById('tabl3' + m.bridge_number);
    cells = tabl3.getElementsByTagName('td');
   cells[1].innerHTML='<img class="image_answer" id="image_answer_' + m.bridge_number +  '" onclick="del_ch(this.id)" src="' + pic_answer +'" />';
   
   }else{
   $('#' + m.bridge_number).remove();
   }

   break;
   
   case 'ChannelHangupRequest': $('#' + m.bridge_number).remove(); break;
   
   case 'Dial_BUSY':  $('#' + m.bridge_number).remove();   break;
   default:
   };
   
  };

/////////////////////////////////////////
/////////////////////////////////////////

function come2me_ch(click_id){
  var arr = click_id.split('_');
   var x = +arr[2] + 1000;
     var x;
if(arr[1] == 'playback' ){x = JSON.stringify( { type: 'Come2me', bridge_id: arr[2], channel_id: x,number_oper:oper});}
        
socket.send(x);

}
//////////////////////////////////

function del_ch(click_id){
   
     var arr = click_id.split('_');
   
   var x = +arr[2] + 1000;
   
     var x;
if(arr[1] == 'answer' ){x = JSON.stringify( { type: 'HangUp', bridge_id: arr[2], channel_id: x,number_oper:oper});}
          
socket.send(x);
   
}


//////////////////////////////////
function sshow_ticket(m, img){
   
//var ext_btn_play = document.createElement('button');
//   var ext_btn_redirect= document.createElement('button');
   

   var fieldset = document.createElement('fieldset');


   fieldset.setAttribute( "id", m.bridge_number);
    fieldset.setAttribute( "class", "field_set");

   fieldset.appendChild(create_new3_Table(m,img));
   
   
   var legend = document.createElement('LEGEND');
   var txt_legend = document.createTextNode(m.bridge_number);
    legend.setAttribute( "id", m.bridge_number);
   legend.setAttribute( "name", m.bridge_number);
    legend.setAttribute( "class", m.bridge_number);
   legend.appendChild(txt_legend);
   
   fieldset.appendChild(legend);
   document.getElementById('monitor').appendChild(fieldset);
   
   var div = document.createElement('div');
   document.getElementById('monitor').appendChild(div);

};

function create_new3_Table(m, img) {
//&nbsp;&nbsp;   

var div = document.createElement('div');
div.setAttribute("id", 'tabl3' + m.bridge_number);
div.innerHTML = '<table><tr>' +
'<td class="td_client">' +
'<label class="lbl_client">ФИО</label>' + '&nbsp' + '&nbsp' + '&nbsp' +
'<input class="data_client" type="textfield" size="45" value="' + m.client_info[0].name + '">' + '<br>' +
'<label class="lbl_client">Организация</label>' + '&nbsp' + '&nbsp' + '&nbsp' +
'<input class="data_client" type="textfield" size="45" value="' + m.client_info[0].organization +'">' +  '<br>' +
'<label class="lbl_client">Телефон</label>' + '&nbsp' + '&nbsp' + '&nbsp' +
'<input class="data_client" type="textfield" size="45" value="' + m.client_info[0].telephone_number_1 + '">' +   '<br>' +
'<label class="lbl_client">Мобильный</label>' + '&nbsp' + '&nbsp' + '&nbsp' +
'<input class="data_client" type="textfield" size="45" value="' + m.client_info[0].telephone_mobile_1 + '">' +   '<br>' +
'<label class="lbl_client">E-mail</label>' + '&nbsp' + '&nbsp' + '&nbsp' +
'<input class="data_client" type="textfield" size="45" value="' + m.client_info[0].e_mail + '">' +   '<br>' +
'<label class="lbl_client">Контакты</label>' + '&nbsp' + '&nbsp' + '&nbsp' +
'<input class="data_client" type="textfield" size="45" value="' + m.client_info[0].contacts + '">' +   '<br>' +
'<label class="lbl_client">Сделка</label>' + '&nbsp' + '&nbsp' + '&nbsp' +
'<input class="data_client" type="textfield" size="45" value="' + m.client_info[0].case_1 + '">' +   '<br>' +
'<label class="lbl_client">Сделка</label>' + '&nbsp' + '&nbsp' + '&nbsp' +
'<input class="data_client" type="textfield" size="45" value="' + m.client_info[0].case_2 + '">' +    '<br>' +
'<label class="lbl_client">Сделка</label>' + '&nbsp' + '&nbsp' + '&nbsp' +
'<input class="data_client" type="textfield" size="45" value="' + m.client_info[0].case_3 + '">' +    '<br>' +
'<label class="lbl_client">Доп</label>' + '&nbsp' + '&nbsp' + '&nbsp' +
'<input class="data_client" type="textfield" size="45" value="Всё о фильме: дата выхода, трейлеры, фото, актеры">' +    '<br>' +
'<label class="lbl_client">Доп</label>' + '&nbsp' + '&nbsp' + '&nbsp' +
'<input class="data_client" type="textfield" size="45" value="Всё о фильме: дата выхода, трейлеры, фото, актеры">' +    '<br>' +
'<label class="lbl_client">Доп</label>' + '&nbsp' + '&nbsp' + '&nbsp' +
'<input class="data_client" type="textfield" size="45" value="Всё о фильме: дата выхода, трейлеры, фото, актеры">' +    '<br>' +
'</td>' +
'<td id="image_pic_to_a_"' + m.bridge_number + '"><img class="img_ring"  id="image_playback_' + m.bridge_number +  '"  onclick="come2me_ch(this.id)"  src="'+ img + '"/></td>' +
'<td><img class="img_a" src="' + m.client_info[0].photo  +'"/></td>' +
'</tr></table>';
   return   document.body.appendChild(div);

}


function cr_btn(){
   /*
   start
   stop
   restart
   pause
   unpause
   forward
   reverse
   */
}



Потешная таблица
Код: Выделить всё
CREATE TABLE `info_clients` (
  `data_create` datetime DEFAULT CURRENT_TIMESTAMP,
  `data_modified` datetime DEFAULT CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  `name` varchar(80) DEFAULT NULL,
  `organization` varchar(80) DEFAULT NULL,
  `telephone_number_1` varchar(80) DEFAULT NULL,
  `telephone_mobile_1` varchar(80) DEFAULT NULL,
  `e_mail` varchar(80) DEFAULT NULL,
  `contacts` varchar(80) DEFAULT NULL,
  `case_1` varchar(80) DEFAULT NULL,
  `case_2` varchar(80) DEFAULT NULL,
  `case_3` varchar(80) DEFAULT NULL,
  `photo` varchar(80) DEFAULT NULL,
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Вложения
ws.jpg
1
Нас определяет то, что мы делаем.
Аватара пользователя
dimondack
посетитель
 
Сообщения: 104
Зарегистрирован: 21 янв 2015, 13:00

Re: ARI Stasis

Сообщение dimondack » 05 дек 2019, 13:14

Вот еще интересная возможность
пропускать входящий звонок из транка через Stasis
Код: Выделить всё
'000' =>         1. Noop(****CRM******)                    [extensions.conf:164]
                    2. Answer()                                   [extensions.conf:165]
                    3. Stasis(dialer)                             [extensions.conf:166]
                    4. HangUp()                                   [extensions.conf:167]



таблица в базе
Код: Выделить всё
CREATE TABLE `service_opers` (
  `data_create` datetime DEFAULT CURRENT_TIMESTAMP,
  `data_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `oper` varchar(80) DEFAULT NULL,
  `await_calling_number` varchar(80) DEFAULT NULL,
  `uncon_forward` text,
  `busy_forward` text,
  `timeout_forward` text
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



Если в базе нашелся номер сотрудника то ${exten} = 'users',result[0].oper
отправляем в контекст 'users',
continue_d(ticket_stasis[rnd].ch_a,'users',result[0].oper,' ',' ');

если нет, то дальше.... ,
а у меня пока на playback 1000
continue_d(ticket_stasis[rnd].ch_a,'users','1000','','');


сам скрипт
Код: Выделить всё
#!/usr/bin/env node

var ARI_HOST = '127.0.0.1';
var ARI_PORT = '8088';
var API_KEY = 'ariuser'+':'+ '123';
var APP_NAME = 'dialer';
var CONTEXT = 'users';
var TIMER = '30';
var FORMAT = 'alaw,ulaw';
var MEDIA = 'sound:paul_m';
//var MEDIA = 'sound:sh_11';
var MEDIA = 'sound:paul_bangles';
var SKIPMS = '3000';
var MIN =2000;
var MAX =2999;



var mysql = require('mysql');
var conn = mysql.createConnection({
host:'localhost',
port: '3306',
user:'crm',
password:'crm',
database:'crm',
charset: 'utf8'
});


 conn.connect(function(err){
    if (err) {
      return console.error("Ошибка: " + err.message);
    }
    else{
      console.log("Подключение к серверу MySQL успешно установлено");
    }
 });



var WebSocket = require('ws');
var WebSocketServer = require('ws').Server;
var request = require('request');
var ws = new WebSocket( 'ws://' + ARI_HOST + ':' + ARI_PORT + '/ari/events?app=' + APP_NAME + '&api_key=' + API_KEY );
var wss;
var moh_chan;



var uid ={};
var rnd ;
var ep;

var tmp;
var ticket_stasis = []; // объявление массива



class Ticket_Stasis{
 //var trunk = new Array();   
 constructor(channel_id_b,channel_id_a,channel_name_a,calling_name,calling_number,called_number,trunk) {
 this.bridge_number = channel_id_b - 1000;
 this.channel_id_a  = channel_id_a;
 this.channel_name_a = channel_name_a;
 this.calling_name =  calling_name;
 this.calling_number = calling_number
 this.channel_id_b = channel_id_b;
 this.called_number = called_number;
 this.endp_tech =null;
 this.playback_channel_id_a = channel_id_b + 4000;
 this.playback_channel_id_b = channel_id_b + 7000;
 this.snoop_channel_id_a = channel_id_b + 1000;
 this.snoop_channel_id_b = channel_id_b + 2000;
 this.ring_kpv_to_a =true;
 this.ring_kpv_to_b =false;
 this.hangup_from_a = false; // On
 this.hangup_from_b = true;  // Off
 this.ticket_state = true; 
 this.trunk  = trunk;
 this.count_trying = 0;
 this.client_info ='';
 this.showcase = 'StasisStart';
 }

 get trunks()   { return `${this.trunk}`;  }
 get ui()   {    return `${this.bridge_number}`;  }
 get ch_a() {    return `${this.channel_id_a}`;  }
 get ch_b() {    return `${this.channel_id_b}`;  }
 get playback_ch_a() {    return `${this.playback_channel_id_a}`;  }
 get playback_ch_b() {    return `${this.playback_channel_id_b}`;  }
 get snoop_ch_a() {    return `${this.snoop_channel_id_a}`;  }
 get snoop_ch_b() {    return `${this.snoop_channel_id_b}`;  }
 
 get cdn () {    return `${this.called_number}`;  }
 get cgn () {    return `${this.calling_number}`;  }

 get ring_kpv_goto_a () {    return `${this.ring_kpv_to_a}`;  }
 get ring_kpv_goto_b () {    return `${this.ring_kpv_to_b}`;  }
 get hangup_status_a () {    return `${this.hangup_from_a}`;  }
 get hangup_status_b () {    return `${this.hangup_from_b}`;  }
 get ticket_status()    {    return `${this.ticket_state}`;  }
 get info() { return `${this.client_info}`;  }           
 get show_case()    {    return `${this.showcase}`;  }
 get cnt_try() {    return `${this.count_trying}`;   }
 get ep() {    return `${this.endp_tech}`;   }
 
 
 set ep(v) {   this.endp_tech = v;   }
 set cnt_try(v) {   this.count_trying = v;   }
 set trunks(v)   { this.trunk = v; }
 set ch_a(v) { this.channel_id_a = v; }
 set ch_b(v) { this.channel_id_b = v; }
 set ring_kpv_goto_a (v) {    this.ring_kpv_to_a = v; }
 set ring_kpv_goto_b (v) {    this.ring_kpv_to_b = v; }
 set hangup_status_a (v) {  this.hangup_from_a = v; }
 set hangup_status_b (v) {  this.hangup_from_b = v; }
 set ticket_status (v)   {  this.ticket_state=v; }
 set info(v)    {      this.client_info=v;  }
 set show_case(v)    {    this.showcase=v;  }

}



//////////////////////////
// обработчик входящих сообщений Asterisk
ws.on('open',function(){console.log('Connected to ARI');});
ws.on('error',function(e){console.log('ARI Connection error:',e);});
ws.on('message',function(d,flags){
  var str = JSON.parse(d);
  var ep;

////////////////////////////////// 
//console.log(str);
////////////////////////////////
switch(str.type)
{
   
   
   case "StasisStart":
//console.log(str);
   console.log('Stasis  start - Dialer');
   if(str.channel.dialplan.exten == ""){break;}
   
rnd = get_uid();
   
ticket_stasis[rnd] = new Ticket_Stasis(rnd,str.channel.id,str.channel.name,str.channel.caller.name,str.channel.caller.number,str.channel.dialplan.exten,str.args);
//   show_ticket(rnd);
ticket_stasis[rnd].show_case='StasisStart';
plus_bridge(ticket_stasis[rnd].ui);
plus_ch_to_bridge(ticket_stasis[rnd].ui,str.channel.id)
/////////////////////req service opers
var cgn =ticket_stasis[rnd].cgn;
if(cgn.startsWith('+')){
cgn=cgn.subString(1,cgn.length);}

var n = "'";
var n1 =n + '%' + cgn + '%' + n;

conn.query('SELECT *  FROM service_opers where await_calling_number like' + n1

,function(error, result, fields){
//console.log(result[0].oper);

if(result != ''){
console.log(result[0].oper);
ticket_stasis[rnd].show_case='StasisEnd';
continue_d(ticket_stasis[rnd].ch_a,'users',result[0].oper,'','');
//delete ticket_stasis[rnd];
}else{

ticket_stasis[rnd].show_case='StasisEnd';
continue_d(ticket_stasis[rnd].ch_a,'users','1000','','');
//delete ticket_stasis[rnd];

}

});

/////////////////////////////END Mysql
      break;
   
      
    case "ChannelHangupRequest":
//    console.log(str);
ticket_stasis.some(function(item, index, array) {

if(ticket_stasis[index].ch_a == 'timeout' ){
minus_bridge (ticket_stasis[index].ui);
//ticket_stasis[index].ticket_status=false;
//ticket_stasis[index].show_case='ChannelHangupRequest';
//wss.broadcast(JSON.stringify(ticket_stasis[index]));
delete ticket_stasis[index];
return;
 }

if(ticket_stasis[index].ch_a == str.channel.id ){
//console.log('From A');
if(ticket_stasis[index].show_case != 'StasisStart'){
minus_ch(ticket_stasis[index].ch_b,'normal');}
minus_bridge (ticket_stasis[index].ui);
//ticket_stasis[index].ticket_status=false;
ticket_stasis[index].show_case='ChannelHangupRequest';
//wss.broadcast(JSON.stringify(ticket_stasis[index]));
delete ticket_stasis[index];
return;
}
//------------------------
if(ticket_stasis[index].ch_b == str.channel.id){
//if(ticket_stasis[index].ch_a!=null){}
minus_ch(ticket_stasis[index].ch_a,'normal');
minus_bridge (ticket_stasis[index].ui);
//ticket_stasis[index].ticket_status=false;
ticket_stasis[index].show_case='ChannelHangupRequest';
//wss.broadcast(JSON.stringify(ticket_stasis[index]));
delete ticket_stasis[index];
return;
}

})

break;

case   "ChannelLeftBridge":break;
 
case "ChannelDestroyed":
break;

case "PlaybackStarted":break;

case "PlaybackFinished":break;

case "StasisEnd":
ticket_stasis.some(function(item, index, array) {

if(ticket_stasis[index].show_case == 'StasisEnd'){
minus_bridge(ticket_stasis[index].ui);
delete ticket_stasis[index];
}

});

break;

case "ChannelUserevent"://console.log(str);
break;


    default:  // console.log(str);      //




//////////////////////////////
}// end switch case
///////////////////////////////
}); //ws end ws.onmessage
ws.on('error',function(e){console.log('ARI Connection error:',e);});

//////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////

function get_uid(){
 var rnd2 = Math.floor(MIN + Math.random()*(MAX + 1 - MIN));

//console.log("LEN ticket array: ",ticket_stasis.length);
let cnt = 0;
let i =45;
while(i){
 
ticket_stasis.forEach((element, index, array) => {
if(ticket_stasis[index].ch_b == rnd2){cnt = cnt + 1;}

//cnt = cnt + 1; 

})

if(cnt == 0 ){rnd=rnd2; i=0;}
else{cnt=0;rnd2 = Math.floor(MIN + Math.random()*(MAX + 1 - MIN));}
}


//console.log("unicum == ",rnd );
rnd = rnd2;
return rnd2;
};



function continue_d(ch,cntxt,ep,pr,lbl){
var url;
url = 'http://' + ARI_HOST + ':' + ARI_PORT;
url = url + '/ari/channels/' + ch + '/continue?context=' + cntxt;
request.post( url,
{form: {
'extension': ep,
'priority':pr,
'label': lbl,
'api_key': API_KEY, }}
,function (error, response, body) {
            if (!error) {
                console.log( 'Create_continue  Response Code:', response.statusCode );
                console.log( 'Create_continue : ', ep );
                }
            }
)
}



function  plus_bridge (brd){
//console.log('plus bridge');
request.post(
    'http://' + ARI_HOST + ':' + ARI_PORT + '/ari/bridges/' + brd,
            {
                form: {
                type: 'mixing',
                name: brd,
                'api_key': API_KEY,
                }
            },
            function (error, response, body) {
                if ( !error) {
        //      if ( !error && response.statusCode == 200) {
//              console.log( 'stasis start. WS on message: ', b, ': ', response.statusCode );
                console.log( 'Create Bridge  Response code: ',':', response.statusCode );
                console.log( 'Create Bridge: ', brd);
                }
        //      moh_manage( data );
            }
        );

};

function  minus_bridge (brd){

request.del(
                'http://' + ARI_HOST + ':' + ARI_PORT + '/ari/bridges/' + brd,
                {
                    form: {
                    'api_key': API_KEY,
                    },
                },
                function (error, response, body) {
                            if (!error) {
                            //if (!error && response.statusCode != 204) {

//              console.log( ' WS on message: ', b, ': ', response.statusCode );
                                console.log('Delete Bridge Response code: ', response.statusCode);
                                console.log('Delete Bridge : ', brd);

                            }
                }
            );



// var url = 'http://' + ARI_HOST + ':' + ARI_PORT + '/ari/bridges/' +  b + '?api_key=' + API_KEY;

};


function  plus_ch_to_bridge (brd, ch){

//console.log('plus ch to bridge',brd,'channel ', ch);
request.post(
    'http://' + ARI_HOST + ':' + ARI_PORT + '/ari/bridges/' + brd + '/addChannel?channel=' + ch,
            {
                form: {
//                   channel: ch,
                    'api_key': API_KEY,
                }
            },
            function (error, response, body) {
                if (!error &&  response.statusCode != 200) {
//              console.log( 'stasis start. WS on message: ', b, ': ', response.statusCode );
                console.log( 'Add channel to Bridge Response code: ', response.statusCode );
                console.log( 'Add channel to Bridge: ', ch, 'To' , brd)
                }
        //      moh_manage( data );
            }
        );

};



function  minus_ch_from_bridge (brd, ch){

// var url = 'http://' + ARI_HOST + ':' + ARI_PORT + '/ari/bridges?bridgeId=' + BRIDGE_ID + '&api_key=' + API_KEY;
// http://192.168.88.25:8088/ari/bridges/1451451451/addChannel?channel=ХХХ_IN_ХХХХХ.ХХХ&api_key=ariuser:123
//http://192.168.88.25:8088/ari/bridges/1451451451/removeChannel?channel=1571734363.523&api_key=ariuser:123


request.del(
 'http://' + ARI_HOST + ':' + ARI_PORT + '/ari/bridges/' + brd + '/removeChannel?channel=' + ch,
                {
                    form: {
                    'api_key': API_KEY,
                    },
                },
                function (error, response, body) {
                            if (!error && response.statusCode != 204) {

//              console.log( ' WS on message: ', b, ': ', response.statusCode );
                                console.log('Delete channel from Bridge  Response code : ', response.statusCode);
                                console.log('Delete channel:', ch, ' from Bridge : ', brd);

                            }
                }
            );


// var url = 'http://' + ARI_HOST + ':' + ARI_PORT + '/ari/bridges/' + b + '/removeChannel?channel=' + ch + '&api_key=' + API_KEY;


};






вот index 'смотрелки' в базу
Код: Выделить всё
<!doctype html>
<html>
<head>
<title>Start</title>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="keywords" content="">
<meta name="description" content="">
<meta name="msapplication-TileImage" content="img/logo.png">


<link rel="apple-touch-icon" sizes="192x192" href="img/logo.png">
<link rel="icon" type="image/png" sizes="192x192" href="img/logo.png">

<link rel="stylesheet" href="css/style.css" type="text/css">
</head>
<script  type="text/javascript" src="js/jquery-3.4.1.js"></script>

<form method="post" enctype="application/x-www-form-urlencoded" action="index.php">
<br>
<fieldset class="field_set">
<legend class="title"> Перевод звонка на оператора  </legend>
<table width="100%">
<tr>
   <th>&nbsp;</th>
   <th>&nbsp;</th>
   <th>&nbsp;</th>
</tr>



<tr>
<td>
<label>
&nbsp;&nbsp;Номер клиента</label>
</td>

<td>
<input class="margin-left0" type="text" name="client" id="client" size="24">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<label>Перевод на </label>
<input class="margin-left0" type="text" name="oper" id="oper" size="10">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<?php

print '<input type="checkbox" name="oper" size="50" id="jbtn" value="oper"   onchange="cl_btn()"> ';
 

print '<button id="form_submit" class="btn" value="" >';
print '<div id="txt_btn">Записать</div>';
print '</button>';
?>

</td>



</tr>

</table>

</fieldset>
<script  type="text/javascript">
function cl_btn(){
var orig = '<div id="txt_btn">Записать</div>';
var w = '<label id="wr">Записать</label>';
var d = '<label id="dlt" >Удалить</label>';
var dd = '<div id="txt_btn">Удалить</div>';
if ($('#jbtn').is(':checked')){
         $('#txt_btn').replaceWith(dd);
} else {

//$('#dlt').replaceWith(orig);
$('#txt_btn').replaceWith(orig);
}

}


</script>

<?php



include("./func/f_cdr.php");


isset($_POST['oper']); 

//if($p){

$oper = $_POST["oper"];
$len_oper = strlen($oper);


$client =$_POST["client"];
$len_client = strlen($client);

if(isset($_POST['oper']) && $_POST['oper']== 'oper') {
//echo  '+++++++++'.$p;
uregsqli("service_opers",$client,$oper,'1');
}else{
//if($len_oper==0 && $len_client){ }
uregsqli("service_opers",$client,$oper,'0');
}

/


?>

</form>
</html>
Нас определяет то, что мы делаем.
Аватара пользователя
dimondack
посетитель
 
Сообщения: 104
Зарегистрирован: 21 янв 2015, 13:00

Re: ARI Stasis

Сообщение dimondack » 05 дек 2019, 16:31

...
Вложения
451.zip
(286.52 Кб) Скачиваний: 2339
Нас определяет то, что мы делаем.
Аватара пользователя
dimondack
посетитель
 
Сообщения: 104
Зарегистрирован: 21 янв 2015, 13:00

Re: ARI Stasis

Сообщение dimondack » 09 дек 2019, 19:16

Так интереснее будет


index
Код: Выделить всё
<!doctype html>
<html>
<head>
<title>Start</title>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="keywords" content="">
<meta name="description" content="">
<meta name="msapplication-TileImage" content="img/logo.png">


<link rel="apple-touch-icon" sizes="192x192" href="img/logo.png">
<link rel="icon" type="image/png" sizes="192x192" href="img/logo.png">

<link rel="stylesheet" href="css/style.css" type="text/css">
</head>
<script  type="text/javascript" src="js/jquery-3.4.1.js"></script>

<form method="post" enctype="application/x-www-form-urlencoded" action="index.php">
<br>
<fieldset class="field_set">
<legend class="title"> Перевод звонка на оператора  </legend>
<table width="100%">
<tr>
   <th>&nbsp;</th>
   <th>&nbsp;</th>
   <th>&nbsp;</th>
</tr>



<tr>
<td>
<label>
&nbsp;&nbsp;Номер клиента</label>
</td>

<td>
<input class="margin-left0" type="text" name="client" id="client" size="24">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<label>Перевод на </label>
<input class="margin-left0" type="text" name="oper" id="oper" size="10">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<?php



print '<button id="form_submit" class="btn" value="" >';
print '<div id="txt_btn">Записать</div>';
print '</button>';
echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
print '<input type="checkbox" name="chk" size="50" id="jbtn" value="chk"   onchange="cl_btn()"> ';

?>

</td>



</tr>

</table>

</fieldset>
<script  type="text/javascript">
function cl_btn(){
var orig = '<div id="txt_btn">Записать</div>';
var w = '<label id="wr">Записать</label>';
var d = '<label id="dlt" >Удалить</label>';
var dd = '<div id="txt_btn">Очистить таблицу</div>';
if ($('#jbtn').is(':checked')){
         $('#txt_btn').replaceWith(dd);
         $('.chkt').attr('checked',false);

} else {

//$('#dlt').replaceWith(orig);
$('#txt_btn').replaceWith(orig);
}

}

function del_rec(chkb){
var orig = '<div id="txt_btn">Записать</div>';
var w = '<label id="wr">Записать</label>';
var d = '<label id="dlt" >Удалить</label>';
var dd = '<div id="txt_btn">Удалить запись</div>';
if ($('#' + chkb).is(':checked')){

         $('#txt_btn').replaceWith(dd);
var a = chkb.split('_');
var ja = a[0].replace('x','+');
var jb = a[1];



} else {


$('#txt_btn').replaceWith(orig);
}

}

</script>

<?php



include("./func/f_cdr.php");


isset($_POST['oper']); 

//if($p){

$oper = $_POST["oper"];
$len_oper = strlen($oper);
$oper = sprintf("%d",$oper);
if($oper == 0){unset($oper); }


$client =$_POST["client"];
$len_client = strlen($client);

if($client == 0){unset($client); }else
{
if( $client[0]  == '+'){}
else{$client = sprintf("%d",$client);}}

if($len_oper != 0 && $len_client == 0){unset($oper);}

 


if(isset($_POST['chk']) && $_POST['chk']== 'chk') {

uregsqli("service_opers",$client,$oper,'1');
}else{

uregsqli("service_opers",$client,$oper,'0');
}

//if(isset($_POST['delrec']) && $_POST['delrec']== 'delrec') {
if(isset($_POST['delrec'])) {
//echo "CHECK";

$j=$_POST['delrec']; 
$ar = explode('_',$j);
$pos = strpos($ar[0],'x');
if($pos === 0 ){$ar[0] ='+'.substr($ar[0],1,strlen($ar[0])-1); }

uregsqli("service_opers",$ar[0],$ar[1],'2');

}
?>

</form>
</html>


function
Код: Выделить всё
<?php

function con_base()
{

$d= date("Y-m-d");
$nd= "'".$d." "."00:00:00"."'";
$link = mysqli_connect(
            'localhost',  /* Хост, к которому мы подключаемся */
            'crm',       /* Имя пользователя */
            'crm',   /* Используемый пароль */
            'crm');     /* База данных для запросов по умолчанию */
 
if (!$link) {
   printf("Невозможно подключиться к базе данных. Код ошибки: %s\n", mysqli_connect_error());
   //   print("Невозможно подключиться к базе данных. Код ошибки: %s\n", mysqli_connect_error());

   exit;
}

return $link;

}



function uregsqli($tbl,$client,$oper,$ind )
{



$cnt_full =0;
$cnt_answer = 0;
$cnt_no_answer =0;
$cnt_busy =0;
$cnt_congest=0;
$cnt_fail =0;

$today = date("H:i:s  Y-m-d  D");


$link=con_base();
mysqli_set_charset('utf8',$link);
$client = "'".$client."'";

switch($ind){

case 0:
//////////
//$result = mysqli_query($link, "SELECT * FROM  $tbl where await_calling_number=$client");
$pos =strpos($client,'8');
//echo $pos;
if($pos == 1){ $client = "'+7".substr($client,2,strlen($client) -1); }

// while( $row = mysqli_fetch_assoc($result) ){
// if($row['await_calling_number'] == $client){
$req = mysqli_query($link, "DELETE FROM  $tbl WHERE await_calling_number=$client");
//$req = mysqli_query($link, "UPDATE  $tbl SET oper=$oper where  await_calling_number=$client "); 
//   }
 
// }
//////////
//print $client;
//$pos =strpos($client,'8');
//echo $pos;
//if($pos == 1){ $client = "'+7".substr($client,2,strlen($client) -1); }
$req = mysqli_query($link, "INSERT INTO $tbl(await_calling_number,oper)VALUES($client,$oper) ");
$result = mysqli_query($link, "SELECT * FROM  $tbl");
break;

case 1:

//$req = mysqli_query($link, "DELETE FROM  $tbl WHERE  oper=$oper AND  await_calling_number=$client" );
$req = mysqli_query($link, "truncate  $tbl" );
$result = mysqli_query($link, "SELECT * FROM  $tbl");
break;


case 2:
//echo $client;
$req = mysqli_query($link, "DELETE FROM  $tbl WHERE  oper=$oper AND  await_calling_number=$client" );
//$req = mysqli_query($link, "truncate  $tbl" );
$result = mysqli_query($link, "SELECT * FROM  $tbl");
break;


default: break;
}
   /* Выводим результаты в html */
    echo '<br>';
        echo '<br>';
       
print '<table border="1" cellpadding="7" cellspacing="0">';
print '<td width="1%" align="left">'.$today.'</td>';
print '</table>';

print '<table border="1" cellpadding="7" cellspacing="0">';
print '<td bgcolor="#F08080" width="1%" align="center">'."Дата".'</td>';
//print '<td bgcolor="#F08080" width="10%" align="center">'."Дата Создания".'</td>';
//print '<td bgcolor="#F08080" width="10%" align="center">'."Дата Изменений".'</td>'; 
print '<td bgcolor="#F08080" width="1%" align="center">'."Клиент".'</td>';
print '<td bgcolor="#F08080" width="1%" align="center">'."Менеджер".'</td>';
print '<td bgcolor="#F08080" width="1%" align="center">'."______".'</td>';
print '<td bgcolor="#F08080" width="1%" align="center">'."______".'</td>';
//print '<td bgcolor="#F08080" width="10%" align="center">'."______".'</td>';
$s_p = 0;
   while( $row = mysqli_fetch_assoc($result) ){

    print '<tr>';
      print '<td  width="10%" valign="top" align="left">'.$row['data_create'].'</td>';
//      print '<td width="10%" align="center">'.$row['data_modified'].'</td>'; 
    print '<td width="10%"  align="center">'.$row['await_calling_number'].'</td>';
                print '<td width="10%" valign="center" align="center">'.$row['oper'].'</td>';

           $cnt_full=$cnt_full + 1;
/////////////////////////////      
print '<td width="15%" align="center">';
$eid=$row['await_calling_number'].'_'.$row['oper'];
$pos=strpos($eid,'+');
//echo $pos;
if($pos === 0){ $eid='x'.substr($eid,1,strlen($eid)-1); }
//echo "";
//str_ireplace('+','x',$eid);
//ho $eid;
print '<input type="checkbox" name="delrec" size="" class="chkt" id="'.$eid.'" value="'.$eid.'" onchange="del_rec(this.id)">';
//print '<input type="checkbox" name="delrec" size="" class="chkt" id="'.$row['oper'].'" value="delrec" onchange="del_rec(this.id)">';


print '</td>';
print '<td width="15%" align="center">';
//print $eid;
print '</td>';
print '</tr>';


    }

//  end печать   
  print '</table>';   

print '<table border="1" cellpadding="7" cellspacing="0">';
print '<td width="1%" align="left">';
print  "Выведено записей: ".$cnt_full."\n";
print '</td>';
print '</table>';

 
//print '</table>';   
 
   /* Освобождаем используемую память */
    mysqli_free_result($result);
 
 
   
     
/* Закрываем соединение */
mysqli_close($link);
}

 
?>
Вложения
452.zip
2
(286.7 Кб) Скачиваний: 2298
Нас определяет то, что мы делаем.
Аватара пользователя
dimondack
посетитель
 
Сообщения: 104
Зарегистрирован: 21 янв 2015, 13:00

Re: ARI Stasis

Сообщение dimondack » 09 дек 2019, 20:08

И вот


'000' => 1. Noop(****CRM******) [extensions.conf:164]
2. Answer() [extensions.conf:165]
3. Stasis(dialer) [extensions.conf:166]
4. HangUp() [extensions.conf:167]



Все водящие звонки отправляются на playback и плавают там на "рейде"
А операторы сами забирают клиента.

Как то так..
Вложения
answer.jpg
answer
ring.jpg
ring
445.zip
445
(2.08 Мб) Скачиваний: 2302
Нас определяет то, что мы делаем.
Аватара пользователя
dimondack
посетитель
 
Сообщения: 104
Зарегистрирован: 21 янв 2015, 13:00


Вернуться в Настройка VoIP железа

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

cron