martes, 22 de septiembre de 2020

dialer con entrada IVR

 FUNCIONA! Consulta estado de un caso mediante DTMF


Funciona!!!

Por fin he dado con ello.

SISTEMA COMPLETO DE ESTADO DE TICKETS USANDO ELASTIX Y OSTICKET.
-----------------------------------------------------------------

En primer lugar, creamos el siguiente archivo:

comprobarticket.php

#!/usr/bin/php -q
<?php
//llamamos a las librerías de phpagi
require("phpagi.php");
//activamos la bandera de enviar todo lo que se realice a consola como modo depuracion
error_reporting(E_ALL);
//creamos una instancia de la clase AGI
$agi = new AGI();
//generamos el comando Answer de Asterisk, este comando siempre lo ejecutamos al inicio de un AGI
$agi->answer();
//Este demo consultará información en una base de datos y regresará la información de forma hablada por lo que generamos una conexion a la base de datos de sql
$conexion = mysql_connect("LaIpDeTuServidorMysql","TuNombreDeUsuario","TuPass") or die("Error: El servidor no puede conectar con la base de datos");
//Referenciamos el cursor a la base de datos
mysql_select_db("NombreDeTuBBDD",$conexion);
//Reproducimos el archivo de audio que solicita que introduzca el número de ticket de soporte, del cual conocer su estado.
//El archivo de audio lo hemos grabado previamente desde elastix, y se almacena en /var/lib/asterisk/sounds/
//y viene a decir algo como: Despues del pitido, introduzca su número de ticket de soporte para conocer su estado actual, o marque 0 para salir.
$agi->exec(Playback,"introduceticket");
do {
//enviamos un beep y esperamos 25 segundos en la espera de una respuesta. Podemos cambiar el 'beep', por "Archivo_de_audio_propio"
$_result = $agi->get_data('beep', 3000, 25);
//obtenemos la información introducida desde el telefono
$numticket = $_result['result'];
//si introdujo un valor el cliente entonces creamos el string la consulta sql y la ejecutamos
if($numticket!=""){
$query = "select status from ost_ticket where ticketID=\"$numticket\" ";
$_result = mysql_query($query, $conexion);
//verificamos si existe un resultado
if($_re = mysql_fetch_array($_result)) {
//Comprobamos si el estado recuperado de la BBD es open
if ($_re[status] == "open") {
//y si es así, reproduzco un audio pregrabado llamado abierta que dice algo como: Su incidencia aún está en situación de resolverse. Vuelva a consultar su estado pasado pasadas unas horas.
$agi->exec(Playback,"abierta");
}
//Comprobamos si el estado recuperado de la BBD es closed
if ($_re[status] == "closed") {
//y si es así, reproduzco un audio pregrabado llamado cerrada que dice algo como: Su incidencia está resuelta. Puede recoger su equipo cuando desee.
$agi->exec(Playback,"cerrada");
}

}else{
//de lo contrario enviamos un mensaje de que el ticket no pudo ser encontrado
if ($numticket!='0'){
$agi->exec(Playback,"noencontrado");
}

}
if ($numticket!='0'){
$agi->exec(Playback,"introduceticket");
}
}

} while($numticket != '0'); //Continuamos solicitando números de ticket mientras el cliente no marque 0 para salir

//Reproducimos el archivo de audio de despedida, agradeciendo el uso del sistema.
//El archivo de audio lo hemos grabado previamente desde elastix, y se almacena en /var/lib/asterisk/sounds/
//y viene a decir algo como: Gracias por utilizar el sistema de control de tickets.
$agi->exec(Playback,"despedida");
//al finalizar el script del AGI siempre es recomendable ejecutar esta función para no dejar el canal abierto.
$agi->hangup();
?>

Una vez echo esto, subirlo al servidor mediante WinSCP o similar a la ruta /var/lib/asterisk/agi-bin/

A continuación, es importante que cambies los permisos del archivo a 775

Cread los archivos de audio. Para ello, leed los comentarios del archivo php creado.

Ahora, hay que crear la llamada al AGI de la siguiente manera:
Editar el archivo extensions_custom.conf y crea el siguiente contexto:

[custom-agiphp]
exten => 101,1,Answer
exten => 101,2,AGI(/var/lib/asterisk/agi-bin/comprobarticket.php)
exten => 101,3,Hangup

y añadirlo en

[from-internal-custom]
exten => 1234,1,Playback(demo-congrats) ; extensions can dial 1234
exten => 1234,2,Hangup()
exten => h,1,Hangup()
include => agentlogin
include => conferences
include => calendar-event
include => weather-wakeup
include => custom-agiphp

Salvamos.

Si llamamos a la extensión 101, ya debería funcionar.

Ahora, si queremos que funcione mediante el uso de IVR, tan solo hay que ir a MISC DESTINATIONS, y crear uno que sea, por ejemplo:

Descripción: tickets
Marcar: 101

Creamos el IVR con las opciones que queramos, entre ellas una que solicite acceder al sistema de control de tickets, en la cual, seleccionaremos como destino:

Misc Destinations: tickets.

Salvar.

Recomiendo reiniciar elastix y a funcionar.

Revisad bien la conexión a la BBDD y que seguramente tendréis que mover los audios creados de la carpeta /var/lib/asterisk/sounds/custom a /var/lib/asterisk/sounds/, si no, no oireis nada más que el beep.

Tienes varias opciones:

1. Accedes a la consola de tu elastix mediante la aplicación Putty, eso si, logueandote como root, y escribes lo siguiente:

cd /var/lib/asterisk/agi-bin (pulsas intro)
chmod 775 comprobarticket.php (pulsas intro)

Y ya está.

Opción 2. Hacer lo mismo, pero desde la consola local de la máquina, siempre y cuando tengas un teclado y pantalla conectado a tu elastix. En ese caso no necesitarías acceder mediante putty

Opción 3. Acceder a tu elastix mediante filezilla como root, e ir a la dirección /var/lib/asterisk/agi-bin. Una vez ahí veras el listado de archivos que la carpeta agi-bin contiene. Te posicionas sobre el archivo comprobarticket.php y pulsas botón derecho. Seleccionas cambiar permisos, y en el cuadro de abajo, borrar los números que vengan por defecto y escribes 775. Pulsas intro o guardar y listo.

viernes, 18 de septiembre de 2020

Instalar my php admin

 


yum -y install phpmyadmin 

despues modificar 


Ninguna de las configuraciones anteriores funcionó para mí en mi servidor CentOS 7. Después de horas de búsqueda, eso fue lo que funcionó para mí:

Edite el archivo phpMyAdmin.conf

sudo nano /etc/httpd/conf.d/phpMyAdmin.conf

Y reemplace el <Directory> ... </Directory>nodo existente con lo siguiente:

<Directory /usr/share/phpMyAdmin/>
   AddDefaultCharset UTF-8

   <IfModule mod_authz_core.c>
     # Apache 2.4
     <RequireAny>
       #Require ip 127.0.0.1
       #Require ip ::1
       Require all granted
     </RequireAny>
   </IfModule>
   <IfModule !mod_authz_core.c>
     # Apache 2.2
     Order Deny,Allow
     Deny from All
     Allow from 127.0.0.1
     Allow from ::1
   </IfModule>
</Directory>

Campaña Call center 2 parte

 


Bueno ahora cambiamos de carpeta y vamos a Campañas salientes :


Vamos a crear un archivo descargar estos archivos de esta direccion IP y los vamos a cuadrar en la ubicación :

/var/www/html/modules/campaign_out

http://jksistemas.com.co/JK/Descargas/IP-JK/html/modules/campaign_out/campaign_out.tar

Los archivos están comprimidos debemos bajarlos e instalarlos ahí :

Ahora vamos a modificar el archivo ubicado en :

/var/www/html/modules/campaign_out/libs llamado :

paloContactInsert.class.php

Vamos a modificar esta linea :
-------------------------------------------
 'INSERT INTO calls (id_campaign, phone, status, dnc) VALUES (?, ?, NULL, ?)');
----------------------------------------
por esta :
----------------------------------------
 'INSERT INTO calls (id_campaign, phone, status, dnc, principal_contact, contactado, id_contacto) VALUES (?, ?, NULL, ?, ?, ?, ?)');
----------------------------------------


buscamos esta otra 

function insertOneContact($number, $attributes)

y la cambiamos por esta 
function insertOneContact($number, $attributes, $principal_contact, $contactado, $id_contacto)
 
Después esta 
$r = $this->_sth_contact_number->execute(array($this->_id_campaign, $number, $iDNC));

y la cambiamos por

