This commit is contained in:
Lizandro Guarnizo
2026-02-03 21:30:55 -05:00
parent 44423adb32
commit 1aae148396
89 changed files with 8581 additions and 7687 deletions
+56 -7
View File
@@ -851,8 +851,9 @@ class BotService {
break;
case 'message':
// Enviar mensaje de respuesta
$this->whatsappService->sendTextMessage($phoneNumber, $option['action_value']);
// Enviar mensaje de respuesta (procesando saltos de línea)
$message = $this->processLineBreaks($option['action_value']);
$this->whatsappService->sendTextMessage($phoneNumber, $message);
$this->exitMenu($phoneNumber);
break;
@@ -864,6 +865,7 @@ class BotService {
case 'request_documents':
// Solicitar al usuario que envíe documentación y activar estado awaiting_documents
$message = $option['action_value'] ?: "Por favor, envíe los documentos o fotos requeridas.";
$message = $this->processLineBreaks($message);
$this->whatsappService->sendTextMessage($phoneNumber, $message);
try {
$stateSvc = new ConversationStateService();
@@ -891,6 +893,7 @@ class BotService {
case 'end':
// Finalizar conversación (comportamiento por defecto)
$message = $option['action_value'] ?: "Gracias por usar nuestro servicio. ¡Hasta pronto!";
$message = $this->processLineBreaks($message);
$this->whatsappService->sendTextMessage($phoneNumber, $message);
$this->exitMenu($phoneNumber);
// Pausar el bot para esta conversación por 3 minutos (antes eran 4 horas)
@@ -899,6 +902,20 @@ class BotService {
}
}
/**
* Procesar texto para respetar saltos de línea
* Convierte \n escapados a saltos reales
*/
private function processLineBreaks($text) {
if (empty($text)) return $text;
// Convertir \n escapados (cadena literal) a saltos de línea reales
$text = str_replace('\\n', "\n", $text);
$text = str_replace('\n', "\n", $text);
return $text;
}
/**
* Procesar llamada API externa
*/
@@ -934,7 +951,8 @@ class BotService {
);
if ($autoResponse) {
$this->whatsappService->sendTextMessage($phoneNumber, $autoResponse['response_text']);
$message = $this->processLineBreaks($autoResponse['response_text']);
$this->whatsappService->sendTextMessage($phoneNumber, $message);
// Si la keyword es 'menu', mostrar el menú
if ($keyword === 'menu' || $keyword === 'menú') {
@@ -1036,6 +1054,23 @@ class BotService {
$this->db->update('users', ['advisor_requested' => 1, 'bot_paused_until' => $pausedUntil, 'bot_enabled' => 0], 'phone_number = :phone', ['phone' => $phoneNumber]);
$this->whatsappService->sendTextMessage($phoneNumber, "🔔 Le hemos transferido a un asesor; le responderemos en breve.");
// Enviar automáticamente el menú de horario_asesor para que el cliente sepa cuándo esperar
try {
$horarioMenu = $this->db->fetch(
"SELECT id FROM menus WHERE name = :name AND is_active = 1",
['name' => 'horario_asesor']
);
if ($horarioMenu && !empty($horarioMenu['id'])) {
$this->showMenu($phoneNumber, $horarioMenu['id']);
error_log("[BotService] Sent horario_asesor menu to {$phoneNumber} after advisor request");
} else {
error_log("[BotService] horario_asesor menu not found when requesting advisor for {$phoneNumber}");
}
} catch (Exception $e) {
error_log('Failed to send horario_asesor menu on advisor request: ' . $e->getMessage());
}
if (function_exists('writeLog')) writeLog('INFO', "Advisor solicited for $phoneNumber until $pausedUntil");
} catch (Exception $e) {
error_log('requestAdvisor failed: ' . $e->getMessage());
@@ -1152,15 +1187,29 @@ class BotService {
if (function_exists('writeLog')) writeLog('INFO', "Operator {$operatorId} finished attending for {$phoneNumber}, survey={$template}");
// Ensure consistent behavior: release hold / clear flags when finishing attend
// Do NOT send the main menu nor notify the user that the conversation is resumed.
try {
// Release hold silently to avoid duplicate notification after finishing attend
// Send notification that conversation has been resumed, but do NOT auto-send the menu.
$this->releaseHold($phoneNumber, true);
// Intentionally not calling showMainMenu or sending a 'conversation resumed' message here.
$this->releaseHold($phoneNumber, false);
} catch (Exception $e) {
error_log('finishAttendConversation: releaseHold failed: ' . $e->getMessage());
}
// Enviar automáticamente el menú de horario_asesor después de finalizar
try {
$horarioMenu = $this->db->fetch(
"SELECT id FROM menus WHERE name = :name AND is_active = 1",
['name' => 'horario_asesor']
);
if ($horarioMenu && !empty($horarioMenu['id'])) {
$this->showMenu($phoneNumber, $horarioMenu['id']);
error_log("[BotService] Sent horario_asesor menu to {$phoneNumber} after finishing attend");
} else {
error_log("[BotService] horario_asesor menu not found for {$phoneNumber}");
}
} catch (Exception $e) {
error_log('Failed to send horario_asesor menu: ' . $e->getMessage());
}
} catch (Exception $e) {
error_log('finishAttendConversation failed: ' . $e->getMessage());
throw $e;