function manejarLogin_checkLogin() { $respuesta = array('action' => 'wait', 'message' => '(no message)'); $bContinuar = TRUE; // Verificación rápida para saber si el canal es correcto $sAgente = $_SESSION['callcenter']['agente']; $sExtension = $_SESSION['callcenter']['extension']; $oPaloConsola = new PaloSantoConsola('Agent/' . $sAgente); if ($bContinuar) { $estado = $oPaloConsola->estadoAgenteLogoneado($sExtension); switch ($estado['estadofinal']) { case 'error': case 'mismatch': // Otra extensión ya ocupa el login del agente indicado, o error $_SESSION['callcenter'] = generarEstadoInicial(); $respuesta['action'] = 'error'; $respuesta['message'] = _tr('Cannot start agent login') . ' - ' . $oPaloConsola->errMsg . "ext={$sExtension} agente={$sAgente}"; $bContinuar = FALSE; break; case 'logged-out': // No se encuentra evidencia de que se empezara el login $_SESSION['callcenter'] = generarEstadoInicial(); $respuesta['action'] = 'error'; $respuesta['message'] = _tr('Agent login process not started'); $bContinuar = FALSE; break; case 'logging': $_SESSION['callcenter']['estado_consola'] = 'logging'; $respuesta['action'] = 'wait'; $respuesta['message'] = _tr('Logging agent in. Please wait...'); break; case 'logged-in': // El agente ha podido logonearse. Se procede a mostrar el formulario $_SESSION['callcenter']['estado_consola'] = 'logged-in'; $respuesta['action'] = 'login'; $bContinuar = FALSE; break; } } if ($bContinuar && $respuesta['action'] == 'wait') { $oPaloConsola->desconectarEspera(); // Se inicia espera larga con el navegador... $iTimeoutPoll = PaloSantoConsola::recomendarIntervaloEsperaAjax(); session_commit(); set_time_limit(0); $iTimestampInicio = time(); while ($bContinuar && time() - $iTimestampInicio < $iTimeoutPoll) { // Verificar si el agente ya está en línea $sEstado = $oPaloConsola->esperarResultadoLogin(); if ($sEstado == 'logged-in') { // Reiniciar la sesión para poder modificar las variables session_start(); // El agente ha podido logonearse. Se procede a mostrar el formulario $_SESSION['callcenter']['estado_consola'] = 'logged-in'; $respuesta['action'] = 'login'; $bContinuar = FALSE; } elseif ($sEstado == 'logged-out') { // Reiniciar la sesión para poder modificar las variables session_start(); // El procedimiento de login ha fallado, sin causa conocida $_SESSION['callcenter'] = generarEstadoInicial(); $respuesta['action'] = 'error'; $respuesta['message'] = _tr('Agent log-in terminated.'); $bContinuar = FALSE; } elseif ($sEstado == 'error') { // Reiniciar la sesión para poder modificar las variables session_start(); // Ocurre un error al consultar el estado del agente $_SESSION['callcenter'] = generarEstadoInicial(); $respuesta['action'] = 'error'; $respuesta['message'] = _tr('Agent log-in failed!') . ' - ' . $oPaloConsola->errMsg; $bContinuar = FALSE; } } } $json = new Services_JSON(); $sContenido = $json->encode($respuesta); Header('Content-Type: application/json'); $oPaloConsola->desconectarTodo(); return $sContenido; }
function manejarMonitoreo_checkStatus($module_name, $smarty, $sDirLocalPlantillas) { $respuesta = array(); ignore_user_abort(true); set_time_limit(0); // Estado del lado del cliente $estadoHash = getParameter('clientstatehash'); if (!is_null($estadoHash)) { $estadoCliente = isset($_SESSION[$module_name]['estadoCliente']) ? $_SESSION[$module_name]['estadoCliente'] : array(); } else { $estadoCliente = getParameter('clientstate'); if (!is_array($estadoCliente)) { return; } } // Modo a funcionar: Long-Polling, o Server-sent Events $sModoEventos = getParameter('serverevents'); $bSSE = !is_null($sModoEventos) && $sModoEventos; if ($bSSE) { Header('Content-Type: text/event-stream'); printflush("retry: 1\n"); } else { Header('Content-Type: application/json'); } // Verificar hash correcto if (!is_null($estadoHash) && $estadoHash != $_SESSION[$module_name]['estadoClienteHash']) { $respuesta['estadoClienteHash'] = 'mismatch'; $respuesta['hashRecibido'] = $estadoHash; jsonflush($bSSE, $respuesta); return; } $oPaloConsola = new PaloSantoConsola(); // Estado del lado del servidor $estadoCampania = $oPaloConsola->leerEstadoCampania($estadoCliente['campaigntype'], $estadoCliente['campaignid']); if (!is_array($estadoCampania)) { $respuesta['error'] = $oPaloConsola->errMsg; jsonflush($bSSE, $respuesta); $oPaloConsola->desconectarTodo(); return; } // Acumular inmediatamente las filas que son distintas en estado $respuesta = crearRespuestaVacia(); // Cuenta de estados foreach (array_keys($estadoCliente['statuscount']) as $k) { // Actualización de valores de contadores if ($estadoCliente['statuscount'][$k] != $estadoCampania['statuscount'][$k]) { $respuesta['statuscount']['update'][$k] = $estadoCampania['statuscount'][$k]; $estadoCliente['statuscount'][$k] = $estadoCampania['statuscount'][$k]; } } // Estado de llamadas no conectadas foreach (array_keys($estadoCliente['activecalls']) as $k) { // Llamadas que cambiaron de estado o ya no están sin agente if (!isset($estadoCampania['activecalls'][$k])) { // Llamada ya no está esperando agente $respuesta['activecalls']['remove'][] = array('callid' => $estadoCliente['activecalls'][$k]['callid']); unset($estadoCliente['activecalls'][$k]); } elseif ($estadoCliente['activecalls'][$k]['callstatus'] != $estadoCampania['activecalls'][$k]['callstatus']) { // Llamada ha cambiado de estado $respuesta['activecalls']['update'][] = formatoLlamadaNoConectada($estadoCampania['activecalls'][$k]); $estadoCliente['activecalls'][$k] = $estadoCampania['activecalls'][$k]; } } foreach (array_keys($estadoCampania['activecalls']) as $k) { // Llamadas nuevas if (!isset($estadoCliente['activecalls'][$k])) { $respuesta['activecalls']['add'][] = formatoLlamadaNoConectada($estadoCampania['activecalls'][$k]); $estadoCliente['activecalls'][$k] = $estadoCampania['activecalls'][$k]; } } // Estado de agentes de campaña foreach (array_keys($estadoCliente['agents']) as $k) { // Agentes que cambiaron de estado o desaparecieron (???) if (!isset($estadoCampania['agents'][$k])) { // Agente ya no aparece (???) $respuesta['agents']['remove'][] = array('agent' => $estadoCliente['agents'][$k]['agentchannel']); unset($estadoCliente['agents'][$k]); } elseif ($estadoCliente['agents'][$k] != $estadoCampania['agents'][$k]) { // Agente ha cambiado de estado $respuesta['agents']['update'][] = formatoAgente($estadoCampania['agents'][$k]); $estadoCliente['agents'][$k] = $estadoCampania['agents'][$k]; } } foreach (array_keys($estadoCampania['agents']) as $k) { // Agentes nuevos (???) if (!isset($estadoCliente['agents'][$k])) { $respuesta['agents']['add'][] = formatoAgente($estadoCampania['agents'][$k]); $estadoCliente['agents'][$k] = $estadoCampania['agents'][$k]; } } unset($estadoCampania); $oPaloConsola->escucharProgresoLlamada(TRUE); $iTimeoutPoll = PaloSantoConsola::recomendarIntervaloEsperaAjax(); do { $oPaloConsola->desconectarEspera(); // Se inicia espera larga con el navegador... $iTimestampInicio = time(); while (connection_status() == CONNECTION_NORMAL && esRespuestaVacia($respuesta) && time() - $iTimestampInicio < $iTimeoutPoll) { session_commit(); $listaEventos = $oPaloConsola->esperarEventoSesionActiva(); if (is_null($listaEventos)) { $respuesta['error'] = $oPaloConsola->errMsg; jsonflush($bSSE, $respuesta); $oPaloConsola->desconectarTodo(); return; } @session_start(); /* Si el navegador elige otra campaña mientras se espera la primera * campaña, entonces esta espera es inválida, y el navegador ya ha * iniciado otra sesión comet. */ if (isset($_SESSION[$module_name]) && !($estadoCliente['campaigntype'] === $_SESSION[$module_name]['estadoCliente']['campaigntype'] && $estadoCliente['campaignid'] === $_SESSION[$module_name]['estadoCliente']['campaignid'])) { $respuesta['estadoClienteHash'] = 'invalidated'; jsonflush($bSSE, $respuesta); $oPaloConsola->desconectarTodo(); return; } $iTimestampActual = time(); foreach ($listaEventos as $evento) { $sCanalAgente = isset($evento['agent_number']) ? $evento['agent_number'] : NULL; switch ($evento['event']) { case 'agentloggedin': if (isset($estadoCliente['agents'][$sCanalAgente])) { /* Se ha logoneado agente que atiende a esta campaña. * ATENCIÓN: sólo se setean suficientes campos para la * visualización. Otros campos quedan con sus valores * antiguos, si tenían */ $estadoCliente['agents'][$sCanalAgente]['status'] = 'online'; $estadoCliente['agents'][$sCanalAgente]['callnumber'] = NULL; $estadoCliente['agents'][$sCanalAgente]['pausestart'] = NULL; $estadoCliente['agents'][$sCanalAgente]['linkstart'] = NULL; $estadoCliente['agents'][$sCanalAgente]['trunk'] = NULL; $respuesta['agents']['update'][] = formatoAgente($estadoCliente['agents'][$sCanalAgente]); } break; case 'agentloggedout': if (isset($estadoCliente['agents'][$sCanalAgente])) { /* Se ha deslogoneado agente que atiende a esta campaña. * ATENCIÓN: sólo se setean suficientes campos para la * visualización. Otros campos quedan con sus valores * antiguos, si tenían */ $estadoCliente['agents'][$sCanalAgente]['status'] = 'offline'; $estadoCliente['agents'][$sCanalAgente]['callnumber'] = NULL; $estadoCliente['agents'][$sCanalAgente]['pausestart'] = NULL; $estadoCliente['agents'][$sCanalAgente]['linkstart'] = NULL; $estadoCliente['agents'][$sCanalAgente]['trunk'] = NULL; $respuesta['agents']['update'][] = formatoAgente($estadoCliente['agents'][$sCanalAgente]); } break; case 'callprogress': $bProcesar = $estadoCliente['campaigntype'] == 'incomingqueue' ? $estadoCliente['campaignid'] == $evento['queue'] && is_null($evento['campaign_id']) : $estadoCliente['campaignid'] == $evento['campaign_id'] && $estadoCliente['campaigntype'] == $evento['call_type']; if ($bProcesar) { // Llamada corresponde a cola monitoreada $callid = $evento['call_id']; // Para llamadas entrantes, cada llamada en cola aumenta el total if ($evento['call_type'] == 'incoming' && $evento['new_status'] == 'OnQueue') { agregarContadorLlamada('total', $estadoCliente, $respuesta); } if (in_array($evento['new_status'], array('Failure', 'Abandoned', 'NoAnswer'))) { if (isset($estadoCliente['activecalls'][$callid])) { restarContadorLlamada($estadoCliente['activecalls'][$callid]['callstatus'], $estadoCliente, $respuesta); agregarContadorLlamada($evento['new_status'], $estadoCliente, $respuesta); // Quitar de las llamadas que esperan un agente $respuesta['activecalls']['remove'][] = array('callid' => $callid); unset($estadoCliente['activecalls'][$callid]); } } elseif (in_array($evento['new_status'], array('OnHold', 'OffHold'))) { // Se supone que una llamada en hold ya fue asignada a un agente } else { if (isset($estadoCliente['activecalls'][$callid])) { restarContadorLlamada($estadoCliente['activecalls'][$callid]['callstatus'], $estadoCliente, $respuesta); $estadoCliente['activecalls'][$callid]['callstatus'] = $evento['new_status']; $estadoCliente['activecalls'][$callid]['trunk'] = $evento['trunk']; if ($evento['new_status'] == 'OnQueue') { $estadoCliente['activecalls'][$callid]['queuestart'] = $evento['datetime_entry']; } $respuesta['activecalls']['update'][] = formatoLlamadaNoConectada($estadoCliente['activecalls'][$callid]); } else { // Valores sólo para satisfacer formato $estadoCliente['activecalls'][$callid] = array('callid' => $callid, 'callnumber' => $evento['phone'], 'callstatus' => $evento['new_status'], 'dialstart' => $evento['datetime_entry'], 'dialend' => NULL, 'queuestart' => $evento['datetime_entry'], 'trunk' => $evento['trunk']); $respuesta['activecalls']['add'][] = formatoLlamadaNoConectada($estadoCliente['activecalls'][$callid]); } agregarContadorLlamada($evento['new_status'], $estadoCliente, $respuesta); } $respuesta['log'][] = formatoLogCampania(array('id' => $evento['id'], 'new_status' => $evento['new_status'], 'datetime_entry' => $evento['datetime_entry'], 'campaign_type' => $evento['call_type'], 'campaign_id' => $evento['campaign_id'], 'call_id' => $evento['call_id'], 'retry' => $evento['retry'], 'uniqueid' => $evento['uniqueid'], 'trunk' => $evento['trunk'], 'phone' => $evento['phone'], 'queue' => $evento['queue'], 'agentchannel' => $sCanalAgente, 'duration' => NULL)); } break; case 'pausestart': if (isset($estadoCliente['agents'][$sCanalAgente])) { // Agente ha entrado en pausa $estadoCliente['agents'][$sCanalAgente]['status'] = 'paused'; $estadoCliente['agents'][$sCanalAgente]['pausestart'] = $evento['pause_start']; $respuesta['agents']['update'][] = formatoAgente($estadoCliente['agents'][$sCanalAgente]); } break; case 'pauseend': if (isset($estadoCliente['agents'][$sCanalAgente])) { // Agente ha salido de pausa $estadoCliente['agents'][$sCanalAgente]['status'] = is_null($estadoCliente['agents'][$sCanalAgente]['linkstart']) ? 'online' : 'oncall'; $estadoCliente['agents'][$sCanalAgente]['pausestart'] = NULL; $respuesta['agents']['update'][] = formatoAgente($estadoCliente['agents'][$sCanalAgente]); } break; case 'agentlinked': // Si la llamada estaba en lista activa, quitarla $callid = $evento['call_id']; if (isset($estadoCliente['activecalls'][$callid])) { restarContadorLlamada($estadoCliente['activecalls'][$callid]['callstatus'], $estadoCliente, $respuesta); $respuesta['activecalls']['remove'][] = array('callid' => $estadoCliente['activecalls'][$callid]['callid']); unset($estadoCliente['activecalls'][$callid]); } // Si el agente es uno de los de la campaña, modificar if (isset($estadoCliente['agents'][$sCanalAgente])) { $estadoCliente['agents'][$sCanalAgente]['status'] = is_null($estadoCliente['agents'][$sCanalAgente]['pausestart']) ? 'oncall' : 'paused'; $estadoCliente['agents'][$sCanalAgente]['callnumber'] = $evento['phone']; $estadoCliente['agents'][$sCanalAgente]['linkstart'] = $evento['datetime_linkstart']; $estadoCliente['agents'][$sCanalAgente]['trunk'] = $evento['trunk']; $respuesta['agents']['update'][] = formatoAgente($estadoCliente['agents'][$sCanalAgente]); $respuesta['log'][] = formatoLogCampania(array('id' => $evento['campaignlog_id'], 'new_status' => 'Success', 'datetime_entry' => $evento['datetime_linkstart'], 'campaign_type' => $evento['call_type'], 'campaign_id' => $evento['campaign_id'], 'call_id' => $evento['call_id'], 'retry' => $evento['retries'], 'uniqueid' => $evento['uniqueid'], 'trunk' => $evento['trunk'], 'phone' => $evento['phone'], 'queue' => $evento['queue'], 'agentchannel' => $sCanalAgente, 'duration' => NULL)); agregarContadorLlamada('Success', $estadoCliente, $respuesta); } break; case 'agentunlinked': // Si el agente es uno de los de la campaña, modificar if (isset($estadoCliente['agents'][$sCanalAgente])) { /* Es posible que se reciba un evento agentunlinked luego * del evento agentloggedout si el agente se desconecta con * una llamada activa. */ if ($estadoCliente['agents'][$sCanalAgente]['status'] != 'offline') { $estadoCliente['agents'][$sCanalAgente]['status'] = is_null($estadoCliente['agents'][$sCanalAgente]['pausestart']) ? 'online' : 'paused'; } $estadoCliente['agents'][$sCanalAgente]['callnumber'] = NULL; $estadoCliente['agents'][$sCanalAgente]['linkstart'] = NULL; $estadoCliente['agents'][$sCanalAgente]['trunk'] = NULL; $respuesta['agents']['update'][] = formatoAgente($estadoCliente['agents'][$sCanalAgente]); $respuesta['log'][] = formatoLogCampania(array('id' => $evento['campaignlog_id'], 'new_status' => $evento['shortcall'] ? 'ShortCall' : 'Hangup', 'datetime_entry' => $evento['datetime_linkend'], 'campaign_type' => $evento['call_type'], 'campaign_id' => $evento['campaign_id'], 'call_id' => $evento['call_id'], 'retry' => NULL, 'uniqueid' => NULL, 'trunk' => NULL, 'phone' => $evento['phone'], 'queue' => NULL, 'agentchannel' => $sCanalAgente, 'duration' => $evento['duration'])); if ($evento['call_type'] == 'incoming') { restarContadorLlamada('Success', $estadoCliente, $respuesta); agregarContadorLlamada('Finished', $estadoCliente, $respuesta); agregarContadorLlamada('Total', $estadoCliente, $respuesta); $respuesta['duration'] = $evento['duration']; } else { if ($evento['shortcall']) { restarContadorLlamada('Success', $estadoCliente, $respuesta); agregarContadorLlamada('ShortCall', $estadoCliente, $respuesta); } else { // Se actualiza Finished para actualizar estadísticas agregarContadorLlamada('Finished', $estadoCliente, $respuesta); $respuesta['duration'] = $evento['duration']; } } if (isset($respuesta['duration'])) { $estadoCliente['stats']['total_sec'] += $respuesta['duration']; if ($estadoCliente['stats']['max_duration'] < $respuesta['duration']) { $estadoCliente['stats']['max_duration'] = $respuesta['duration']; } } } break; } } } $estadoHash = generarEstadoHash($module_name, $estadoCliente); $respuesta['estadoClienteHash'] = $estadoHash; jsonflush($bSSE, $respuesta); $respuesta = crearRespuestaVacia(); } while ($bSSE && connection_status() == CONNECTION_NORMAL); $oPaloConsola->desconectarTodo(); }
function getAgentState($agent_number) { $oPaloConsola = new PaloSantoConsola('SIP/' . $agent_number); $estado = $oPaloConsola->estadoAgenteLogoneado(''); $oPaloConsola->desconectarTodo(); return $estado['callinfo']; }