Что будем делать и зачем

Кому-то может показаться что данная статья не нужна, или что она лишняя учитывая “подробность документации”, однако этот далеко не так. Даже у меня, мудрёного опытом человека, возникли вопросы, и в документации опущен очень важный момент, который я подробно опишу в статье. Мы попунктно пройдём все этапы от авторизации, до загрузки первого товара в группу. В данном проекте мы будем работать с vk api через одноимённую  библиотеку vk_api ознакомиться документацией можно тут. Она на русском языке, и довольно не плохо описаны все популярные методы.

Авторизация

Пожалуй самая важная часть проекта, это его авторизация)) как я и говорил выше, работать мы будем через библиотеку vk_api, которая существенно экономит время и нервы. Итак с чего же нам нужно начать? Кому-то может показаться отличной идеей использовать код из примера быстрого старта, и использовать авторизацию через телефон и пароль, но смею вас заверить, это плохая идея, и вот почему:

  • При многочисленных тестах, можно поймать капчу.
  • При частых запросах, или множестве аккаунтов, можно вообще упереться в лимиты.
  • Сессия авторизация храниться в кэши, при закрытии скрипта его нельзя переиспользовать.

Если эти аргументы для вас не показались убедительными, дело ваше, однако я рекомендую использовать токен. Получить его можно на данном сайте, под любые задачи и цели.

Преимущества токена?

  • Можно выгрузить его в переменную окружения, и не бояться компрометации.
  • Если даже токен был скомпрометирован, его не трудно отозвать, не меняя пароль.
  • Ограничения ответственности. Токен можно ограничить в правах на нужный раздел.
  • Опциональный подход. Для разных проектов, разные токены.
  • Не требует дополнительных запросов к серверу, а используется напрямую при выполнении задачи.

Как вы понимаете, подход авторизации через токен, имеет ряд преимуществ, которых лишён метод прямой авторизации. По этому мы рассмотрим пример моего кода, именно с использованием токена.

Важный момент !

У опытного, или любознательного разработчика, в этом месте возникнет закономерный вопрос, какой уровень доступа нужен для манипуляции над товарами в группе, ведь если верить официальной документации, зачем то нужно создавать Standalone приложение, потому получать коды запуска баллистических ракет, и отправлять на марс человека который это всё писал, зачем не ясно. А теперь серъёзно, для создания и редактирования товаров в сообществе, вам достаточно Implicit Flow авторизации, то есть обычной авторизации как пользователь сайта, т.е через токен, как я описал выше. Никаких дополнительных ключей доступа, или выделенных токенов получать не требуется! Для особо одарённых, сам вк пишет (видимо не тот же человек что писал новую документацию),

Ключи доступа используются для обращения к API ВКонтакте от имени сообщества.

Наша же задача, обращаться к сообществу как его администратор, или модератор у которого есть права на создание и редактирование товаров. Внимание, обязательно убедитесь в том, что вы были закреплены в правах, в противном случае вместе с разжалованием, клиент потеряет и автоматизацию. 

Итоги

И того, для успешной авторизации в вк, нам всего то и надо, получить токен, определить переменную, и произвести авторизацию, профит..

import vk_api 
vk_session = vk_api.VkApi(token='3735abсf7e9') 
vk = vk_session.get_api()

Получение сервера

Довольно странная механика, но что есть с тем и работаем. Для того что бы иметь возможность создать товар, в обязательном порядке должен быть передан параметр main_photo_id, как понятно из имени это id обложки, почему то создать товар без обложки нельзя, хотя вручную вполне себе можно. Итак приступим! Первое на что стоит обратить внимание это параметр main_photo=1, он необходим для того что бы после загрузки фото, мы получили в ответ параметры crop_data и crop_hash, без них использовать фото в качестве обложки не выйдет. Для получения ссылки, мы будем использовать специальный метод getMarketUploadServer

upload_server = vk.photos.getMarketUploadServer(group_id=0000000, main_photo=1)

Обратите внимание, что в group_id нужно передать id сообщества без символа минус.

В ответ нам приходит словарь с одним элементом, и постоянным ключом upload_url, который и содержит нужную нам ссылку для последующего POST запроса с изображением.

Отправляем фото на сервер

Важный этап, который почему-то многими игнорируется, а многими не понимается, опять же в связи с запутанным описанием в документации. На самом деле всё безумно просто, и как всегда решается в одну строку, которую мы подробно и рассмотрим. Для начала нам понадобиться библиотека requests или можно использовать urllib3, кому что удобнее.

load_data = requests.post(upload_server, files={'photo': open('main-photo.jpg', 'rb')}).json()

Прежде всего отвечу на вопрос, зачем тут переменная, если по сути у нас есть ссылка, и файл, что ещё нужно? А дело в том что это не финальный этап процесса к сожалению. Полученные данные нам нужно ещё передать в следующий метод, который занимается непосредственно сохранением. В документации к слову, описана необходимость, но даже нет ссылки на конкретный метод photos.saveMarketPhoto, а без него мы не сможем получить id обложки.

