up
This commit is contained in:
+11
-1
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
@@ -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);
|
||||
@@ -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";
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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;
|
||||
Reference in New Issue
Block a user