@vasiliyshaidiuk

Как загрузить изображение на сервер vk?

Привет всем. В общем я пытаюсь сделать загрузку фото со своего компа на сервер вк, чтобы после его прикрепить к посту. Получаю адрес для загрузки, пытаюсь отправить файл на него, и в ответе получаю пустой массив photo:[] , тоесть мое фото просто не загрузилось. Пытался разными способами попробовать это сделать, в т.ч. менял формат с multipart/form-data на image/jpeg. В данный момент у меня такой код (напишу только свою функцию передачи файла):
spoiler
std::string Programm::UploadPhoto(std::string upload_url, std::string file)
// upload_url - ссылка, на которую загружается файл
// file - ссылка на файл на моем компе с окончанием расширения (test.png)
{
    std::string content, fields = "photo" + file;
    String^ managed = msclr::interop::marshal_as<String^>(file.c_str());
    if (!File::Exists(managed)) { return content = "no_photo"; }
 
    //----------------------------------------------------------
    CURL* curl;
    char buff[200];
    struct curl_httppost* post = NULL;
    struct curl_httppost* last = NULL;
 
    curl_global_init(CURL_GLOBAL_ALL);
    curl = curl_easy_init();
//  curl_formadd(&post, &last, CURLFORM_COPYNAME, "photo", CURLFORM_FILE, file.c_str(), CURLFORM_CONTENTTYPE, "image/jpeg", CURLFORM_END); // Так пробовал
//  curl_formadd(&post, &last, CURLFORM_COPYNAME, "photo", CURLFORM_FILE, file.c_str(), CURLFORM_CONTENTTYPE, "multipart/form-data", CURLFORM_END); // и так пробовал
    curl_formadd(&post, &last, CURLFORM_COPYNAME, "photo", CURLFORM_FILECONTENT, file.c_str(), CURLFORM_END);// и так..
 
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
    curl_easy_setopt(curl, CURLOPT_URL, upload_url.c_str());
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, fields.c_str());
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)fields.size());
 
    //  сохраняем html код cтраницы в строку content
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &content);
 
    CURLcode res = curl_easy_perform(curl);
 
    if (res != CURLE_OK)
    {
        sprintf(buff, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); //  fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        return std::string(buff);
    }
    //  else { return content = "res == CURLE_OK"; }
    return content;
    curl_easy_cleanup(curl);
}

Поддержка вк написала ссылку на некоторый сайт, где написан хороший пример на php, но мне на С++ пишу.. Меня в данном примере смущает функция curl_file_create, которой в либе libcurl на С++ я не нашел.. Код такой:
spoiler
function VKaddGoodsOnMarket ($name,$description,$category_id,$price,$photourl) {
  $vkToken = '';
  $vkGroupID = '';
  $vkVersionAPI = '5.60';
  //Получаем ссылку для загрузки фото
  $GET_getMarketUploadServer = [
    'group_id' => $vkGroupID, 
    'main_photo' => 1,
    'access_token' => $vkToken,
    'v' => $vkVersionAPI
  ];
  $resukt_url_dp = json_decode(file_get_contents('https://api.vk.com/method/photos.getMarketUploadServer?'.http_build_query($GET_getMarketUploadServer)), TRUE);
  //Загружаем фото КУРЛом, отправляя ПОСТ на полученю ссылку
  $curl_file = curl_file_create($photourl,'image/jpeg','test_name.jpg');
  $ch=curl_init();
  curl_setopt_array($ch, array(
  CURLOPT_RETURNTRANSFER => 1,
  CURLOPT_URL => $resukt_url_dp['response']['upload_url'],
  CURLOPT_POST => 1,
  CURLOPT_POSTFIELDS => array("photo" => $curl_file)
  ));
  //Получим массив с хешем и прочим
  $img_attach = json_decode(curl_exec($ch), true);
  
  //Сохраняем фоточку отпрявляя ГЕТ запрос в ВК
  $GET_saveMarketPhoto = [
    'group_id' => $vkGroupID, 
    'photo' => stripslashes($img_attach['photo']),
    'server' => $img_attach['server'],
    'hash' => $img_attach['hash'],
    'crop_data' => $img_attach['crop_data'],
    'crop_hash' => $img_attach['crop_hash'],
    'access_token' => $vkToken,
    'v' => $vkVersionAPI
  ];
  $photo = json_decode(file_get_contents('https://api.vk.com/method/photos.saveMarketPhoto?'.http_build_query($GET_saveMarketPhoto)), TRUE);
  
  $photoGoods = $photo['response'][0]['id'];
 
  $GET_marketadd = [
    'owner_id' => '-'.$vkGroupID.'',
    'name' => $name,
    'description' => $description,
    'category_id' => $category_id,
    'price' => $price,
    'main_photo_id' => $photoGoods,
    'access_token' => $vkToken,
    'v' => $vkVersionAPI
  ];
  $addMarket = json_decode(file_get_contents('https://api.vk.com/method/market.add?'.http_build_query($GET_marketadd)), TRUE);
  return $addMarket;
}


В инете есть куча решений этой проблемы, но увы, не на С++/CLI, на котором я пишу проект.. Помогите, пожалуйста) В приоритете мне нужно таким образом загружать изображение сразу со ссылки https://pu.vk.com/c..... , но если так нельзя - то уже делать загрузку изображения с моего компа.
  • Вопрос задан
  • 1460 просмотров
Пригласить эксперта
Ответы на вопрос 1
@sakost
Начинающий недопрограммист на python.
Попробуй в свой С++ интегрировать данный python скрипт
import requests

class API:
    API_URL = 'https://api.vk.com/method/'
    def __init___(self, image_path, access_token):
        self.img = image_path
        self.token = access_token
    def send(self):
        response = requests.post(self.API_URL + 'photos.getMessagesUploadServer', params={'access_token': self.token}).json()
        req = requests.post(response['upload_url'], params={'access_token': self.token}, files={'file': open(self.img, 'rb')}).json()
        req.update({'access_token': self.token})
        req = requests.post(self.API_URL + 'photos.saveMessagesPhoto', params=req)
        return req.json()
# Usage :
# api = API('img.jpeg', 'XXX')
# response = api.send()
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы