From 845762f9162623d65578c608ae337632ae67eaac Mon Sep 17 00:00:00 2001 From: lizandrogd <77708265+lizandrogd@users.noreply.github.com> Date: Wed, 21 Jan 2026 02:45:59 -0500 Subject: [PATCH] up --- api/get_conversations.php | 16 +++--- api/get_templates.php | 3 +- api/release_hold.php | 29 +++++++++++ api/set_bot_enabled.php | 24 +++++++++ conversations.php | 70 +++++++++++++++++++++++++- scripts/add_user_bot_enabled.php | 15 ++++++ scripts/describe_message_templates.php | 9 ++++ scripts/test_bot_enabled.php | 31 ++++++++++++ scripts/test_get_templates.php | 13 +++++ services/BotService.php | 5 ++ 10 files changed, 207 insertions(+), 8 deletions(-) create mode 100644 api/release_hold.php create mode 100644 api/set_bot_enabled.php create mode 100644 scripts/add_user_bot_enabled.php create mode 100644 scripts/describe_message_templates.php create mode 100644 scripts/test_bot_enabled.php create mode 100644 scripts/test_get_templates.php diff --git a/api/get_conversations.php b/api/get_conversations.php index 48688df..fd8365f 100644 --- a/api/get_conversations.php +++ b/api/get_conversations.php @@ -21,6 +21,8 @@ try { COALESCE(u.name, u.phone_number) AS name, u.phone_number, u.avatar_url, + u.bot_enabled, + u.on_hold, lm.message_id AS last_message_id, lm.content AS last_message, lm.direction AS direction, @@ -48,15 +50,17 @@ try { // Formatear datos para el frontend $conversations = array_map(function($conv) { return [ - 'id' => intval($conv['id']), 'user_id' => intval($conv['user_id']), - 'content' => $conv['content'] ?? '', + 'name' => $conv['name'] ?? $conv['phone_number'], + 'phone_number' => $conv['phone_number'], + 'avatar_url' => $conv['avatar_url'] ?? null, + 'last_message' => $conv['last_message'] ?? '', + 'last_time' => $conv['last_time'] ?? null, 'direction' => $conv['direction'] ?? 'incoming', 'message_type' => $conv['message_type'] ?? 'text', - 'status' => $conv['status'] ?? 'sent', - 'created_at' => $conv['created_at'], - 'phone_number' => $conv['phone_number'], - 'name' => $conv['name'] ?? $conv['phone_number'] + 'unread_count' => intval($conv['unread_count'] ?? 0), + 'bot_enabled' => isset($conv['bot_enabled']) ? (bool)$conv['bot_enabled'] : true, + 'on_hold' => isset($conv['on_hold']) ? (bool)$conv['on_hold'] : false ]; }, $conversations); diff --git a/api/get_templates.php b/api/get_templates.php index 62e0e11..4ba62a3 100644 --- a/api/get_templates.php +++ b/api/get_templates.php @@ -27,7 +27,8 @@ try { $approvedOnly = isset($_GET['approved_only']) && $_GET['approved_only'] == '1'; $limit = isset($_GET['limit']) ? intval($_GET['limit']) : null; - $sql = "SELECT id, name, template_name, language_code, category, status, body_text, created_at FROM message_templates"; + // Ajuste: some DBs may not have body_text column; omit it to avoid SQL errors + $sql = "SELECT id, name, template_name, language_code, category, status, created_at FROM message_templates"; $params = []; if ($approvedOnly) { diff --git a/api/release_hold.php b/api/release_hold.php new file mode 100644 index 0000000..be7a4c1 --- /dev/null +++ b/api/release_hold.php @@ -0,0 +1,29 @@ + false, 'error' => 'user_id required']); + exit; + } + + $db = Database::getInstance(); + $user = $db->fetch('SELECT phone_number FROM users WHERE id = :id', ['id' => $userId]); + if (!$user) { + http_response_code(404); + echo json_encode(['success' => false, 'error' => 'User not found']); + exit; + } + + $db->update('users', ['on_hold' => 0], 'id = :id', ['id' => $userId]); + + echo json_encode(['success' => true]); +} catch (Exception $e) { + http_response_code(500); + echo json_encode(['success' => false, 'error' => $e->getMessage()]); +} diff --git a/api/set_bot_enabled.php b/api/set_bot_enabled.php new file mode 100644 index 0000000..1c433ba --- /dev/null +++ b/api/set_bot_enabled.php @@ -0,0 +1,24 @@ + false, 'error' => 'user_id and enabled required']); + exit; + } + + $db = Database::getInstance(); + $db->update('users', ['bot_enabled' => $enabled], 'id = :id', ['id' => $userId]); + + echo json_encode(['success' => true]); +} catch (Exception $e) { + http_response_code(500); + echo json_encode(['success' => false, 'error' => $e->getMessage()]); +} diff --git a/conversations.php b/conversations.php index 126b0de..4286425 100644 --- a/conversations.php +++ b/conversations.php @@ -471,10 +471,16 @@
-
Usuario
+
Usuario + +
+1234567890 +
+
+ +
@@ -728,6 +734,68 @@ }); document.querySelector(`[data-user-id="${userId}"]`)?.classList.add('active'); + // Actualizar estado del toggle del bot según datos de la conversación + const conv = this.conversations.find(c => c.user_id === userId); + if (conv) { + const btn = document.getElementById('bot-toggle'); + const holdIndicator = document.getElementById('hold-indicator'); + const releaseBtn = document.getElementById('release-hold-btn'); + + if (holdIndicator) { + holdIndicator.style.display = conv.on_hold ? 'inline' : 'none'; + } + + if (releaseBtn) { + releaseBtn.style.display = conv.on_hold ? 'inline-block' : 'none'; + releaseBtn.onclick = async () => { + try { + const resp = await fetch('api/release_hold.php', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ user_id: userId }) + }); + const json = await resp.json(); + if (json && json.success) { + conv.on_hold = false; + holdIndicator.style.display = 'none'; + releaseBtn.style.display = 'none'; + await this.loadConversations(); + } else { + alert('Error al liberar la espera'); + } + } catch (e) { + console.error('Error releasing hold', e); + } + }; + } + + if (btn) { + btn.textContent = conv.bot_enabled ? 'Bot: On' : 'Bot: Off'; + btn.classList.toggle('btn-outline-danger', !conv.bot_enabled); + btn.classList.toggle('btn-outline-secondary', conv.bot_enabled); + btn.onclick = async () => { + try { + const resp = await fetch('api/set_bot_enabled.php', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ user_id: userId, enabled: conv.bot_enabled ? 0 : 1 }) + }); + const json = await resp.json(); + if (json && json.success) { + conv.bot_enabled = !conv.bot_enabled; + btn.textContent = conv.bot_enabled ? 'Bot: On' : 'Bot: Off'; + btn.classList.toggle('btn-outline-danger', !conv.bot_enabled); + btn.classList.toggle('btn-outline-secondary', conv.bot_enabled); + } else { + alert('Error al cambiar el estado del bot'); + } + } catch (e) { + console.error('Error toggling bot', e); + } + }; + } + } + // Cargar mensajes await this.loadMessages(userId); // Cargar respuestas rápidas diff --git a/scripts/add_user_bot_enabled.php b/scripts/add_user_bot_enabled.php new file mode 100644 index 0000000..4aeed83 --- /dev/null +++ b/scripts/add_user_bot_enabled.php @@ -0,0 +1,15 @@ +fetch("SHOW COLUMNS FROM users LIKE 'bot_enabled'"); +if ($col) { + echo "Column bot_enabled already exists\n"; + exit(0); +} +try { + $db->query("ALTER TABLE users ADD COLUMN bot_enabled TINYINT(1) NULL DEFAULT 1 AFTER bot_paused_until"); + echo "Added column bot_enabled\n"; +} catch (Exception $e) { + echo "Failed to add bot_enabled: " . $e->getMessage() . "\n"; + exit(1); +} diff --git a/scripts/describe_message_templates.php b/scripts/describe_message_templates.php new file mode 100644 index 0000000..3d2bf65 --- /dev/null +++ b/scripts/describe_message_templates.php @@ -0,0 +1,9 @@ +fetchAll('DESCRIBE message_templates'); + foreach ($cols as $c) echo $c['Field'] . ' => ' . $c['Type'] . PHP_EOL; +} catch (Exception $e) { + echo 'Error: ' . $e->getMessage() . PHP_EOL; +} diff --git a/scripts/test_bot_enabled.php b/scripts/test_bot_enabled.php new file mode 100644 index 0000000..8901839 --- /dev/null +++ b/scripts/test_bot_enabled.php @@ -0,0 +1,31 @@ +execute('DELETE FROM users WHERE phone_number = :p', ['p' => $phone]); +$userId = $db->insert('users', ['phone_number' => $phone, 'status' => 'active', 'bot_enabled' => 0, 'welcome_sent_at' => date('Y-m-d H:i:s'), 'created_at' => date('Y-m-d H:i:s')]); +$user = $db->fetch('SELECT * FROM users WHERE id = :id', ['id' => $userId]); + +// Clear conversations +$db->execute('DELETE FROM conversations WHERE user_id = :uid', ['uid' => $userId]); + +// Send message while bot disabled +$bot->processMessage($user, 'hola', 'text'); +$outs = $db->fetchAll("SELECT * FROM conversations WHERE user_id = :uid AND direction = 'outgoing'", ['uid' => $userId]); +echo "Outgoing after disabled: " . count($outs) . "\n"; + +// Enable bot +$db->update('users', ['bot_enabled' => 1], 'id = :id', ['id' => $userId]); +$user2 = $db->fetch('SELECT * FROM users WHERE id = :id', ['id' => $userId]); +$bot->processMessage($user2, 'hola', 'text'); +$outs2 = $db->fetchAll("SELECT * FROM conversations WHERE user_id = :uid AND direction = 'outgoing'", ['uid' => $userId]); +echo "Outgoing after enabled: " . count($outs2) . "\n"; + +// Cleanup +$db->execute('DELETE FROM conversations WHERE user_id = :uid', ['uid' => $userId]); +$db->execute('DELETE FROM users WHERE id = :id', ['id' => $userId]); + +echo "Done\n"; \ No newline at end of file diff --git a/scripts/test_get_templates.php b/scripts/test_get_templates.php new file mode 100644 index 0000000..d051b33 --- /dev/null +++ b/scripts/test_get_templates.php @@ -0,0 +1,13 @@ +getMessage() . "\n"; + echo $t->getTraceAsString() . "\n"; +} +$out = ob_get_clean(); +echo $out; diff --git a/services/BotService.php b/services/BotService.php index 45aedda..dccc271 100644 --- a/services/BotService.php +++ b/services/BotService.php @@ -51,6 +51,11 @@ class BotService { return; } + // Si el usuario ha desactivado el bot manualmente (toggle), no responder + if (isset($user['bot_enabled']) && !$user['bot_enabled']) { + return; + } + // Si el asesor ya respondió después del último mensaje del usuario, frenar al bot $lastIncoming = $this->db->fetch("SELECT created_at FROM conversations WHERE user_id = :uid AND direction = 'incoming' ORDER BY created_at DESC LIMIT 1", ['uid' => $user['id']]); $lastOutgoing = $this->db->fetch("SELECT created_at FROM conversations WHERE user_id = :uid AND direction = 'outgoing' ORDER BY created_at DESC LIMIT 1", ['uid' => $user['id']]);