function manejarSesionActiva_checkStatus($module_name, $smarty, $sDirLocalPlantillas, $oPaloConsola, $estado) { $respuesta = array(); ignore_user_abort(true); set_time_limit(0); $sNombrePausa = NULL; $iDuracionLlamada = NULL; $iDuracionPausa = $iDuracionPausaActual = NULL; $estadoCliente = getParameter('clientstate'); // Validación del estado del cliente: // onhold break_id calltype campaign_id callid $estadoCliente['onhold'] = isset($estadoCliente['onhold']) ? $estadoCliente['onhold'] == 'true' : false; foreach (array('break_id', 'calltype', 'campaign_id', 'callid') as $k) { if (!isset($estadoCliente[$k]) || $estadoCliente[$k] == 'null') { $estadoCliente[$k] = NULL; } } if (is_null($estadoCliente['calltype'])) { $estadoCliente['campaign_id'] = $estadoCliente['callid'] = NULL; } elseif (is_null($estadoCliente['callid'])) { $estadoCliente['campaign_id'] = $estadoCliente['calltype'] = NULL; } elseif (is_null($estadoCliente['campaign_id']) && $estadoCliente['calltype'] != 'incoming') { $estadoCliente['calltype'] = $estadoCliente['callid'] = NULL; } // 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'); } // Respuesta inmediata si el agente ya no está logoneado if ($estado['estadofinal'] != 'logged-in') { // Respuesta inmediata si el agente ya no está logoneado jsonflush($bSSE, array('event' => 'logged-out')); return; } // Verificación de la consistencia del estado de break if (!is_null($estado['pauseinfo'])) { $sNombrePausa = $estado['pauseinfo']['pausename']; $iDuracionPausaActual = time() - strtotime($estado['pauseinfo']['pausestart']); $iDuracionPausa = $iDuracionPausaActual + $_SESSION['callcenter']['break_acumulado']; } else { /* Si esta condición se cumple, entonces se ha perdido el evento * pauseexit durante la espera en manejarSesionActiva_checkStatus(). * Se hace la suposición de que el refresco ocurre poco después de * que termina el break, y que por lo tanto el error al usar time() * como fin del break es pequeño. */ if (!is_null($_SESSION['callcenter']['break_iniciado'])) { $_SESSION['callcenter']['break_acumulado'] += time() - strtotime($_SESSION['callcenter']['break_iniciado']); } $_SESSION['callcenter']['break_iniciado'] = NULL; } if (!is_null($estado['pauseinfo']) && (is_null($estadoCliente['break_id']) || $estadoCliente['break_id'] != $estado['pauseinfo']['pauseid'])) { // La consola debe de entrar en break $respuesta[] = construirRespuesta_breakenter($estado['pauseinfo']['pauseid']); } elseif (!is_null($estadoCliente['break_id']) && is_null($estado['pauseinfo'])) { // La consola debe de salir del break $respuesta[] = construirRespuesta_breakexit(); } // Verificación de la consistencia del estado de hold if (!$estadoCliente['onhold'] && $estado['onhold']) { // La consola debe de entrar en hold $respuesta[] = construirRespuesta_holdenter(); } elseif ($estadoCliente['onhold'] && !$estado['onhold']) { // La consola debe de salir de hold $respuesta[] = construirRespuesta_holdexit(); } if (!is_null($estado['callinfo'])) { $iDuracionLlamada = time() - strtotime($estado['callinfo']['linkstart']); } // Verificación de atención a llamada if (!is_null($estado['callinfo']) && (is_null($estadoCliente['calltype']) || $estadoCliente['calltype'] != $estado['callinfo']['calltype'] || $estadoCliente['campaign_id'] != $estado['callinfo']['campaign_id'] || $estadoCliente['callid'] != $estado['callinfo']['callid'])) { // Información sobre la llamada conectada $infoLlamada = $oPaloConsola->leerInfoLlamada($estado['callinfo']['calltype'], $estado['callinfo']['campaign_id'], $estado['callinfo']['callid']); // Leer información del formulario de la campaña if ($estado['callinfo']['calltype'] == 'incoming' && is_null($estado['callinfo']['campaign_id'])) { $infoCampania['forms'] = NULL; } else { $infoCampania = $oPaloConsola->leerInfoCampania($estado['callinfo']['calltype'], $estado['callinfo']['campaign_id']); } // Almacenar para regenerar formulario $_SESSION['callcenter']['ultimo_calltype'] = $estado['callinfo']['calltype']; $_SESSION['callcenter']['ultimo_callid'] = $estado['callinfo']['callid']; $_SESSION['callcenter']['ultimo_callsurvey']['call_survey'] = $infoLlamada['call_survey']; $_SESSION['callcenter']['ultimo_campaignform']['forms'] = $infoCampania['forms']; $respuesta[] = construirRespuesta_agentlinked($smarty, $sDirLocalPlantillas, $oPaloConsola, $estado['callinfo'], $infoLlamada, $infoCampania); } elseif (!is_null($estadoCliente['calltype']) && is_null($estado['callinfo'])) { // La consola dejó de atender una llamada $respuesta[] = construirRespuesta_agentunlinked(); } // Ciclo de verificación para Server-sent Events $sAgente = 'Agent/' . $_SESSION['callcenter']['agente']; $iTimeoutPoll = PaloSantoConsola::recomendarIntervaloEsperaAjax(); $bReinicioSesion = FALSE; do { $oPaloConsola->desconectarEspera(); // Se inicia espera larga con el navegador... session_commit(); $iTimestampInicio = time(); $respuestaEventos = array(); while (connection_status() == CONNECTION_NORMAL && count($respuestaEventos) <= 0 && count($respuesta) <= 0 && time() - $iTimestampInicio < $iTimeoutPoll) { $listaEventos = $oPaloConsola->esperarEventoSesionActiva(); if (is_null($listaEventos)) { // Ocurrió una excepción al esperar eventos @session_start(); $respuesta[] = array('event' => 'logged-out'); // Eliminar la información de login $_SESSION['callcenter'] = generarEstadoInicial(); $bReinicioSesion = TRUE; break; } foreach ($listaEventos as $evento) { if (isset($evento['agent_number']) && $evento['agent_number'] == $sAgente) { switch ($evento['event']) { case 'agentloggedout': // Reiniciar la sesión para poder modificar las variables @session_start(); $respuesta[] = array('event' => 'logged-out'); // Eliminar la información de login $_SESSION['callcenter'] = generarEstadoInicial(); $bReinicioSesion = TRUE; break; case 'pausestart': unset($respuestaEventos[$evento['pause_class']]); switch ($evento['pause_class']) { case 'break': if (is_null($estadoCliente['break_id']) || $estadoCliente['break_id'] != $evento['pause_type']) { $sNombrePausa = $evento['pause_name']; $respuestaEventos['break'] = construirRespuesta_breakenter($evento['pause_type']); } @session_start(); $iDuracionPausaActual = time() - strtotime($evento['pause_start']); $iDuracionPausa = $iDuracionPausaActual + $_SESSION['callcenter']['break_acumulado']; $_SESSION['callcenter']['break_iniciado'] = $evento['pause_start']; break; case 'hold': if (!$estadoCliente['onhold']) { $respuestaEventos['hold'] = construirRespuesta_holdenter(); } break; } break; case 'pauseend': unset($respuestaEventos[$evento['pause_class']]); switch ($evento['pause_class']) { case 'break': if (!is_null($estadoCliente['break_id'])) { $respuestaEventos['break'] = construirRespuesta_breakexit(); } @session_start(); $_SESSION['callcenter']['break_acumulado'] += $evento['pause_duration']; $_SESSION['callcenter']['break_iniciado'] = NULL; break; case 'hold': if ($estadoCliente['onhold']) { $respuestaEventos['hold'] = construirRespuesta_holdexit(); } break; } break; case 'agentlinked': unset($respuestaEventos['llamada']); /* Actualizar la interfaz si entra una nueva llamada, o si * la llamada activa anterior es reemplazada. */ if (is_null($estadoCliente['calltype']) || $estadoCliente['calltype'] != $evento['call_type'] || $estadoCliente['campaign_id'] != $evento['campaign_id'] || $estadoCliente['callid'] != $evento['call_id']) { $nuevoEstado = array('calltype' => $evento['call_type'], 'campaign_id' => $evento['campaign_id'], 'linkstart' => $evento['datetime_linkstart'], 'callid' => $evento['call_id'], 'callnumber' => $evento['phone']); $iDuracionLlamada = time() - strtotime($nuevoEstado['linkstart']); // Leer información del formulario de la campaña if ($nuevoEstado['calltype'] == 'incoming' && is_null($nuevoEstado['campaign_id'])) { $infoCampania['forms'] = NULL; } else { $infoCampania = $oPaloConsola->leerInfoCampania($nuevoEstado['calltype'], $nuevoEstado['campaign_id']); } // Almacenar para regenerar formulario @session_start(); $_SESSION['callcenter']['ultimo_calltype'] = $nuevoEstado['calltype']; $_SESSION['callcenter']['ultimo_callid'] = $nuevoEstado['callid']; $_SESSION['callcenter']['ultimo_callsurvey']['call_survey'] = $evento['call_survey']; $_SESSION['callcenter']['ultimo_campaignform']['forms'] = $infoCampania['forms']; $respuestaEventos['llamada'] = construirRespuesta_agentlinked($smarty, $sDirLocalPlantillas, $oPaloConsola, $nuevoEstado, $evento, $infoCampania); } break; case 'agentunlinked': unset($respuestaEventos['llamada']); if (!is_null($estadoCliente['calltype'])) { $respuestaEventos['llamada'] = construirRespuesta_agentunlinked(); } break; } } } } // while(...) // Sólo debe haber hasta un evento de llamada, de break, de hold if (isset($respuestaEventos['break'])) { $respuesta[] = $respuestaEventos['break']; } if (isset($respuestaEventos['hold'])) { $respuesta[] = $respuestaEventos['hold']; } if (isset($respuestaEventos['llamada'])) { $respuesta[] = $respuestaEventos['llamada']; } // Agregar los textos a cambiar en la interfaz $sDescInicial = describirEstadoBarra($estadoCliente); $estadoFinal = $estadoCliente; foreach ($respuesta as $evento) { switch ($evento['event']) { case 'holdenter': $estadoCliente['onhold'] = TRUE; break; case 'holdexit': $estadoCliente['onhold'] = FALSE; break; case 'breakenter': $estadoFinal['break_id'] = $evento['break_id']; $estadoCliente['break_id'] = $evento['break_id']; break; case 'breakexit': $estadoFinal['break_id'] = NULL; $estadoCliente['break_id'] = NULL; break; case 'agentlinked': $estadoFinal['calltype'] = $evento['calltype']; $estadoCliente['calltype'] = $evento['calltype']; $estadoCliente['campaign_id'] = $evento['campaign_id']; $estadoCliente['callid'] = $evento['callid']; break; case 'agentunlinked': $estadoFinal['calltype'] = NULL; $estadoCliente['calltype'] = NULL; $estadoCliente['campaign_id'] = NULL; $estadoCliente['callid'] = NULL; break; } } $sDescFinal = describirEstadoBarra($estadoFinal); $iPosEvento = count($respuesta) - 1; if ($iPosEvento >= 0 && $sDescInicial != $sDescFinal) { switch ($sDescFinal) { case 'llamada': $respuesta[$iPosEvento]['txt_estado_agente_inicial'] = _tr('Đang có cuộc gọi đến'); $respuesta[$iPosEvento]['class_estado_agente_inicial'] = 'elastix-callcenter-class-estado-activo'; $respuesta[$iPosEvento]['timer_seconds'] = $iDuracionLlamada; break; case 'break': $respuesta[$iPosEvento]['txt_estado_agente_inicial'] = _tr('On break') . ': ' . $sNombrePausa; $respuesta[$iPosEvento]['class_estado_agente_inicial'] = 'elastix-callcenter-class-estado-break'; $respuesta[$iPosEvento]['timer_seconds'] = $iDuracionPausa; break; case 'ocioso': $respuesta[$iPosEvento]['txt_estado_agente_inicial'] = _tr('No active call'); $respuesta[$iPosEvento]['class_estado_agente_inicial'] = 'elastix-callcenter-class-estado-ocioso'; $respuesta[$iPosEvento]['timer_seconds'] = ''; break; } } jsonflush($bSSE, $respuesta); $respuesta = array(); } while ($bSSE && !$bReinicioSesion && connection_status() == CONNECTION_NORMAL); $oPaloConsola->desconectarTodo(); }
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 agent_monitoring_checkStatus($module_name, $smarty, $sDirLocalPlantillas, $oPaloConsola) { $respuesta = array(); //return 'test'; 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; } } foreach (array_keys($estadoCliente) as $k) { $estadoCliente[$k]['oncallupdate'] = $estadoCliente[$k]['oncallupdate'] == 'true'; } // 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'; jsonflush($bSSE, $respuesta); $oPaloConsola->desconectarTodo(); return; } // Estado del lado del servidor $estadoMonitor = $oPaloConsola->listarEstadoMonitoreoAgentes(); if (!is_array($estadoMonitor)) { $respuesta['error'] = $oPaloConsola->errMsg; jsonflush($bSSE, $respuesta); $oPaloConsola->desconectarTodo(); return; } //tri // Acumular inmediatamente las filas que son distintas en estado ksort($estadoMonitor); $estadoMonitor = mergeQueueAgent($estadoMonitor); $jsonData = contructDataJSON($estadoMonitor); foreach ($jsonData as $jsonKey => $jsonRow) { if (isset($estadoCliente[$jsonKey])) { if ($estadoCliente[$jsonKey]['agentstatus'] != $jsonRow['agentstatus'] || $estadoCliente[$jsonKey]['oncallupdate'] != $jsonRow['oncallupdate']) { $respuesta[$jsonKey] = $jsonRow; $estadoCliente[$jsonKey]['agentstatus'] = $jsonRow['agentstatus']; $estadoCliente[$jsonKey]['oncallupdate'] = $jsonRow['oncallupdate']; unset($respuesta[$jsonKey]['agentname']); } } } $iTimeoutPoll = PaloSantoConsola::recomendarIntervaloEsperaAjax(); do { $oPaloConsola->desconectarEspera(); // Se inicia espera larga con el navegador... session_commit(); $iTimestampInicio = time(); while (connection_status() == CONNECTION_NORMAL && count($respuesta) <= 0 && time() - $iTimestampInicio < $iTimeoutPoll) { $listaEventos = $oPaloConsola->esperarEventoSesionActiva(); if (is_null($listaEventos)) { $respuesta['error'] = $oPaloConsola->errMsg; jsonflush($bSSE, $respuesta); $oPaloConsola->desconectarTodo(); return; } $iTimestampActual = time(); foreach ($listaEventos as $evento) { $sNumeroAgente = $sCanalAgente = $evento['agent_number']; if (substr($sNumeroAgente, 0, 4) == 'SIP/') { $sNumeroAgente = substr($sNumeroAgente, 4); } //$sCanalAgente = str_replace('/','_',$sCanalAgente); switch ($evento['event']) { case 'agentloggedin': // foreach (array_keys($estadoMonitor) as $sAgent) { if (isset($estadoMonitor[$sCanalAgente])) { $jsonKey = 'Agent_' . $sNumeroAgente; if (isset($jsonData[$jsonKey]) && $jsonData[$jsonKey]['agentstatus'] == 'offline') { // Estado en el estado de monitor $estadoMonitor[$sCanalAgente]['agentstatus'] = 'online'; $estadoMonitor[$sCanalAgente]['lastsessionstart'] = date('Y-m-d H:i:s', $iTimestampActual); $estadoMonitor[$sCanalAgente]['lastsessionend'] = NULL; if (!is_null($estadoMonitor[$sCanalAgente]['lastpausestart']) && is_null($estadoMonitor[$sCanalAgente]['lastpauseend'])) { $estadoMonitor[$sCanalAgente]['lastpauseend'] = date('Y-m-d H:i:s', $iTimestampActual); } $estadoMonitor[$sCanalAgente]['linkstart'] = NULL; // Estado en la estructura JSON $jsonData[$jsonKey]['agentstatus'] = $estadoMonitor[$sCanalAgente]['agentstatus']; $jsonData[$jsonKey]['sec_laststatus'] = 0; $jsonData[$jsonKey]['oncallupdate'] = FALSE; // Get customer information //tri $agentState = getAgentState($jsonRow['agent_number']); $arrSmartyData[$jsonKey]['callnumber'] = $agentState['callnumber']; $arrSmartyData[$jsonKey]['callid'] = $agentState['callid']; $customer = getCustomer($arrSmartyData[$jsonKey]['callnumber']); $arrSmartyData[$jsonKey]['customer'] = $customer ? $customer : $arrSmartyData[$jsonKey]['callnumber']; // Estado del cliente $estadoCliente[$jsonKey]['agentstatus'] = $jsonData[$jsonKey]['agentstatus']; $estadoCliente[$jsonKey]['oncallupdate'] = $jsonData[$jsonKey]['oncallupdate']; // Estado a emitir al cliente $respuesta[$jsonKey] = $jsonData[$jsonKey]; unset($respuesta[$jsonKey]['agentname']); } } // } break; case 'agentloggedout': //foreach (array_keys($estadoMonitor) as $sAgent) { if (isset($estadoMonitor[$sCanalAgente])) { $jsonKey = 'Agent_' . $sNumeroAgente; if (isset($jsonData[$jsonKey]) && $jsonData[$jsonKey]['agentstatus'] != 'offline') { // Estado en el estado de monitor $estadoMonitor[$sCanalAgente]['agentstatus'] = 'offline'; $estadoMonitor[$sCanalAgente]['lastsessionend'] = date('Y-m-d H:i:s', $iTimestampActual); if (!is_null($estadoMonitor[$sCanalAgente]['lastpausestart']) && is_null($estadoMonitor[$sCanalAgente]['lastpauseend'])) { $estadoMonitor[$sCanalAgente]['lastpauseend'] = date('Y-m-d H:i:s', $iTimestampActual); } $estadoMonitor[$sCanalAgente]['linkstart'] = NULL; if (!is_null($estadoMonitor[$sCanalAgente]['lastsessionstart'])) { $iTimestampInicio = strtotime($estadoMonitor[$sCanalAgente]['lastsessionstart']); $iDuracionSesion = $iTimestampActual - $iTimestampInicio; if ($iDuracionSesion >= 0) { $estadoMonitor[$sCanalAgente]['logintime'] += $iDuracionSesion; } } // Estado en la estructura JSON $jsonData[$jsonKey]['agentstatus'] = $estadoMonitor[$sCanalAgente]['agentstatus']; $jsonData[$jsonKey]['sec_laststatus'] = 0; $jsonData[$jsonKey]['oncallupdate'] = FALSE; $jsonData[$jsonKey]['logintime'] = $estadoMonitor[$sCanalAgente]['logintime']; // Estado del cliente $estadoCliente[$jsonKey]['agentstatus'] = $jsonData[$jsonKey]['agentstatus']; $estadoCliente[$jsonKey]['oncallupdate'] = $jsonData[$jsonKey]['oncallupdate']; // Estado a emitir al cliente $respuesta[$jsonKey] = $jsonData[$jsonKey]; unset($respuesta[$jsonKey]['agentname']); } } // } break; case 'pausestart': //foreach (array_keys($estadoMonitor) as $sAgent) { if (isset($estadoMonitor[$sCanalAgente])) { $jsonKey = 'Agent_' . $sNumeroAgente; if (isset($jsonData[$jsonKey]) && $jsonData[$jsonKey]['agentstatus'] != 'offline') { // Estado en el estado de monitor if ($estadoMonitor[$sCanalAgente]['agentstatus'] != 'oncall') { $estadoMonitor[$sCanalAgente]['agentstatus'] = 'paused'; } $estadoMonitor[$sCanalAgente]['lastpausestart'] = date('Y-m-d H:i:s', $iTimestampActual); $estadoMonitor[$sCanalAgente]['lastpauseend'] = NULL; // Estado en la estructura JSON $jsonData[$jsonKey]['agentstatus'] = $estadoMonitor[$sCanalAgente]['agentstatus']; if ($jsonData[$jsonKey]['agentstatus'] == 'oncall') { if (!is_null($estadoMonitor[$sCanalAgente]['linkstart'])) { $iTimestampInicio = strtotime($estadoMonitor[$sCanalAgente]['linkstart']); $iDuracionLlamada = $iTimestampActual - $iTimestampInicio; if ($iDuracionLlamada >= 0) { $jsonData[$jsonKey]['sec_laststatus'] = $iDuracionLlamada; $jsonData[$jsonKey]['sec_calls'] = $estadoMonitor[$sCanalAgente]['sec_calls'] + $iDuracionLlamada; } } } else { $jsonData[$jsonKey]['sec_laststatus'] = 0; } $jsonData[$jsonKey]['logintime'] = $estadoMonitor[$sCanalAgente]['logintime']; if (!is_null($estadoMonitor[$sCanalAgente]['lastsessionstart'])) { $iTimestampInicio = strtotime($estadoMonitor[$sCanalAgente]['lastsessionstart']); $iDuracionSesion = $iTimestampActual - $iTimestampInicio; if ($iDuracionSesion >= 0) { $jsonData[$jsonKey]['logintime'] += $iDuracionSesion; } } // Estado del cliente $estadoCliente[$jsonKey]['agentstatus'] = $jsonData[$jsonKey]['agentstatus']; $estadoCliente[$jsonKey]['oncallupdate'] = $jsonData[$jsonKey]['oncallupdate']; // Estado a emitir al cliente $respuesta[$jsonKey] = $jsonData[$jsonKey]; unset($respuesta[$jsonKey]['agentname']); } } // } break; case 'pauseend': //foreach (array_keys($estadoMonitor) as $sAgent) { if (isset($estadoMonitor[$sCanalAgente])) { $jsonKey = 'Agent_' . $sNumeroAgente; if (isset($jsonData[$jsonKey]) && $jsonData[$jsonKey]['agentstatus'] != 'offline') { // Estado en el estado de monitor if ($estadoMonitor[$sCanalAgente]['agentstatus'] != 'oncall') { $estadoMonitor[$sCanalAgente]['agentstatus'] = 'online'; } $estadoMonitor[$sCanalAgente]['lastpauseend'] = date('Y-m-d H:i:s', $iTimestampActual); // Estado en la estructura JSON $jsonData[$jsonKey]['agentstatus'] = $estadoMonitor[$sCanalAgente]['agentstatus']; if ($jsonData[$jsonKey]['agentstatus'] == 'oncall') { if (!is_null($estadoMonitor[$sCanalAgente]['linkstart'])) { $iTimestampInicio = strtotime($estadoMonitor[$sCanalAgente]['linkstart']); $iDuracionLlamada = $iTimestampActual - $iTimestampInicio; if ($iDuracionLlamada >= 0) { $jsonData[$jsonKey]['sec_laststatus'] = $iDuracionLlamada; $jsonData[$jsonKey]['sec_calls'] = $estadoMonitor[$sCanalAgente]['sec_calls'] + $iDuracionLlamada; } } } else { $jsonData[$jsonKey]['sec_laststatus'] = $iTimestampActual - strtotime($estadoMonitor[$sCanalAgente]['lastsessionstart']); } $jsonData[$jsonKey]['logintime'] = $estadoMonitor[$sCanalAgente]['logintime']; if (!is_null($estadoMonitor[$sCanalAgente]['lastsessionstart'])) { $iTimestampInicio = strtotime($estadoMonitor[$sCanalAgente]['lastsessionstart']); $iDuracionSesion = $iTimestampActual - $iTimestampInicio; if ($iDuracionSesion >= 0) { $jsonData[$jsonKey]['logintime'] += $iDuracionSesion; } } // Estado del cliente $estadoCliente[$jsonKey]['agentstatus'] = $jsonData[$jsonKey]['agentstatus']; $estadoCliente[$jsonKey]['oncallupdate'] = $jsonData[$jsonKey]['oncallupdate']; // Estado a emitir al cliente $respuesta[$jsonKey] = $jsonData[$jsonKey]; unset($respuesta[$jsonKey]['agentname']); } } //} break; case 'agentlinked': // Averiguar la cola por la que entró la llamada nueva $sCallQueue = $evento['queue']; if (is_null($sCallQueue)) { $infoCampania = $oPaloConsola->leerInfoCampania($evento['call_type'], $evento['campaign_id']); if (!is_null($infoCampania)) { $sCallQueue = $infoCampania['queue']; } } if (isset($estadoMonitor[$sCanalAgente])) { $jsonKey = 'Agent_' . $sNumeroAgente; if (isset($jsonData[$jsonKey]) && $jsonData[$jsonKey]['agentstatus'] != 'offline') { // Estado en el estado de monitor $estadoMonitor[$sCanalAgente]['agentstatus'] = 'oncall'; $estadoMonitor[$sCanalAgente]['linkstart'] = NULL; $estadoMonitor[$sCanalAgente]['num_calls']++; $estadoMonitor[$sCanalAgente]['linkstart'] = $evento['datetime_linkstart']; // Estado en la estructura JSON $jsonData[$jsonKey]['agentstatus'] = $estadoMonitor[$sCanalAgente]['agentstatus']; $jsonData[$jsonKey]['sec_laststatus'] = is_null($estadoMonitor[$sCanalAgente]['linkstart']) ? NULL : $iTimestampActual - strtotime($estadoMonitor[$sCanalAgente]['linkstart']); $jsonData[$jsonKey]['num_calls'] = $estadoMonitor[$sCanalAgente]['num_calls']; $jsonData[$jsonKey]['sec_calls'] = $estadoMonitor[$sCanalAgente]['sec_calls'] + (is_null($jsonData[$jsonKey]['sec_laststatus']) ? 0 : $jsonData[$jsonKey]['sec_laststatus']); $jsonData[$jsonKey]['oncallupdate'] = !is_null($estadoMonitor[$sCanalAgente]['linkstart']); $jsonData[$jsonKey]['logintime'] = $estadoMonitor[$sCanalAgente]['logintime']; if (!is_null($estadoMonitor[$sCanalAgente]['lastsessionstart'])) { $iTimestampInicio = strtotime($estadoMonitor[$sCanalAgente]['lastsessionstart']); $iDuracionSesion = $iTimestampActual - $iTimestampInicio; if ($iDuracionSesion >= 0) { $jsonData[$jsonKey]['logintime'] += $iDuracionSesion; } } $jsonData[$jsonKey]['linkqueue'] = $evento['queue']; //tri $customer = getCustomer($evento['phone']); $jsonData[$jsonKey]['customer'] = $customer ? $customer : $evento['phone']; // Estado del cliente $estadoCliente[$jsonKey]['agentstatus'] = $jsonData[$jsonKey]['agentstatus']; $estadoCliente[$jsonKey]['oncallupdate'] = $jsonData[$jsonKey]['oncallupdate']; // Estado a emitir al cliente $respuesta[$jsonKey] = $jsonData[$jsonKey]; unset($respuesta[$jsonKey]['agentname']); //$respuesta = $evento; } } break; case 'agentunlinked': //foreach (array_keys($estadoMonitor) as $sAgent) { if (isset($estadoMonitor[$sCanalAgente])) { $jsonKey = 'Agent_' . $sNumeroAgente; if (isset($jsonData[$jsonKey]) && $jsonData[$jsonKey]['agentstatus'] != 'offline') { // Estado en el estado de monitor $estadoMonitor[$sCanalAgente]['agentstatus'] = !is_null($estadoMonitor[$sCanalAgente]['lastpausestart']) && is_null($estadoMonitor[$sCanalAgente]['lastpauseend']) ? 'paused' : 'online'; if (!is_null($estadoMonitor[$sCanalAgente]['linkstart'])) { $iTimestampInicio = strtotime($estadoMonitor[$sCanalAgente]['linkstart']); $iDuracionLlamada = $iTimestampActual - $iTimestampInicio; if ($iDuracionLlamada >= 0) { $estadoMonitor[$sCanalAgente]['sec_calls'] += $iDuracionLlamada; } } $estadoMonitor[$sCanalAgente]['linkstart'] = NULL; // Estado en la estructura JSON $jsonData[$jsonKey]['agentstatus'] = $estadoMonitor[$sCanalAgente]['agentstatus']; if ($jsonData[$jsonKey]['agentstatus'] == 'paused') { $jsonData[$jsonKey]['sec_laststatus'] = $iTimestampActual - strtotime($estadoMonitor[$sCanalAgente]['lastpausestart']); } else { $jsonData[$jsonKey]['sec_laststatus'] = $iTimestampActual - strtotime($estadoMonitor[$sCanalAgente]['lastsessionstart']); } $jsonData[$jsonKey]['num_calls'] = $estadoMonitor[$sCanalAgente]['num_calls']; $jsonData[$jsonKey]['sec_calls'] = $estadoMonitor[$sCanalAgente]['sec_calls']; $jsonData[$jsonKey]['oncallupdate'] = FALSE; $jsonData[$jsonKey]['logintime'] = $estadoMonitor[$sCanalAgente]['logintime']; if (!is_null($estadoMonitor[$sCanalAgente]['lastsessionstart'])) { $iTimestampInicio = strtotime($estadoMonitor[$sCanalAgente]['lastsessionstart']); $iDuracionSesion = $iTimestampActual - $iTimestampInicio; if ($iDuracionSesion >= 0) { $jsonData[$jsonKey]['logintime'] += $iDuracionSesion; } } // Estado del cliente $estadoCliente[$jsonKey]['agentstatus'] = $jsonData[$jsonKey]['agentstatus']; $estadoCliente[$jsonKey]['oncallupdate'] = $jsonData[$jsonKey]['oncallupdate']; // Estado a emitir al cliente $respuesta[$jsonKey] = $jsonData[$jsonKey]; unset($respuesta[$jsonKey]['agentname']); } } //} break; } } } if (count($respuesta) > 0) { @session_start(); $estadoHash = generarEstadoHash($module_name, $estadoCliente); $respuesta['estadoClienteHash'] = $estadoHash; session_commit(); } //$respuesta = $estadoMonitor; jsonflush($bSSE, $respuesta); jsonflush($bSSE, var_dump($respuesta)); $respuesta = array(); } while ($bSSE && connection_status() == CONNECTION_NORMAL); $oPaloConsola->desconectarTodo(); }