up
This commit is contained in:
@@ -421,6 +421,8 @@ class WhatsAppService
|
||||
|
||||
/**
|
||||
* Subir archivo multimedia a WhatsApp
|
||||
* Intenta primero con PHP curl. Si falla por SSL/conexión (errno 35, 56, 77),
|
||||
* reintenta usando el CLI curl vía exec (mismo workaround que para descargas).
|
||||
*/
|
||||
public function uploadMedia($filePath, $mimeType)
|
||||
{
|
||||
@@ -430,6 +432,7 @@ class WhatsAppService
|
||||
|
||||
$url = $this->apiUrl . $this->phoneNumberId . '/media';
|
||||
|
||||
// ── Intento 1: PHP curl con opciones SSL relajadas ──────────────────────
|
||||
$ch = curl_init();
|
||||
|
||||
$postFields = [
|
||||
@@ -439,43 +442,104 @@ class WhatsAppService
|
||||
];
|
||||
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => $postFields,
|
||||
CURLOPT_HTTPHEADER => [
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => $postFields,
|
||||
CURLOPT_HTTPHEADER => [
|
||||
'Authorization: Bearer ' . $this->token
|
||||
],
|
||||
CURLOPT_TIMEOUT => 300,
|
||||
CURLOPT_CONNECTTIMEOUT => 30,
|
||||
CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
|
||||
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
||||
CURLOPT_TIMEOUT => 300,
|
||||
CURLOPT_CONNECTTIMEOUT => 30,
|
||||
CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
|
||||
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
||||
// Forzar TLS 1.2 (evita problemas de negociación SSL en algunos VPS)
|
||||
CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2,
|
||||
]);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$response = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$curlError = curl_error($ch);
|
||||
$curlErrno = curl_errno($ch);
|
||||
curl_close($ch);
|
||||
|
||||
// Log detallado para diagnóstico
|
||||
error_log("WhatsAppService::uploadMedia - URL: {$url}, HTTP: {$httpCode}, curlErrno: {$curlErrno}, curlError: {$curlError}, tokenLen: " . strlen($this->token) . ", phoneId: {$this->phoneNumberId}");
|
||||
error_log("WhatsAppService::uploadMedia (php-curl) - URL: {$url}, HTTP: {$httpCode}, errno: {$curlErrno}, error: {$curlError}");
|
||||
|
||||
if ($curlErrno !== 0) {
|
||||
// Errores de capa SSL/red que se benefician del fallback CLI
|
||||
$sslErrors = [35, 56, 77, 58, 59, 60]; // CURLE_SSL_CONNECT_ERROR, CURLE_RECV_ERROR, etc.
|
||||
$needsFallback = ($curlErrno !== 0 && in_array($curlErrno, $sslErrors, true));
|
||||
|
||||
if (!$needsFallback && $curlErrno !== 0) {
|
||||
throw new Exception("Error de conexión subiendo archivo (curl #{$curlErrno}): {$curlError}");
|
||||
}
|
||||
|
||||
if ($httpCode !== 200 && $httpCode !== 201) {
|
||||
throw new Exception("Error subiendo archivo (HTTP {$httpCode}): " . $response);
|
||||
if (!$needsFallback) {
|
||||
if ($httpCode !== 200 && $httpCode !== 201) {
|
||||
throw new Exception("Error subiendo archivo (HTTP {$httpCode}): " . $response);
|
||||
}
|
||||
$result = json_decode($response, true);
|
||||
if (!isset($result['id'])) {
|
||||
throw new Exception("No se obtuvo ID del archivo subido: " . $response);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result = json_decode($response, true);
|
||||
|
||||
// ── Intento 2: CLI curl (usa GnuTLS / sistema, evita bug OpenSSL de PHP) ─
|
||||
error_log("WhatsAppService::uploadMedia: PHP curl falló (errno {$curlErrno}), usando curl CLI...");
|
||||
|
||||
if (!function_exists('exec') || !@exec('echo 1')) {
|
||||
throw new Exception("Error de conexión subiendo archivo (curl #{$curlErrno}): {$curlError} — fallback CLI no disponible");
|
||||
}
|
||||
|
||||
// Archivo temporal para la respuesta del CLI
|
||||
$tmpResponse = tempnam(sys_get_temp_dir(), 'wa_upload_');
|
||||
|
||||
$cmd = sprintf(
|
||||
'curl --silent --show-error'
|
||||
. ' --ipv4'
|
||||
. ' --tlsv1.2'
|
||||
. ' --max-time 300'
|
||||
. ' -o %s'
|
||||
. ' -w "%%{http_code}"'
|
||||
. ' -X POST'
|
||||
. ' -H %s'
|
||||
. ' -F %s'
|
||||
. ' -F %s'
|
||||
. ' -F %s'
|
||||
. ' %s'
|
||||
. ' 2>&1',
|
||||
escapeshellarg($tmpResponse),
|
||||
escapeshellarg('Authorization: Bearer ' . $this->token),
|
||||
escapeshellarg('messaging_product=whatsapp'),
|
||||
escapeshellarg('type=' . $mimeType),
|
||||
escapeshellarg('file=@' . $filePath . ';type=' . $mimeType),
|
||||
escapeshellarg($url)
|
||||
);
|
||||
|
||||
$cliHttpCode = null;
|
||||
$cliOut = null;
|
||||
@exec($cmd, $outputLines, $exitCode);
|
||||
$cliHttpCode = trim(implode('', $outputLines));
|
||||
$cliBody = @file_get_contents($tmpResponse);
|
||||
@unlink($tmpResponse);
|
||||
|
||||
error_log("WhatsAppService::uploadMedia (curl-cli) - exit: {$exitCode}, http: {$cliHttpCode}, body: " . substr((string)$cliBody, 0, 300));
|
||||
|
||||
if ($exitCode !== 0) {
|
||||
throw new Exception("Error de conexión subiendo archivo (curl CLI exit {$exitCode}): {$cliHttpCode}");
|
||||
}
|
||||
|
||||
$cliCode = intval($cliHttpCode);
|
||||
if ($cliCode !== 200 && $cliCode !== 201) {
|
||||
throw new Exception("Error subiendo archivo via CLI (HTTP {$cliCode}): " . $cliBody);
|
||||
}
|
||||
|
||||
$result = json_decode($cliBody, true);
|
||||
if (!isset($result['id'])) {
|
||||
throw new Exception("No se obtuvo ID del archivo subido: " . $response);
|
||||
throw new Exception("No se obtuvo ID del archivo subido (CLI): " . $cliBody);
|
||||
}
|
||||
|
||||
return $result; // Retorna el objeto completo con 'id'
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user