fix: Eventos AMI

This commit is contained in:
lukibeg 2025-12-20 10:49:22 -03:00
parent e907250ac1
commit 19df927f57
1 changed files with 53 additions and 48 deletions

View File

@ -98,49 +98,42 @@ public function handle(Request $request)
private function handleMemberStatus($agent, $data, $tenantId) private function handleMemberStatus($agent, $data, $tenantId)
{ {
// 1. A PAUSA TEM PRIORIDADE ABSOLUTA $isPaused = ($data['Paused'] ?? '0') == '1';
// Se o Asterisk diz que Paused é '1', o agente está pausado,
// não importa se o telefone está no gancho ou fora do gancho.
if (($data['Paused'] ?? '0') == '1') {
$agent->status = 'paused';
// Só atualizamos o motivo se o evento trouxer um motivo novo.
// O QueueMemberStatus as vezes não traz o motivo, então evitamos apagar o existente.
if (!empty($data['PausedReason'])) {
$agent->pause_reason = $data['PausedReason'];
} elseif (!$agent->pause_reason) {
$agent->pause_reason = 'Pausa'; // Fallback se estiver nulo
}
} else {
// 2. SE NÃO ESTÁ PAUSADO, OLHAMOS O STATUS DO DISPOSITIVO
$agent->pause_reason = null;
$asteriskStatus = $data['Status'] ?? null; $asteriskStatus = $data['Status'] ?? null;
$targetStatus = 'offline';
$targetReason = null;
if ($isPaused) {
$targetStatus = 'paused';
$targetReason = !empty($data['PausedReason']) ? $data['PausedReason'] : ($agent->pause_reason ?? 'Pausa');
} else {
$targetReason = null;
switch ($asteriskStatus) { switch ($asteriskStatus) {
case '1': // AST_DEVICE_NOT_INUSE (Livre) case '1':
$agent->status = 'available'; $targetStatus = 'available';
break; break;
case '2':
case '2': // AST_DEVICE_INUSE (Em uso / Falando) case '3':
case '3': // AST_DEVICE_BUSY (Ocupado) case '6':
case '6': // AST_DEVICE_RINGING (Tocando) $targetStatus = 'talking';
// Aqui mantemos 'talking' para ficar azul no dashboard
$agent->status = 'talking';
break; break;
case '5':
case '5': // AST_DEVICE_UNAVAILABLE (Offline / Cabo desconectado / Softphone fechado) $targetStatus = 'offline';
$agent->status = 'offline';
break; break;
default: default:
// Se vier status desconhecido (4, 0, etc), mantemos o atual ou definimos offline $targetStatus = 'offline';
// $agent->status = 'offline';
break; break;
} }
} }
// TRAVA DE IDEMPOTÊNCIA (Igual ao handlePause)
if ($agent->status === $targetStatus && $agent->pause_reason === $targetReason) {
return;
}
$agent->status = $targetStatus;
$agent->pause_reason = $targetReason;
$agent->last_status_change = now(); $agent->last_status_change = now();
$agent->save(); $agent->save();
@ -196,13 +189,25 @@ private function handleComplete($queue, $data)
private function handlePause($agent, $data, $tenantId) private function handlePause($agent, $data, $tenantId)
{ {
// Esse evento ocorre quando a ação de pausa é disparada
$isPaused = isset($data['Paused']) && $data['Paused'] == '1'; $isPaused = isset($data['Paused']) && $data['Paused'] == '1';
$targetStatus = $isPaused ? 'paused' : 'available'; // Se despausar, assume livre
$agent->status = $isPaused ? 'paused' : 'available'; $targetReason = null;
$agent->pause_reason = $isPaused ? ($data['Reason'] ?? 'Pausa') : null; if ($isPaused) {
$targetReason = $data['Reason'] ?? $data['PausedReason'] ?? 'Pausa';
if (trim($targetReason) === '') $targetReason = 'Pausa';
}
// --- TRAVA DE IDEMPOTÊNCIA ---
// Se o agente está em 10 filas, esse evento dispara 10 vezes.
// Se o status já for igual, IGNORA para não spamar o WebSocket.
if ($agent->status === $targetStatus && $agent->pause_reason === $targetReason) {
return;
}
$agent->status = $targetStatus;
$agent->pause_reason = $targetReason;
$agent->last_status_change = now(); $agent->last_status_change = now();
$agent->save(); $agent->save();
broadcast(new DashboardUpdate($tenantId)); broadcast(new DashboardUpdate($tenantId));