В webhook WhatsApp Cloud API обычно приходит идентификатор медиа, а не постоянная публичная ссылка на файл.
Скачивание состоит из двух авторизованных запросов: сначала получается временный URL, затем по нему забирается содержимое. Ошибка на любом этапе выглядит как недоступное вложение.
На каком этапе ломается загрузка
Разделите получение события, запрос метаданных и потоковое скачивание файла.
- Webhook принят, но в нем нет прямого URL на изображение или документ.
- Запрос по media ID возвращает ошибку доступа или объект не найден.
- Временный URL получен, но позже отвечает 401, 403 или 404.
- Файл сохраняется пустым, поврежденным или с неверным расширением.
Почему возникает проблема
Чаще всего проблема связана с устаревшей ссылкой, неподходящим токеном или неправильной обработкой бинарного ответа.
- Media ID ошибочно воспринимается как URL или имя файла.
- В запросе отсутствует действующий access token с нужными правами.
- Временная ссылка сохраняется в очередь слишком надолго и успевает истечь.
- Приложение читает бинарный ответ как JSON или текст.
- Медиа относится к другому business account или phone number context.
Пошаговая диагностика
Логи должны показывать этап и код ответа, но не содержать полный токен или временный URL.
- Сохраните media ID, message ID, MIME type и время получения webhook.
- Проверьте запрос метаданных к поддерживаемой версии Graph API.
- Убедитесь, что токен принадлежит нужному приложению и бизнес-контексту.
- Скачайте файл сразу после получения URL с заголовком авторизации.
- Сравните Content-Type, Content-Length и фактически записанное число байт.
Не храните временную ссылку как адрес файла
Надежнее ставить в очередь media ID и выполнять оба запроса рядом по времени.
- Задача скачивания содержит media ID и идентификатор исходного сообщения.
- Временный URL запрашивается непосредственно перед загрузкой.
- Результат сохраняется в собственное закрытое хранилище.
- Повторная обработка не создает дубли одного вложения.
Как исправить проблему
Исправьте цепочку запросов и добавьте контролируемый повтор для временных сбоев.
- Получайте метаданные и URL по media ID с актуальным токеном.
- Скачивайте содержимое потоково и передавайте авторизацию в запросе.
- Определяйте расширение по подтвержденному MIME type, а не по URL.
- Ограничьте размер файла и время загрузки до записи в хранилище.
- При истекшем URL запросите новый, не повторяя бесконечно старую ссылку.
Как проверить результат
- Изображения, документы, аудио и видео проходят один контролируемый pipeline.
- Размер и MIME сохраненного файла совпадают с метаданными.
- Повтор webhook не создает второй файл и вторую бизнес-операцию.
- Токены и временные ссылки отсутствуют в открытых логах.
Типичные ошибки
- Открывать media ID в браузере как публичную ссылку.
- Сохранять временный URL для скачивания через несколько часов.
- Писать access token целиком в журнал ошибок.
- Повторять любой ответ без ограничения попыток и анализа кода.
Как предотвратить повторение
- Мониторьте долю ошибок отдельно для метаданных и загрузки файла.
- Обновляйте версию Graph API и проверяйте права токена заранее.
- Используйте идемпотентность по message ID и media ID.
- Добавьте карантин для файлов с неподдерживаемым типом или размером.
Когда нужна помощь
Если вложения WhatsApp не скачиваются, я проверю webhook, media ID, права токена и бинарную загрузку, настрою надежное хранение и повтор без дублей и утечки секретов.