Как загрузить фото в пост ВКонтакте через API
При автоматизации постинга в группы ВКонтакте часто возникает задача прикрепить изображение к сообщению. Проблема в том, что токен, полученный для wall.post, может не подходить для загрузки файлов через photos.getWallUploadServer. В этой статье разберём, почему это происходит и как правильно настроить токены для работы с медиафайлами.
Почему токен для wall.post не подходит для загрузки фото
Метод photos.getWallUploadServer требует токен с особыми правами доступа (scope). Если при генерации токена вы указали только wall, то загрузка фото будет недоступна. Необходимо добавить разрешение photos в параметр scope при получении токена.
Также проверьте, что ваш токен не истёк - срок жизни некоторых токенов ограничен (например, 1 день для Implicit Flow). Используйте access_token с бессрочным сроком, если это возможно.
Как правильно получить токен с доступом к фото
Воспользуйтесь официальным Implicit Flow или Authorization Code Flow. В параметр scope укажите wall,photos,groups. Пример ссылки для получения кода:
https://oauth.vk.com/authorize?client_id=YOUR_CLIENT_ID&display=page&redirect_uri=https://oauth.vk.com/blank.html&scope=wall,photos,groups&response_type=token&v=5.131После успешной авторизации вы получите access_token в URL (после #). Сохраните его - он будет работать и для wall.post, и для photos.getWallUploadServer.
Пошаговая инструкция: загрузка фото и публикация поста
Шаг 1: Получите ссылку для загрузки
Отправьте GET-запрос к методу photos.getWallUploadServer с вашим токеном. Параметры: group_id (ID группы) и access_token. Ответ вернёт upload_url.
Шаг 2: Загрузите фото на сервер ВК
Отправьте POST-запрос на полученный upload_url с файлом изображения (multipart/form-data). В ответ получите server, photo и hash.
Шаг 3: Сохраните фото в альбоме группы
Вызовите метод photos.saveWallPhoto с параметрами: group_id, server, photo, hash и токен. Ответ вернёт массив с id и owner_id фото.
Шаг 4: Опубликуйте пост с прикреплённым фото
Теперь используйте wall.post с параметром attachments в формате photo{owner_id}_{id}. Например: photo-123456_789012.
Частые ошибки и их решение
- Ошибка доступа (15): токен не имеет прав
photos- перевыпустите токен с нужным scope. - Токен истёк: используйте бессрочный токен (Implicit Flow с
v=5.131и без указанияexpires_in) или обновляйте его регулярно. - Неверный group_id: убедитесь, что группа существует и бот является её администратором.
- Файл слишком большой: сжимайте изображение до 50 МБ (рекомендуется до 10 МБ).
Пример кода на Python
Ниже приведён упрощённый скрипт для загрузки фото и постинга:
import requests
token = 'ВАШ_ТОКЕН'
group_id = 'ID_ГРУППЫ'
# Получаем upload_url
url = 'https://api.vk.com/method/photos.getWallUploadServer'
params = {'group_id': group_id, 'access_token': token, 'v': '5.131'}
response = requests.get(url, params=params).json()
upload_url = response['response']['upload_url']
# Загружаем фото
files = {'photo': open('image.jpg', 'rb')}
upload_response = requests.post(upload_url, files=files).json()
# Сохраняем фото
save_url = 'https://api.vk.com/method/photos.saveWallPhoto'
save_params = {
'group_id': group_id,
'server': upload_response['server'],
'photo': upload_response['photo'],
'hash': upload_response['hash'],
'access_token': token,
'v': '5.131'
}
save_response = requests.post(save_url, params=save_params).json()
photo = save_response['response'][0]
attachment = f"photo{photo['owner_id']}_{photo['id']}"
# Публикуем пост
post_url = 'https://api.vk.com/method/wall.post'
post_params = {
'owner_id': -int(group_id),
'message': 'Текст поста',
'attachments': attachment,
'access_token': token,
'v': '5.131'
}
requests.post(post_url, params=post_params)После выполнения скрипта пост с изображением появится на стене группы.