up
This commit is contained in:
@@ -30,7 +30,7 @@ try {
|
||||
|
||||
// Obtener información del usuario
|
||||
$user = $db->fetch(
|
||||
"SELECT id, phone_number, name FROM users WHERE id = ?",
|
||||
"SELECT id, phone_number, name, in_service, in_service_by, in_service_at FROM users WHERE id = ?",
|
||||
[$user_id]
|
||||
);
|
||||
|
||||
@@ -39,6 +39,15 @@ try {
|
||||
echo json_encode(['error' => 'Usuario no encontrado']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Si la conversación está siendo atendida, resolver el nombre del operador
|
||||
$inServiceByName = null;
|
||||
if (!empty($user['in_service_by'])) {
|
||||
$admin = $db->fetch("SELECT id, full_name, username FROM admin_users WHERE id = ?", [$user['in_service_by']]);
|
||||
if ($admin) {
|
||||
$inServiceByName = $admin['full_name'] ?: $admin['username'];
|
||||
}
|
||||
}
|
||||
|
||||
// Obtener todos los mensajes de la conversación
|
||||
$conversations = $db->fetchAll(
|
||||
@@ -122,7 +131,11 @@ try {
|
||||
'user' => [
|
||||
'id' => intval($user['id']),
|
||||
'phone_number' => $user['phone_number'],
|
||||
'name' => $user['name'] ?? $user['phone_number']
|
||||
'name' => $user['name'] ?? $user['phone_number'],
|
||||
'in_service' => !empty($user['in_service']) ? true : false,
|
||||
'in_service_by' => isset($user['in_service_by']) ? intval($user['in_service_by']) : null,
|
||||
'in_service_at' => $user['in_service_at'] ?? null,
|
||||
'in_service_by_name' => $inServiceByName
|
||||
],
|
||||
'conversations' => $conversations,
|
||||
'total_conversations' => count($conversations)
|
||||
|
||||
@@ -44,3 +44,21 @@
|
||||
[2026-01-21 14:40:09] Request: GET /api/version/media-url.php?id=3932473397057815 GET:{"id":"3932473397057815"} POST:[]
|
||||
[2026-01-21 14:40:09] Graph API request to https://graph.facebook.com/v22.0/3932473397057815
|
||||
[2026-01-21 14:40:10] Proxying Facebook media URL with Authorization to https://lookaside.fbsbx.com/whatsapp_business/attachments/?mid=3932473397057815&source=getMedia&ext=1769024699&hash=ARlXiE4qXDbAzqzvCutrIryD_tdYaN1gjuIZWoBHDbilqQ
|
||||
[2026-01-21 21:35:15] Request: GET /api/version/media-url.php?id=3932473397057815 GET:{"id":"3932473397057815"} POST:[]
|
||||
[2026-01-21 21:35:15] Graph API request to https://graph.facebook.com/v22.0/3932473397057815
|
||||
[2026-01-21 21:35:16] Proxying Facebook media URL with Authorization to https://lookaside.fbsbx.com/whatsapp_business/attachments/?mid=3932473397057815&source=getMedia&ext=1769049615&hash=ARl0ssx82h2xALShS68EX09cnPLDRp3xDrMkXLHxNpYdmQ
|
||||
[2026-01-21 21:39:36] Request: GET /api/version/media-url.php?id=3932473397057815 GET:{"id":"3932473397057815"} POST:[]
|
||||
[2026-01-21 21:39:36] Graph API request to https://graph.facebook.com/v22.0/3932473397057815
|
||||
[2026-01-21 21:39:37] Proxying Facebook media URL with Authorization to https://lookaside.fbsbx.com/whatsapp_business/attachments/?mid=3932473397057815&source=getMedia&ext=1769049877&hash=ARkt4u_w991l5uoAEPQPa_zaMV4_P5fD4HAa6ClILfS5ZA
|
||||
[2026-01-21 21:55:37] Request: GET /api/version/media-url.php?id=3932473397057815 GET:{"id":"3932473397057815"} POST:[]
|
||||
[2026-01-21 21:55:37] Graph API request to https://graph.facebook.com/v22.0/3932473397057815
|
||||
[2026-01-21 21:55:37] Proxying Facebook media URL with Authorization to https://lookaside.fbsbx.com/whatsapp_business/attachments/?mid=3932473397057815&source=getMedia&ext=1769050837&hash=ARn_VZzaTBKkCf7WJMaJHiVu3cYe_pxGrq1Ix9YvppbNBA
|
||||
[2026-01-21 21:59:29] Request: GET /api/version/media-url.php?id=3932473397057815 GET:{"id":"3932473397057815"} POST:[]
|
||||
[2026-01-21 21:59:29] Graph API request to https://graph.facebook.com/v22.0/3932473397057815
|
||||
[2026-01-21 21:59:30] Proxying Facebook media URL with Authorization to https://lookaside.fbsbx.com/whatsapp_business/attachments/?mid=3932473397057815&source=getMedia&ext=1769051070&hash=ARn9gwkRZ-Tfpv4cSUtMh9pebsJNis-s5tEQeIhxh7iPAA
|
||||
[2026-01-21 22:00:11] Request: GET /api/version/media-url.php?id=3932473397057815 GET:{"id":"3932473397057815"} POST:[]
|
||||
[2026-01-21 22:00:11] Graph API request to https://graph.facebook.com/v22.0/3932473397057815
|
||||
[2026-01-21 22:00:11] Proxying Facebook media URL with Authorization to https://lookaside.fbsbx.com/whatsapp_business/attachments/?mid=3932473397057815&source=getMedia&ext=1769051111&hash=ARnFCx7vV54UV2Z2LJnp3JMsxseZMInCxX8bM-xz0mM5AA
|
||||
[2026-01-21 22:05:03] Request: GET /api/version/media-url.php?id=3932473397057815 GET:{"id":"3932473397057815"} POST:[]
|
||||
[2026-01-21 22:05:03] Graph API request to https://graph.facebook.com/v22.0/3932473397057815
|
||||
[2026-01-21 22:05:03] Proxying Facebook media URL with Authorization to https://lookaside.fbsbx.com/whatsapp_business/attachments/?mid=3932473397057815&source=getMedia&ext=1769051403&hash=ARm7CptuN3CH6WN5V1RmuW6rK9iIipE_KE1-FLbj3RQuHQ
|
||||
|
||||
@@ -2,3 +2,11 @@
|
||||
[21-Jan-2026 14:31:30 America/Bogota] PHP Warning: preg_match(): Unknown modifier '&' in C:\laragon\www\whatsapp\api\version\media-url.php on line 131
|
||||
[21-Jan-2026 14:33:32 America/Bogota] PHP Warning: preg_match(): Unknown modifier '&' in C:\laragon\www\whatsapp\api\version\media-url.php on line 131
|
||||
[21-Jan-2026 14:35:45 America/Bogota] PHP Warning: preg_match(): Unknown modifier '&' in C:\laragon\www\whatsapp\api\version\media-url.php on line 131
|
||||
[21-Jan-2026 21:35:16 America/Bogota] PHP Deprecated: Function curl_close() is deprecated since 8.5, as it has no effect since PHP 8.0 in /Users/lizandro/Documents/GitHub/whatsapp/api/version/media-url.php on line 203
|
||||
[21-Jan-2026 21:35:17 America/Bogota] PHP Deprecated: Function curl_close() is deprecated since 8.5, as it has no effect since PHP 8.0 in /Users/lizandro/Documents/GitHub/whatsapp/api/version/media-url.php on line 522
|
||||
[21-Jan-2026 21:39:37 America/Bogota] PHP Deprecated: Function curl_close() is deprecated since 8.5, as it has no effect since PHP 8.0 in /Users/lizandro/Documents/GitHub/whatsapp/api/version/media-url.php on line 203
|
||||
[21-Jan-2026 21:39:37 America/Bogota] PHP Deprecated: Function curl_close() is deprecated since 8.5, as it has no effect since PHP 8.0 in /Users/lizandro/Documents/GitHub/whatsapp/api/version/media-url.php on line 522
|
||||
[21-Jan-2026 21:55:37 America/Bogota] PHP Deprecated: Function curl_close() is deprecated since 8.5, as it has no effect since PHP 8.0 in /Users/lizandro/Documents/GitHub/whatsapp/api/version/media-url.php on line 203
|
||||
[21-Jan-2026 21:55:38 America/Bogota] PHP Deprecated: Function curl_close() is deprecated since 8.5, as it has no effect since PHP 8.0 in /Users/lizandro/Documents/GitHub/whatsapp/api/version/media-url.php on line 522
|
||||
[21-Jan-2026 21:59:30 America/Bogota] PHP Deprecated: Function curl_close() is deprecated since 8.5, as it has no effect since PHP 8.0 in /Users/lizandro/Documents/GitHub/whatsapp/api/version/media-url.php on line 203
|
||||
[21-Jan-2026 21:59:30 America/Bogota] PHP Deprecated: Function curl_close() is deprecated since 8.5, as it has no effect since PHP 8.0 in /Users/lizandro/Documents/GitHub/whatsapp/api/version/media-url.php on line 522
|
||||
|
||||
@@ -357,6 +357,10 @@ if (empty($user_id)) {
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center">
|
||||
<button id="attendBtn" class="btn btn-outline-light btn-sm me-2" onclick="toggleAttend()" title="Atender/Finalizar">
|
||||
<i class="fas fa-user-check"></i> Atender
|
||||
</button>
|
||||
<small id="attendStatus" class="text-white me-3" style="font-size:0.9rem;"></small>
|
||||
<button class="btn btn-outline-light btn-sm me-2" onclick="refreshChat()">
|
||||
<i class="fas fa-sync-alt"></i>
|
||||
</button>
|
||||
@@ -563,6 +567,9 @@ if (empty($user_id)) {
|
||||
document.getElementById('userAvatar').innerHTML =
|
||||
`<span>${(currentUser.name || 'U').charAt(0).toUpperCase()}</span>`;
|
||||
|
||||
// Estado de atención
|
||||
renderAttendControls();
|
||||
|
||||
// Cargar mensajes
|
||||
displayconversations(response.conversations);
|
||||
|
||||
@@ -1060,6 +1067,51 @@ if (empty($user_id)) {
|
||||
wrapper.style.display = (wrapper.style.display === 'block') ? 'none' : 'block';
|
||||
}
|
||||
}
|
||||
|
||||
// ===== Controles de atención (Atender / Finalizar) =====
|
||||
function renderAttendControls() {
|
||||
const btn = document.getElementById('attendBtn');
|
||||
const status = document.getElementById('attendStatus');
|
||||
if (!btn || !status || !currentUser) return;
|
||||
|
||||
if (currentUser.in_service) {
|
||||
btn.innerHTML = '<i class="fas fa-user-times"></i> Finalizar';
|
||||
btn.classList.remove('btn-outline-light');
|
||||
btn.classList.add('btn-light','text-dark');
|
||||
status.innerHTML = `Atendido por ${currentUser.in_service_by_name || 'un asesor'}`;
|
||||
} else {
|
||||
btn.innerHTML = '<i class="fas fa-user-check"></i> Atender';
|
||||
btn.classList.remove('btn-light','text-dark');
|
||||
btn.classList.add('btn-outline-light');
|
||||
status.innerHTML = '';
|
||||
}
|
||||
}
|
||||
|
||||
async function toggleAttend() {
|
||||
if (!currentUser) return;
|
||||
try {
|
||||
if (currentUser.in_service) {
|
||||
const resp = await whatsappManager.apiCall('finish_attend.php', { body: { user_id: userId } });
|
||||
if (resp && resp.success) {
|
||||
showAlert('Finalizada la atención', 'success');
|
||||
await loadUserData();
|
||||
} else {
|
||||
throw new Error(resp.error || 'Error finalizando');
|
||||
}
|
||||
} else {
|
||||
const resp = await whatsappManager.apiCall('attend.php', { body: { user_id: userId } });
|
||||
if (resp && resp.success) {
|
||||
showAlert('Atención iniciada', 'success');
|
||||
await loadUserData();
|
||||
} else {
|
||||
throw new Error(resp.error || 'Error iniciando atención');
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error toggling attend:', err);
|
||||
showAlert('Error al cambiar estado de atención: ' + err.message, 'danger');
|
||||
}
|
||||
}
|
||||
|
||||
function showError(message) {
|
||||
showAlert(message, 'danger');
|
||||
|
||||
@@ -16,7 +16,7 @@ class Database {
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
PDO::ATTR_PERSISTENT => true,
|
||||
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES " . DB_CHARSET . " COLLATE utf8mb4_unicode_ci"
|
||||
(class_exists('Pdo\Mysql') ? \Pdo\Mysql::ATTR_INIT_COMMAND : PDO::MYSQL_ATTR_INIT_COMMAND) => "SET NAMES " . DB_CHARSET . " COLLATE utf8mb4_unicode_ci"
|
||||
];
|
||||
|
||||
$this->pdo = new PDO($dsn, DB_USER, DB_PASS, $options);
|
||||
|
||||
@@ -32,3 +32,22 @@ Stack trace:
|
||||
[2026-01-21 15:16:53] [INFO] Cleared advisor_requested for user 142 after outgoing message
|
||||
[2026-01-21 15:16:56] [INFO] Cleared advisor_requested for user 142 after outgoing message
|
||||
[2026-01-21 15:16:57] [INFO] Bot paused for 5 minutes for 573010000003
|
||||
[2026-01-21 21:55:46] [INFO] Cleared advisor_requested for user 135 after outgoing message
|
||||
[2026-01-21 21:55:46] [INFO] Operator 2 attending conversation for 573168950803
|
||||
[2026-01-21 21:56:00] [INFO] Cleared advisor_requested for user 135 after outgoing message
|
||||
[2026-01-21 21:56:00] [INFO] Operator 2 attending conversation for 573168950803
|
||||
[2026-01-21 21:59:34] [WARN] Failed to send survey template: Error de WhatsApp API: (#131009) Parameter value is not valid
|
||||
[2026-01-21 21:59:34] [INFO] Operator 2 finished attending for 573168950803, survey=encuesta_satisfaccin
|
||||
[2026-01-21 21:59:38] [WARN] Failed to send survey template: Error de WhatsApp API: (#131009) Parameter value is not valid
|
||||
[2026-01-21 21:59:39] [INFO] Operator 2 finished attending for 573168950803, survey=encuesta_satisfaccin
|
||||
[2026-01-21 22:00:23] [INFO] Cleared advisor_requested for user 135 after outgoing message
|
||||
[2026-01-21 22:00:23] [INFO] Operator 2 attending conversation for 573168950803
|
||||
[2026-01-21 22:03:38] [INFO] Cleared advisor_requested for user 163 after outgoing message
|
||||
[2026-01-21 22:03:38] [INFO] Operator 1 attending conversation for 573000000999
|
||||
[2026-01-21 22:04:01] [INFO] Cleared advisor_requested for user 164 after outgoing message
|
||||
[2026-01-21 22:04:02] [INFO] Operator 1 attending conversation for 573000000999
|
||||
[2026-01-21 22:05:30] [WARN] Failed to send survey template: Error de WhatsApp API: (#131009) Parameter value is not valid
|
||||
[2026-01-21 22:05:31] [INFO] Operator 2 finished attending for 573168950803, survey=encuesta_satisfaccin
|
||||
[2026-01-21 22:06:42] [INFO] Cleared advisor_requested for user 135 after outgoing message
|
||||
[2026-01-21 22:06:43] [INFO] Operator 2 attending conversation for 573168950803
|
||||
[2026-01-21 22:07:15] [INFO] Cleared advisor_requested for user 135 after outgoing message
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../config/config.php';
|
||||
require_once __DIR__ . '/../services/BotService.php';
|
||||
|
||||
$db = Database::getInstance();
|
||||
$user = $db->fetch('SELECT id, phone_number FROM users LIMIT 1');
|
||||
if (!$user) {
|
||||
echo "No users found\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Mark user as in_service
|
||||
$db->update('users', ['in_service' => 1, 'in_service_by' => 1, 'in_service_at' => date('Y-m-d H:i:s')], 'id = :id', ['id' => $user['id']]);
|
||||
|
||||
// Fetch stale user array (simulate that caller has an old copy without in_service)
|
||||
$staleUser = ['id' => $user['id'], 'phone_number' => $user['phone_number']];
|
||||
|
||||
$bot = new BotService();
|
||||
$bot->processMessage($staleUser, 'hola', 'text');
|
||||
|
||||
echo "processMessage invoked (should have skipped bot processing if in_service)\n";
|
||||
@@ -25,6 +25,26 @@ class BotService {
|
||||
$messageText = trim($messageText);
|
||||
$phoneNumber = $user['phone_number'];
|
||||
|
||||
// Comprobar en la base de datos el estado más reciente de 'in_service' para evitar condiciones de carrera
|
||||
try {
|
||||
$fresh = $this->db->fetch("SELECT in_service, in_service_by FROM users WHERE phone_number = :phone", ['phone' => $phoneNumber]);
|
||||
if (!empty($fresh['in_service'])) {
|
||||
try {
|
||||
$userId = $user['id'] ?? 'unknown';
|
||||
error_log("[BotService] processMessage - user_id={$userId} is currently in_service (DB), skipping bot processing");
|
||||
} catch (Throwable $t) {
|
||||
// ignore logging errors
|
||||
}
|
||||
return;
|
||||
}
|
||||
// actualizar el array $user con valores frescos por si se usan más adelante
|
||||
$user['in_service'] = !empty($fresh['in_service']);
|
||||
$user['in_service_by'] = $fresh['in_service_by'] ?? null;
|
||||
} catch (Exception $e) {
|
||||
error_log('[BotService] processMessage - failed to refresh in_service: ' . $e->getMessage());
|
||||
// En caso de fallo al consultar, continuar con lógica previa (no bloquear)
|
||||
}
|
||||
|
||||
// DEBUG: log basic context
|
||||
try {
|
||||
$userId = $user['id'] ?? 'unknown';
|
||||
|
||||
@@ -465,7 +465,10 @@ class WhatsAppService
|
||||
$response = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
// curl_close is deprecated in PHP 8.5+ (has no effect). Avoid calling it on newer versions.
|
||||
if (version_compare(PHP_VERSION, '8.5.0', '<')) {
|
||||
curl_close($ch);
|
||||
}
|
||||
|
||||
if ($error) {
|
||||
error_log("cURL Error: " . $error);
|
||||
|
||||
Reference in New Issue
Block a user