This commit is contained in:
lizandrogd
2026-01-21 11:58:17 -05:00
parent 932820d02d
commit c7d0b8b70c
11 changed files with 250 additions and 3 deletions
+11 -1
View File
@@ -4,7 +4,17 @@
* Parámetros: id (media id)
*/
require_once '../config/config.php';
requireAuthentication();
// Permitir que accesos directos desde navegador (GET sin Accept:application/json) redirijan al media sin requerir sesión.
$isGet = $_SERVER['REQUEST_METHOD'] === 'GET';
$accept = $_SERVER['HTTP_ACCEPT'] ?? '';
$wantsJson = strpos($accept, 'application/json') !== false;
// Requerir autenticación sólo para peticiones que no sean GET puro o cuando se solicite JSON (AJAX/API)
if (!$isGet || $wantsJson) {
requireAuthentication();
}
header('Content-Type: application/json; charset=utf-8');
$mediaId = $_GET['id'] ?? ($_POST['id'] ?? null);
+26 -2
View File
@@ -194,12 +194,18 @@ class WhatsAppWebhook {
'message_type' => $messageType,
'content' => $messageText,
'media_url' => $mediaUrl,
'filename' => isset($filename) ? $filename : null,
'mime_type' => isset($mimeType) ? $mimeType : null,
'status' => 'received',
'is_read' => 0
];
// Añadir campos opcionales solo si existen para evitar errores en esquemas antiguos
if (isset($filename) && $filename !== null) {
$saveData['filename'] = $filename;
}
if (isset($mimeType) && $mimeType !== null) {
$saveData['mime_type'] = $mimeType;
}
// Si el mensaje incluye contexto (es respuesta a otro mensaje)
if (isset($message['context']) && isset($message['context']['id'])) {
$saveData['reply_to_message_id'] = $message['context']['id'];
@@ -210,6 +216,8 @@ class WhatsAppWebhook {
$saveData = array_merge($saveData, $extraFields);
}
// Filtrar campos según columnas existentes para evitar errores en esquemas antiguos
$saveData = $this->filterColumns('conversations', $saveData);
$this->saveMessage($saveData);
// Crear notificación para UI (nuevo mensaje entrante)
@@ -290,6 +298,22 @@ class WhatsAppWebhook {
private function saveMessage($messageData) {
return $this->db->insert('conversations', $messageData);
}
/**
* Filtrar los datos para dejar solo las columnas que existen en la tabla
* Evita errores cuando la BD está en un esquema más antiguo
*/
private function filterColumns($table, array $data) {
static $columnsCache = [];
if (!isset($columnsCache[$table])) {
$cols = $this->db->fetchAll("SHOW COLUMNS FROM {$table}");
$columnsCache[$table] = array_map(function($c){ return $c['Field']; }, $cols);
}
$allowed = $columnsCache[$table];
return array_filter($data, function($v, $k) use ($allowed) {
return in_array($k, $allowed, true);
}, ARRAY_FILTER_USE_BOTH);
}
private function logWebhook($requestBody, $responseBody, $statusCode) {
if (ENABLE_LOGGING) {
+11
View File
@@ -0,0 +1,11 @@
<?php
$mediaId = $argv[1] ?? '1379066300634610';
$opts = ['http' => ['method' => 'GET', 'header' => "Accept: application/json\r\n"]];
$ctx = stream_context_create($opts);
$url = "http://localhost/whatsapp/api/get_media.php?id=" . urlencode($mediaId);
$s = @file_get_contents($url, false, $ctx);
if ($s === false) {
echo "Request failed\n";
exit(1);
}
echo $s . "\n";
+9
View File
@@ -0,0 +1,9 @@
<?php
require_once __DIR__ . '/../config/config.php';
$phone = $argv[1] ?? '573168950803';
$db = Database::getInstance();
$user = $db->fetch('SELECT * FROM users WHERE phone_number = ?', [$phone]);
if (!$user) { echo "User not found for phone $phone\n"; exit; }
$rows = $db->fetchAll('SELECT * FROM conversations WHERE user_id = ? ORDER BY created_at DESC LIMIT 10', [$user['id']]);
echo "User id: " . $user['id'] . "\n";
echo json_encode($rows, JSON_PRETTY_PRINT) . "\n";
+64
View File
@@ -0,0 +1,64 @@
<?php
require_once __DIR__ . '/../config/config.php';
$id = $argv[1] ?? null;
if (!$id) { echo "Usage: php debug_process_message.php <webhook_log_id>\n"; exit; }
$db = Database::getInstance();
$row = $db->fetch('SELECT request_body FROM webhook_logs WHERE id = ?', [$id]);
if (!$row) { echo "Log not found\n"; exit; }
$data = json_decode($row['request_body'], true);
$messages = $data['entry'][0]['changes'][0]['value']['messages'] ?? null;
if (!$messages) { echo "No messages in log\n"; exit; }
foreach ($messages as $message) {
echo "--- Message ---\n";
print_r($message);
$phoneNumber = $message['from'] ?? ($message['wa_id'] ?? null);
$messageId = $message['id'] ?? ($message['message_id'] ?? null);
$timestamp = $message['timestamp'] ?? null;
echo "phone=$phoneNumber messageId=$messageId ts=$timestamp\n";
if (empty($phoneNumber) || empty($messageId)) { echo "Missing phone or msg id\n"; continue; }
$existing = $db->fetch('SELECT id FROM conversations WHERE message_id = ?', [$messageId]);
echo "existing: "; var_export((bool)$existing); echo "\n";
$user = $db->fetch('SELECT * FROM users WHERE phone_number = ?', [$phoneNumber]);
if (!$user) { echo "User not found, creating...\n"; $id = $db->insert('users', ['phone_number' => $phoneNumber, 'status' => 'active', 'created_at' => date('Y-m-d H:i:s')]); $user = $db->fetch('SELECT * FROM users WHERE id = ?', [$id]); }
echo "user id: " . $user['id'] . "\n";
$messageText = '';
$messageType = 'text';
$mediaUrl = null; $mimeType = null; $filename = null;
if (isset($message['text']) || (($message['type'] ?? '') === 'text')) {
$messageText = isset($message['text']['body']) ? $message['text']['body'] : ($message['body'] ?? '');
$messageType = 'text';
} elseif (isset($message['image'])) {
$messageText = $message['image']['caption'] ?? '';
$messageType = 'image';
$mediaUrl = $message['image']['url'] ?? ($message['image']['id'] ?? null);
$mimeType = $message['image']['mime_type'] ?? null;
$filename = $message['image']['filename'] ?? null;
}
echo "type=$messageType text=" . substr($messageText,0,100) . " mediaUrl=" . ($mediaUrl ?? 'NULL') . "\n";
$saveData = [
'user_id' => $user['id'],
'message_id' => $messageId,
'direction' => 'incoming',
'message_type' => $messageType,
'content' => $messageText,
'media_url' => $mediaUrl,
'filename' => $filename,
'mime_type' => $mimeType,
'status' => 'received',
'is_read' => 0,
'created_at' => date('Y-m-d H:i:s')
];
try {
$res = $db->insert('conversations', $saveData);
echo "Insert returned: "; var_export($res); echo "\n";
} catch (Exception $e) {
echo "Insert failed: " . $e->getMessage() . "\n";
}
}
+7
View File
@@ -0,0 +1,7 @@
<?php
require_once __DIR__ . '/../config/config.php';
$message_id = $argv[1] ?? null;
if (!$message_id) { echo "Usage: php find_message_by_id.php <message_id>\n"; exit; }
$db = Database::getInstance();
$res = $db->fetch('SELECT * FROM conversations WHERE message_id = ?', [$message_id]);
if ($res) echo json_encode($res, JSON_PRETTY_PRINT) . "\n"; else echo "Not found\n";
+24
View File
@@ -0,0 +1,24 @@
<?php
require_once __DIR__ . '/../config/config.php';
$mediaId = $argv[1] ?? null;
if (!$mediaId) { echo "Usage: php get_media_direct.php <mediaId>\n"; exit(1); }
$token = getConfigFromDB('whatsapp_token', '');
$apiUrl = rtrim(getConfigFromDB('whatsapp_api_url', 'https://graph.facebook.com/v22.0/'), '/');
$url = "{$apiUrl}/{$mediaId}";
echo "Calling: $url\n";
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . $token ],
CURLOPT_TIMEOUT => 10,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$err = curl_error($ch);
curl_close($ch);
if ($err) {
echo "CURL ERR: $err\n"; exit(1);
}
echo "HTTP Code: $httpCode\n";
echo "$response\n";
+9
View File
@@ -0,0 +1,9 @@
<?php
require_once __DIR__ . '/../config/config.php';
$id = $argv[1] ?? null;
if (!$id) { echo "Usage: php inspect_webhook.php <id>\n"; exit; }
$db = Database::getInstance();
$row = $db->fetch('SELECT request_body FROM webhook_logs WHERE id = ?', [$id]);
if (!$row) { echo "Log not found\n"; exit; }
$data = json_decode($row['request_body'], true);
print_r($data);
+35
View File
@@ -0,0 +1,35 @@
<?php
require_once __DIR__ . '/../config/config.php';
require_once __DIR__ . '/../api/webhook.php';
$since_hours = $argv[1] ?? 24; // look back window
$db = Database::getInstance();
$cutoff = date('Y-m-d H:i:s', strtotime("-{$since_hours} hours"));
$rows = $db->fetchAll('SELECT id, request_body FROM webhook_logs WHERE created_at >= ? ORDER BY id ASC', [$cutoff]);
$webhook = new WhatsAppWebhook();
$replayed = 0;
foreach ($rows as $row) {
$data = json_decode($row['request_body'], true);
if (empty($data) || !isset($data['entry'])) continue;
$needReplay = false;
foreach ($data['entry'] as $entry) {
foreach ($entry['changes'] as $change) {
$value = $change['value'] ?? [];
$messages = $value['messages'] ?? [];
foreach ($messages as $m) {
$mid = $m['id'] ?? null;
if ($mid && !$db->fetch('SELECT id FROM conversations WHERE message_id = ?', [$mid])) {
$needReplay = true; break 3;
}
}
}
}
if ($needReplay) {
echo "Replaying webhook_log id={$row['id']}\n";
$ok = $webhook->processPayload($data);
echo " -> processPayload returned: " . ($ok ? 'true' : 'false') . "\n";
$replayed++;
}
}
echo "Completed. Replayed $replayed logs.\n";
+41
View File
@@ -0,0 +1,41 @@
<?php
require_once __DIR__ . '/../config/config.php';
require_once __DIR__ . '/../api/webhook.php';
$id = $argv[1] ?? null;
if (!$id) {
echo "Usage: php replay_webhook_by_id.php <webhook_log_id>\n";
exit;
}
$db = Database::getInstance();
$row = $db->fetch('SELECT request_body FROM webhook_logs WHERE id = ?', [$id]);
if (!$row) { echo "Log id $id not found\n"; exit; }
$data = json_decode($row['request_body'], true);
if (!$data) { echo "Invalid JSON in log id $id\n"; exit; }
$webhook = new WhatsAppWebhook();
$ok = $webhook->processPayload($data);
echo "processPayload returned: " . ($ok ? 'true' : 'false') . "\n";
// Try to show messages for the involved phone numbers
$phones = [];
foreach ($data['entry'] as $entry) {
foreach ($entry['changes'] as $change) {
$val = $change['value'] ?? [];
if (isset($val['contacts'])) {
foreach ($val['contacts'] as $c) if (isset($c['wa_id'])) $phones[] = $c['wa_id'];
}
if (isset($val['messages'])) {
foreach ($val['messages'] as $m) if (isset($m['from'])) $phones[] = $m['from'];
}
}
}
$phones = array_unique($phones);
foreach ($phones as $p) {
$user = $db->fetch('SELECT * FROM users WHERE phone_number = ?', [$p]);
echo "Phone: $p\n";
if (!$user) { echo " No user found\n"; continue; }
$msgs = $db->fetchAll('SELECT id,message_id,message_type,content,media_url,created_at FROM conversations WHERE user_id = ? ORDER BY created_at DESC LIMIT 5', [$user['id']]);
echo json_encode($msgs, JSON_PRETTY_PRINT) . "\n";
}
+13
View File
@@ -0,0 +1,13 @@
<?php
// Test get_conversation_detail.php in debug mode
$_GET['debug'] = 'true';
$_GET['user_id'] = 2;
chdir(__DIR__ . '/../api');
ob_start();
try {
include 'get_conversation_detail.php';
} catch (Throwable $t) {
echo 'Error: ' . $t->getMessage();
}
$out = ob_get_clean();
echo $out;