'Método no permitido. Use GET.']); exit; } try { $db = Database::getInstance(); $limit = max(1, min(200, intval($_GET['limit'] ?? 50))); $page = max(1, intval($_GET['page'] ?? 1)); $offset = ($page - 1) * $limit; $sinceId = isset($_GET['since_id']) ? intval($_GET['since_id']) : null; $search = trim($_GET['search'] ?? ''); $filter = trim($_GET['filter'] ?? ''); // e.g., HAS_conversations $where = []; $params = []; if ($sinceId) { $where[] = 'id > ?'; $params[] = $sinceId; } if ($search !== '') { $where[] = '(request_body LIKE ?)'; $params[] = "%{$search}%"; } if ($filter === 'HAS_conversations') { $where[] = 'request_body LIKE ?'; $params[] = '%"conversations"%'; } $whereClause = empty($where) ? '' : 'WHERE ' . implode(' AND ', $where); if ($sinceId) { // Return newer logs only in ascending order for incremental updates $rows = $db->fetchAll( "SELECT id, SUBSTRING(request_body, 1, 1000) as snippet, status_code, ip_address, created_at FROM webhook_logs {$whereClause} ORDER BY id ASC LIMIT ?", array_merge($params, [$limit]) ); echo json_encode(['success' => true, 'data' => $rows]); exit; } $rows = $db->fetchAll( "SELECT id, SUBSTRING(request_body, 1, 500) as snippet, status_code, ip_address, created_at FROM webhook_logs {$whereClause} ORDER BY created_at DESC LIMIT ? OFFSET ?", array_merge($params, [$limit, $offset]) ); $total = $db->fetch( "SELECT COUNT(*) as cnt FROM webhook_logs {$whereClause}", $params ); $totalCount = intval($total['cnt'] ?? 0); echo json_encode([ 'success' => true, 'data' => $rows, 'pagination' => [ 'page' => $page, 'limit' => $limit, 'total' => $totalCount, 'pages' => $totalCount > 0 ? ceil($totalCount / $limit) : 0 ] ]); } catch (Exception $e) { error_log("Error in get_webhook_logs.php: " . $e->getMessage()); http_response_code(500); echo json_encode(['error' => 'Error interno del servidor']); }