Получаем main_photo_id

Всё что мы делали до этого, вело нас к этому моменту. И мы наконец-то можем получить злосчастный main_photo_id, без которого мы не можем создать товар по правилам вк. То есть без описания можно, а вот без обложки нельзя))

Итак что нам понадобиться: в первую очередь переменная load_data из строчки выше, так-как в ней содержаться необходимые данные, на которых я не буду отдельно останавливаться, а лишь вкратце скажу что все они является обязательными. То есть переменная  load_data  содержит словарь, который мы просто распихиваем по нужным параметрам метода photos.saveMarketPhoto . Выглядеть это должно как-то так.


save_photo = vk.photos.saveMarketPhoto(group_id=group_id,
                                       photo=load_data['photo'],
                                       server=load_data['server'],
                                       hash=load_data['hash'],
                                       crop_data=load_data['crop_data'],
                                       crop_hash=load_data['crop_hash'])

Результатам работы данного метода, будет очередной json с ссылками на миниатюры, и большие варианты фото, и самое важное, это заветные id изображения в теневом альбоме группы. Отмечу так же, что переиспользовать один main_photo_id никак не выйдет, просто потому что он исчезает после генерации. Итак, если вы всё повторили верно, и получили заветный id, то можно приступать к финальной части нашего процесса, а именно к методу market.add

Генерация товара

Это пожалуй самая простая часть всего процесса, поскольку требует от вас исключительно внимательности, при составлении запроса. Итак, что же нам потребуется для создания товара внутри сообщества:

  • owner_id
  • main_photo_id
  • category_id
  • name
  • description
  • price

У меня в конечно итоге получился вот такой не замысловатый код, из двух базовых функций для корректной работы этого достаточно. Конечно выглядит сыро, но зато наглядно.


import vk_api
import requests


vk_session = vk_api.VkApi(token='vk1.a.wj5PglIR')
vk = vk_session.get_api()


def upload_product_img(group_id: int, file_name: str) -> int:
    """
    Функция служит для загрузки обложки товара, и получения её id.
    Так-как без обложки создать товар невозможно, нам необходима эта функция.
    :param group_id: айди группы, без минуса.
    :param file_name: путь/имя изображения товара.
    :return: int айди будущей  обложки.
    """
    # Получаем сервер для загрузки обложки.
    upload_server = vk.photos.getMarketUploadServer(group_id=group_id, main_photo=1)['upload_url']
    # Загружаем изображение на сервер, получаем его мета данные.
    load_data = requests.post(upload_server, files={'photo': open(file_name, 'rb')}).json()
    # Сохраняем мета данные изображения, и получаем id обложки, для создания товара.
    save_photo = vk.photos.saveMarketPhoto(group_id=group_id,
                                           photo=load_data['photo'],
                                           server=load_data['server'],
                                           hash=load_data['hash'],
                                           crop_data=load_data['crop_data'],
                                           crop_hash=load_data['crop_hash'])

    # Возвращаем id сохранённой фото, что бы создать товара.
    return save_photo[0]['id']


def create_product(product_name: str, product_price: [int, float],
                   product_description: str, group_id: int, main_photo: str):

    # Получаем необходимый айди, для обложки.
    photo_id = upload_product_img(group_id, main_photo)
    # Отправляем запрос на создание товара.
    response = vk.market.add(owner_id=f'-{group_id}',
                             main_photo_id=photo_id,
                             category_id=1,
                             name=product_name,
                             price=product_price,
                             description=product_description)

    if response.get('market_item_id') is not None:
        return response['market_item_id']

    else:
        raise Exception(response)


create_product('Имя продукта', 1110.40444, 'Описание товара', 0000000, 'name.jpg')
[mpc_divider preset=”mpc_preset_20″ content_type=”title” content_position=”100″ content_border_css=”border-width:2px;border-color:#f29760;border-style:solid;” content_padding_divider=”true” content_padding_css=”padding-top:5px;padding-right:15px;padding-bottom:5px;padding-left:15px;” font_color=”#f29760″ font_size=”16″ font_line_height=”1″ font_transform=”uppercase” font_align=”center” title=”ИТОГИ” icon=”fa fa-paint-brush” icon_color=”#76bdcc” icon_size=”30″ lines_color=”#f29760″ lines_weight=”2″]

На этом пока всё, самое основное надеюсь вы усвоили. И вот казалось бы, такая простая задача, а сколько гемора придумывает команда вконтакте, для реализации базовой задачи. Я бы мог конечно разобрать пакетную загрузку товаров, но думаю что разберётесь если нужно, самое главное, что я смог сэкономить ваше время (надеюсь), на поиск готовых решения, и примеров.

Всем добра, и мира.