This commit is contained in:
lizandrogd
2026-01-21 12:05:48 -05:00
parent c7d0b8b70c
commit 6cec747ae3
2 changed files with 155 additions and 0 deletions
+114
View File
@@ -0,0 +1,114 @@
<?php
/**
* Endpoint: /api/version/media-url.php
* Parámetros: id (media id) o url (direct url), opcional download=1 para proxy y forzar descarga
* - Si se solicita JSON (Accept: application/json) la endpoint requiere autenticación y devuelve {success:true,url:...}
* - Si se accede mediante GET desde navegador, redirige (302) al URL del media (no requiere sesión)
*/
require_once __DIR__ . '/../../config/config.php';
$isGet = $_SERVER['REQUEST_METHOD'] === 'GET';
$accept = $_SERVER['HTTP_ACCEPT'] ?? '';
$wantsJson = strpos($accept, 'application/json') !== false;
// Requerir autenticación sólo para peticiones no-GET o cuando se solicita JSON (API/AJAX)
if (!$isGet || $wantsJson) {
requireAuthentication();
}
header('Content-Type: application/json; charset=utf-8');
$mediaId = $_GET['id'] ?? $_POST['id'] ?? null;
$providedUrl = $_GET['url'] ?? $_POST['url'] ?? null;
$download = isset($_GET['download']) && $_GET['download'] === '1';
if (!$mediaId && !$providedUrl) {
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Se requiere id o url']);
exit;
}
$mediaUrl = null;
if ($providedUrl) {
$mediaUrl = $providedUrl;
} else {
$token = getConfigFromDB('whatsapp_token', '');
$apiUrl = rtrim(getConfigFromDB('whatsapp_api_url', 'https://graph.facebook.com/v22.0/'), '/');
$endpoint = "{$apiUrl}/{$mediaId}";
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $endpoint,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . $token ],
CURLOPT_TIMEOUT => 15,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$err = curl_error($ch);
curl_close($ch);
if ($err) {
http_response_code(502);
echo json_encode(['success' => false, 'error' => 'Error comunicando con Graph API', 'detail' => $err]);
exit;
}
$decoded = json_decode($response, true);
if ($httpCode >= 400 || !$decoded) {
http_response_code($httpCode ?: 500);
echo json_encode(['success' => false, 'error' => 'Graph API error', 'response' => $decoded]);
exit;
}
$mediaUrl = $decoded['url'] ?? ($decoded['data'][0]['url'] ?? null);
if (!$mediaUrl) {
http_response_code(404);
echo json_encode(['success' => false, 'error' => 'No se recibió URL del media', 'raw' => $decoded]);
exit;
}
}
// Si se solicitó JSON, devolver la URL
if ($wantsJson) {
echo json_encode(['success' => true, 'url' => $mediaUrl]);
exit;
}
// Si se pidió proxy (download=1), traer el contenido y retornarlo como descarga
if ($download) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $mediaUrl,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => 60,
]);
$content = curl_exec($ch);
$info = curl_getinfo($ch);
$err = curl_error($ch);
curl_close($ch);
if ($err) {
http_response_code(502);
header('Content-Type: application/json; charset=utf-8');
echo json_encode(['success' => false, 'error' => 'Error al descargar el archivo', 'detail' => $err]);
exit;
}
// Cabeceras para descarga
header_remove('Content-Type');
header('Cache-Control: public, max-age=3600');
if (!empty($info['content_type'])) header('Content-Type: ' . $info['content_type']);
if (!empty($info['size_download'])) header('Content-Length: ' . $info['size_download']);
$filename = basename(parse_url($mediaUrl, PHP_URL_PATH) ?: 'file');
header('Content-Disposition: attachment; filename="' . $filename . '"');
echo $content;
exit;
}
// Por defecto redirigir al URL (navegador hará la descarga o mostrará la imagen)
header('Cache-Control: public, max-age=3600');
header('Location: ' . $mediaUrl, true, 302);
exit;
+41
View File
@@ -0,0 +1,41 @@
<?php
// Usage: php scripts/test_media_url.php <mediaId>
$mediaId = $argv[1] ?? '1379066300634610';
// 1) JSON request (requires auth) - use local cookie session if possible
$opts = ['http' => ['method' => 'GET', 'header' => "Accept: application/json\r\n"]];
$ctx = stream_context_create($opts);
$url = "http://localhost/whatsapp/api/version/media-url.php?id=" . urlencode($mediaId);
echo "Requesting JSON -> $url\n";
$s = @file_get_contents($url, false, $ctx);
if ($s === false) {
echo "JSON request failed (probably 401 if not authenticated)\n";
} else {
echo $s . "\n";
}
// 2) Direct GET (simulate browser) should receive a Location header (we can't follow in this simple test)
$headers = get_headers($url, 1);
if ($headers) {
echo "\nResponse headers:\n";
print_r($headers);
} else {
echo "No headers received (server unreachable)\n";
}
// 3) Proxy download test
$downloadUrl = $url . '&download=1';
echo "\nDownload test -> $downloadUrl\n";
$opts2 = ['http' => ['method' => 'GET']];
$ctx2 = stream_context_create($opts2);
$stream = @fopen($downloadUrl, 'r', false, $ctx2);
if (!$stream) {
echo "Download request failed (check server or token)\n";
} else {
$meta = stream_get_meta_data($stream);
echo "Opened stream, meta keys: " . implode(',', array_keys($meta)) . "\n";
// Read a small part
$part = fread($stream, 200);
echo "First bytes:\n" . substr($part,0,200) . "\n";
fclose($stream);
}