diff --git a/services/WhatsAppService.php b/services/WhatsAppService.php index 0909597..f9ccc46 100644 --- a/services/WhatsAppService.php +++ b/services/WhatsAppService.php @@ -433,20 +433,32 @@ class WhatsAppService $url = $this->apiUrl . $this->phoneNumberId . '/media'; $errors = []; - // ── Intento 1: PHP curl TLS 1.2 + sin ALPN + IPv4 ────────────────────── - $a1 = $this->_curlUploadAttempt($url, $filePath, $mimeType, [ + // ── Intento 1: PHP curl TLS 1.2 + sin ALPN + IPv4 (hasta 3 reintentos) ── + // curl1 logra conectar por TCP pero puede fallar en el envío (errno 55). + // Reintentar es útil: el error es del lado del CDN de Meta y suele desaparecer. + $a1Opts = [ CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2, - CURLOPT_SSL_ENABLE_ALPN => false, + CURLOPT_SSL_ENABLE_ALPN => false, // sin ALPN → HTTP/1.1 → CDN diferente (alcanzable) + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4, - ]); - if ($a1['ok']) return $a1['result']; + ]; + $a1 = null; + for ($try = 1; $try <= 3; $try++) { + $a1 = $this->_curlUploadAttempt($url, $filePath, $mimeType, $a1Opts); + if ($a1['ok']) return $a1['result']; + error_log("WhatsAppService::uploadMedia a1 intento{$try} fail: errno={$a1['errno']} http={$a1['http']}"); + if ($try < 3) sleep(1); + } $errors[] = "curl1: #{$a1['errno']}({$a1['error']}) http={$a1['http']}"; - error_log("WhatsAppService::uploadMedia a1 fail: {$errors[0]}"); - // ── Intento 2: PHP curl SSL deshabilitado + IPv4 (bypassa verificación) ── + // ── Intento 2: PHP curl SSL deshabilitado + sin ALPN + HTTP/1.1 ────────── + // IMPORTANTE: ALPN desactivado es crítico — con ALPN activo curl resuelve a un + // IP de graph.facebook.com que no tiene ruta en el contenedor (errno 7 inmediato). $a2 = $this->_curlUploadAttempt($url, $filePath, $mimeType, [ CURLOPT_SSL_VERIFYPEER => false, - CURLOPT_SSL_VERIFYHOST => false, + CURLOPT_SSL_VERIFYHOST => 0, + CURLOPT_SSL_ENABLE_ALPN => false, // mismo truco que curl1 + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4, ]); if ($a2['ok']) return $a2['result']; @@ -620,8 +632,11 @@ class WhatsAppService $args = [ $curlBin, '--silent', '--show-error', - '--ipv4', // forzar IPv4 (evita errno 7 por IPv6 no ruteado) + '--ipv4', // forzar IPv4 '--tlsv1.2', + '--http1.1', // sin ALPN→HTTP/2: graph.facebook.com CDN alcanzable + '--no-alpn', // desactiva ALPN extension (igual que CURLOPT_SSL_ENABLE_ALPN=false) + '--insecure', // bypass SSL verify (fallback de último recurso) '--max-time', '300', '-o', $tmpResponse, '-w', '%{http_code}',