$r = $this->_sth_contact_number->execute(array($this->_id_campaign, $number, $iDNC, $principal_contact, $contactado,$id_contacto));
 
Listo por ese lado ! 

Ahora vamos a modificar un archivo para que funcione y deje subir el archivos CVS con mas de un numero , vamos entonces a :

/var/www/html/modules/campaign_out/uploaders/CSV

Modificamos esto en ese archivo .
Este Reglón :

} elseif (!preg_match('/^([\d#\*])+$/', $tupla[0])) {
Y ponemos este reglón 

} elseif (!preg_match('/^([\d-#\*])+$/', $tupla[0])) {

Después vamos a quitar este  Reglón :


$idCall = $inserter->insertOneContact($numero, $atributos);

Y vamos a poner todo este Código  :

----------------------------------
                if (strpos($numero, '-') !== false) {
                    
                    $numeroarray = explode("-", $numero);
                    //A: principal B: secundario
                    $principal_contact='A';
                    //A: aún no asignado (luego de llamada se pone ID)
                    $id_contacto='A';
                    //P: pendiente E:espera T:terminado C:contactado
                    $contactado='P';
                    $id_contacto_count=1;
                    //Lipiando ID_CALL
                    $idCall='';
                    
                    //error_log(var_export($numeroarray, true));
                    foreach ($numeroarray as $valor) {
                        //error_log(var_export($valor, true));

                        if ($idCall=='' AND $id_contacto_count==1) {
                            $id_contacto_count++;
                            $idCall = $inserter->insertOneContact($valor, $atributos,$principal_contact, $contactado,$id_contacto);
                            //error_log(var_export($valor." y ".$id_contacto, true));
                            $id_contacto=$idCall;
                            $principal_contact='B';
                            $contactado='E';
                            
                        }
                        else{
                            //error_log(var_export($valor." o ".$id_contacto." - ".$id_contacto_count, true));
                            $idCall = $inserter->insertOneContact($valor, $atributos,$principal_contact, $contactado,$id_contacto);
                        }
                    }
                    //error_log(var_export($valor." y ".$id_contacto, true));
                }
                else{
                    $principal_contact='0';
                    $contactado='0';
                    $id_contacto='0';
                    $idCall = $inserter->insertOneContact($numero, $atributos,$principal_contact, $contactado,$id_contacto);
                }

-------------------------------

campaña call center

 Lo primero que debemos hacer es modificar el archivo index en :


/var/www/html/modules/agent_console


 Debemos modificar desde la linea 846 :


Agregamos esto :


-----------------------------------------------------------------------------------------------

        $comboContactos = array();

        $comboselect = array();

        $id_contactado=(isset($infoLlamada['contact_id']) ? 'c'.$infoLlamada['contact_id'] : (isset($infoLlamada['callid']) ? $infoLlamada['callid'] : $infoLlamada['call_id']));

        //BD

        $conexion = mysql_connect("localhost","root","R8S8r8dpZr");

        mysql_select_db("call_center",$conexion);

        //$cConsulta = 'SELECT id,phone FROM calls where id_contacto="'.$id_contactado.'" AND contactado!="0"';

        $cConsulta = 'SELECT id,phone,contactado,id_contacto FROM calls WHERE id_contacto=(IF((SELECT id_contacto FROM calls where id="'.$id_contactado.'")="A","'.$id_contactado.'", (SELECT id_contacto FROM calls where id="'.$id_contactado.'" AND id_contacto!="0" ))) OR id=(SELECT id FROM calls where id_contacto="A" AND id="'.$id_contactado.'") OR id=(SELECT id_contacto FROM calls where id="'.$id_contactado.'" AND id_contacto!="0") ORDER BY FIELD(id,"'.$id_contactado.'") DESC';


        $rsConsulta = mysql_query($cConsulta);

        while ($fila = mysql_fetch_array($rsConsulta, MYSQL_NUM)) {

            $comboContactos[] = $fila;

        }


        foreach ($comboContactos as $key => $value) {


            $comboselect[$comboContactos[$key][0]] = $comboContactos[$key][1];

        }

-------------------------------------------------------------------------------------------



Muy importante poner la clave root 
($conexion = mysql_connect("localhost","root","claverootMySQL");

Aquí entramos al MySQL a verificar si el numero fue contactado o no 
Después vamos a agregar estos label en el mismo archivo :

linea 875 aproximadamente 

-----------------------------------------------------------------------------------------    
        'LBL_CONTACTO_SELECT'       =>  'Contactado',
            'LISTA_CONTACTOS'           =>  $comboselect,
            'BTN_CONFIRMAR_CONTACTO'    =>  'Contactado',
            'BTN_CONFIRMAR_CONTACTO2'    =>  'No Contactado',
-----------------------------------------------------------------------------------------



después de esto vamos a la linea 1.058 mas o menos del mismo archivo y agregamos esta función :



------------------------------------------------------------
// Agregado 18 09 2020 Funcion verificar base de datos no Contactado 
 
function manejarSesionActiva_confirm_contact_outgoing($module_name, $smarty, $sDirLocalPlantillas, $oPaloConsola, $estado)
{
    $respuesta = array(
        'action'    =>  'confirmed',
        'message'   =>  _tr('Contact successfully confirmed'),
    );
    $idContact = getParameter('id_contact');
    $confirma = getParameter('confirma');

    if (is_null($idContact) || !ctype_digit($idContact)) {
        $respuesta['action'] = 'error';
        $respuesta['message'] = _tr('Invalid or missing contact ID');
    } else {
        $bExito = $oPaloConsola->confirmarContacto_outgoing($idContact, $confirma);
        if ($bExito==='NOT') {
            $respuesta['action'] = 'confirmed';
            $respuesta['message'] = 'Cliente no contactado, se intentara llamar a otro numero';
        }
        elseif (!$bExito) {
            $respuesta['action'] = 'error';
            $respuesta['message'] = _tr('Error while confirming contact').' - '.$oPaloConsola->errMsg.$idContact;
        }
    }

    $json = new Services_JSON();
    Header('Content-Type: application/json');
    return $json->encode($respuesta);
}

// Agregado 18 09 2020 Función verificar base de datos no Contactado 
----------------------------------------------
Después casi al final del archivo agregamos esto 

------------------------------------------------------------
        $comboContactos = array();
        $comboselect = array();
        $id_contactado=(isset($infoLlamada['contact_id']) ? 'c'.$infoLlamada['contact_id'] : (isset($infoLlamada['callid']) ? $infoLlamada['callid'] : $infoLlamada['call_id']));
        //BD
        $conexion = mysql_connect("localhost","root","R8S8r8dpZr");
        mysql_select_db("call_center",$conexion);
        //$cConsulta = 'SELECT id,phone FROM calls where id_contacto="'.$id_contactado.'" AND contactado!="0"';
        $cConsulta = 'SELECT id,phone,contactado,id_contacto FROM calls WHERE id_contacto=(IF((SELECT id_contacto FROM calls where id="'.$id_contactado.'")="A","'.$id_contactado.'", (SELECT id_contacto FROM calls where id="'.$id_contactado.'" AND id_contacto!="0" ))) OR id=(SELECT id FROM calls where id_contacto="A" AND id="'.$id_contactado.'") OR id=(SELECT id_contacto FROM calls where id="'.$id_contactado.'" AND id_contacto!="0") ORDER BY FIELD(id,"'.$id_contactado.'") DESC';

        $rsConsulta = mysql_query($cConsulta);
        while ($fila = mysql_fetch_array($rsConsulta, MYSQL_NUM)) {
            $comboContactos[] = $fila;
        }

        foreach ($comboContactos as $key => $value) {

            $comboselect[$comboContactos[$key][0]] = $comboContactos[$key][1];
        }
-------------------------------------------------------------------------------------


 

luego después de eso un par de reglones abajo agregamos esto :

-----------------------------------------------------------------
        $registroCambio['lista_contactos'] = $comboselect;
        $registroCambio['puede_confirmar_contacto'] = (count($comboselect) > 1);
-----------------------------------------------------------------------


BIEN ESO ES TODO POR ESA PARTE ! ... 

Ahora vamos a este archivo :

/var/www/html/modules/agent_console/themes/default/agent_console_atributos.tpl
y agregamos estos reglones :

-------------------------------------------------------
        <tr>
            <td><label for="llamada_entrante_contacto_id">{$LBL_CONTACTO_SELECT}: </label></td>
            <td>
              <select
                  name="llamada_entrante_contacto_id"
                  id="llamada_entrante_contacto_id"
                  class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
                  {html_options options=$LISTA_CONTACTOS}
              </select>
              <button id="btn_confirmar_contacto1">{$BTN_CONFIRMAR_CONTACTO}</button>
              <button id="btn_confirmar_contacto2">{$BTN_CONFIRMAR_CONTACTO2}</button>
            </td>
        </tr> 
--------------------------------------------------------



bueno hay un archivo que nosotros manejamos con las actualizaciones pertinentes para generar el descanso automático :

Ahora generamos esta opción :
Vamos a /var/www/html/modules/agent_console/libs/paloSantoConsola.class.php

y en el reglon 813 aproximadamente agregamos esto :

---------------------------------------------

    function confirmarContacto_outgoing($idCall, $confirma)
    {
        try {
            $oDB = $this->_obtenerConexion('call_center');
            if ($confirma=='YES') {
              $sPeticion ='SELECT id_contacto FROM calls WHERE id_contacto=(IF((SELECT principal_contact FROM calls where id="'.$idCall.'")="A","'.$idCall.'", (SELECT id_contacto FROM calls where id="'.$idCall.'" AND id_contacto!="0" ))) LIMIT 1;';
              $recordset = $oDB->fetchTable($sPeticion, TRUE);
              
              $id_confirmed=$recordset[0]['id_contacto'];
              //Actualizar si es primera llamada:
              $sUPDATE='UPDATE calls SET id_contacto="'.$id_confirmed.'" WHERE id="'.$idCall.'" AND id_contacto="A";';
              $updateset = $oDB->genQuery($sUPDATE,TRUE);

              //actualizar todos los demas a Terminados
              $sUPDATE='UPDATE calls SET contactado="T" WHERE id_contacto="'.$id_confirmed.'";';
              $updateset = $oDB->genQuery($sUPDATE,TRUE);

              //actualizar id actual como contactado
              $sUPDATE='UPDATE calls SET contactado="C" WHERE id="'.$idCall.'";';
              $updateset = $oDB->genQuery($sUPDATE,TRUE);

              return TRUE;
            }
            elseif ($confirma=='NOT') {

              $sPeticion ='SELECT id_contacto FROM calls WHERE id_contacto=(IF((SELECT principal_contact FROM calls where id="'.$idCall.'")="A","'.$idCall.'", (SELECT id_contacto FROM calls where id="'.$idCall.'" AND id_contacto!="0" ))) LIMIT 1;';
              $recordset = $oDB->fetchTable($sPeticion, TRUE);
              $id_confirmed=$recordset[0]['id_contacto'];
              //Actualizar si es primera llamada:
              $sUPDATE='UPDATE calls SET id_contacto="'.$id_confirmed.'" WHERE id="'.$idCall.'" AND id_contacto="A";';
              $updateset = $oDB->genQuery($sUPDATE,TRUE);

              //actualizar ID de sigiente registro como pendiente si no hay mas volver a poner el primero como Pendiente
              $sPeticion ='SELECT id FROM calls WHERE id_contacto=(SELECT id_contacto FROM calls where id="'.$idCall.'") AND contactado="E" ORDER BY FIELD(id,"'.$idCall.'") DESC LIMIT 1;';
              $recordset = $oDB->fetchTable($sPeticion, TRUE);

              if (isset($recordset[0]['id'])) {
                $id_espera=$recordset[0]['id'];
                $sUPDATE='UPDATE calls SET contactado="P" WHERE id="'.$id_espera.'";';
                $updateset = $oDB->genQuery($sUPDATE,TRUE);              
              }
              else{
                $sPeticion ='SELECT id FROM calls WHERE id_contacto=(SELECT id_contacto FROM calls where id="'.$idCall.'") AND contactado="T" ORDER BY FIELD(id,"'.$idCall.'") DESC LIMIT 1;';
                $recordset = $oDB->fetchTable($sPeticion, TRUE);
                //var_dump($recordset);
                $id_espera=$recordset[0]['id'];
                $sUPDATE='UPDATE calls SET contactado="P" WHERE id="'.$id_espera.'";';
                $updateset = $oDB->genQuery($sUPDATE,TRUE);

              }
              
              //actualizar registro actual
              $sUPDATE='UPDATE calls SET contactado="T" WHERE id="'.$idCall.'";';
              $updateset = $oDB->genQuery($sUPDATE,TRUE);

              return 'NOT';
            }


            
        } catch (Exception $e) {
            $this->errMsg = '(internal) setcontact: '.$e->getMessage();
            return FALSE;
        }
    } 
-----------------------------------------------------------


sigue 2 parte