
本文详解如何通过 whatsapp cloud api 的媒体 id 获取图片 url,并正确下载二进制图像文件,重点解决因 user-agent 限制导致的“something went wrong”错误。
本文详解如何通过 whatsapp cloud api 的媒体 id 获取图片 url,并正确下载二进制图像文件,重点解决因 user-agent 限制导致的“something went wrong”错误。
在使用 WhatsApp Cloud API 接收消息时,若用户发送了图片,Webhook 仅会返回一个 media_id(如 123456789012345),而非原始图片数据。要获取实际图像,需分两步操作:先调用 Media Endpoint 获取临时访问 URL,再请求该 URL 下载二进制内容。但实践中常遇到第二步返回 "something went wrong" 文本而非图片——这并非认证或权限问题,而是 Facebook/WhatsApp 服务端对 HTTP 请求头(尤其是 User-Agent)做了严格校验。
✅ 正确做法:显式设置兼容的 User-Agent
WhatsApp Cloud API 的媒体 URL(形如 https://lookaside.fbsbx.com/...)要求请求必须携带被认可的 User-Agent,否则直接拒绝并返回 HTML 错误页(内容含 "something went wrong")。浏览器默认 UA 或空 UA 均不被接受;而 PostmanRuntime、curl 默认 UA 或某些爬虫 UA 可能被放行。
以下为完整、健壮的 PHP 示例代码(含错误处理与文件保存):
<?php $token = 'YOUR_ACCESS_TOKEN';
$mediaId = 'YOUR_MEDIA_ID'; // e.g., "123456789012345"
// Step 1: Get media metadata (including download URL)
$mediaUrl = "https://graph.facebook.com/v14.0/{$mediaId}";
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $mediaUrl,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer {$token}",
"Content-Type: application/json"
],
CURLOPT_FOLLOWLOCATION => true,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception("Media fetch failed: HTTP {$httpCode}, Response: {$response}");
}
$mediaData = json_decode($response, true);
if (!isset($mediaData['url'])) {
throw new Exception("No 'url' field in media response");
}
// Step 2: Download image binary from the signed URL
$downloadUrl = $mediaData['url'];
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $downloadUrl,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 60,
CURLOPT_FOLLOWLOCATION => true,
// ✅ Critical: Use an accepted User-Agent
CURLOPT_USERAGENT => 'PostmanRuntime/7.34.0',
// Optional but recommended: disable SSL verification only in dev
// CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer {$token}"
],
]);
$imageBinary = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception("Download failed: HTTP {$httpCode}, Error: {$error}");
}
// Save as file (e.g., with original MIME extension)
$extension = match($mediaData['mime_type'] ?? '') {
'image/jpeg', 'image/jpg' => '.jpg',
'image/png' => '.png',
'image/gif' => '.gif',
default => '.bin'
};
$filename = 'whatsapp_image_' . date('Ymd_His') . $extension;
file_put_contents($filename, $imageBinary);
echo "✅ Image saved successfully as {$filename} ({$mediaData['file_size']} bytes)";
?>
⚠️ 关键注意事项
-
User-Agent不可省略且必须有效:PostmanRuntime/7.34.0是经验证可用的 UA;也可尝试Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36,但避免使用空值或过于简化的 UA(如'curl')。 -
无需额外认证头?:虽然第二步仍传
Authorization: Bearer ...,但实际媒体 URL 已含签名参数(ext,hash),该 Header 对下载非必需(部分环境甚至可能干扰),但保留无害。 -
响应内容类型:确保
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true)启用,否则curl_exec()返回true而非二进制数据。 -
MIME 类型与文件扩展名:务必根据
mediaData['mime_type']决定后缀,避免.bin强制打开失败。 - 超时与重试:媒体 URL 有时效性(通常数小时),建议下载失败时记录日志并触发重试逻辑(如重新获取 media ID)。
✅ 总结
WhatsApp Cloud API 图片下载失败的核心原因,往往不是 token 或权限问题,而是服务端对 User-Agent 的隐式白名单策略。只需将第二步 cURL 请求的 User-Agent 显式设为 PostmanRuntime/7.34.0 等可信值,即可稳定获取二进制图像流。此方案已验证适用于 v14.0 及更高版本 Cloud API,是生产环境中可靠落地的关键实践。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











