randomayzer/docs/VK_API_RESEARCH.md

9.3 KiB
Raw Permalink Blame History

Исследование VK API для проведения розыгрышей

Данный документ содержит детальный анализ методов официального VK API, типов токенов, ограничений, прав доступа и лимитов для реализации сервиса розыгрышей.


1. Типы токенов и уровни доступа

Тип токена Как получается Права / Scope Применимость в розыгрышах Ограничения
Сервисный ключ доступа (Service Token) В настройках VK App (Standalone / Web) Публичные данные (стены открытых групп, открытые профили) Базовый сбор лайков и комментариев с открытых стен Не может получать список репостов (wall.getReposts), не может проверять закрытые профили
Ключ сообщества (Community / Group Token) В настройках группы (Управление -> Работа с API) wall, photos, messages, manage Идеален, когда розыгрыш проводит само сообщество-организатор Работает только в рамках данного сообщества
Пользовательский токен (User Token / OAuth) VK ID OAuth 2.0 (Implicit Flow / Authorization Code) wall, groups, friends, offline Максимальный доступ (проверка репостов, членства в закрытых группах) Требует авторизации организатора через VK ID

2. Ключевые методы VK API для розыгрыша

2.1. Получение информации о посте

  • Метод: wall.getById
  • Параметры:
    • posts: строка формата "{owner_id}_{post_id}" (например, -123456_7890)
    • extended: 1 (возвращает данные авторов и прикрепленных сообществ)
  • Токен: Сервисный, Сообщества или Пользовательский.
  • Возвращаемые данные: Текст записи, вложения (фотографии/видео), счетчики (likes.count, comments.count, reposts.count, views.count), дата публикации.

2.2. Сбор лайков

  • Метод: likes.getList
  • Параметры:
    • type: "post"
    • owner_id: ID владельца стены (отрицательный для групп)
    • item_id: ID записи
    • filter: "likes" (или "copies" для репостов)
    • extended: 1 (возвращает имя, фамилию, аватарку)
    • count: до 1000 за один запрос
    • offset: смещение для пагинации
  • Токен: Сервисный или Пользовательский.
  • Особенности: Позволяет быстро выгрузить до 1000 пользователей за запрос. С помощью execute можно за один сетевой запрос выгрузить до 25 000 лайков.

2.3. Сбор комментариев

  • Метод: wall.getComments
  • Параметры:
    • owner_id: ID сообщества / пользователя
    • post_id: ID записи
    • need_likes: 0 или 1
    • extended: 1 (возвращает профили комментаторов profiles и groups)
    • count: до 100 за один запрос
    • offset: смещение
    • fields: "photo_100,photo_200,screen_name,sex"
  • Токен: Сервисный или Пользовательский.
  • Особенности: Лимит 100 комментариев на вызов. Для постов с тысячами комментариев необходима пакетная выгрузка через execute.

2.4. Сбор и проверка репостов

  • Метод 1: wall.getReposts
    • Параметры: owner_id, post_id, count (до 1000), offset
    • Ограничение: Метод возвращает только репосты на открытые стены и доступен преимущественно с пользовательским токеном с правами wall или токеном сообщества.
  • Метод 2: likes.getList с параметром filter="copies"
    • Возвращает пользователей, сделавших репост записи (если их профили и настройки приватности позволяют отображать действие).
  • Спорные места и Privacy Policy VK:
    • Если профиль пользователя закрыт (приватный аккаунт), стороннее приложение не может увидеть репост на его стене без авторизации самого этого пользователя. В регламенте розыгрышей организаторы обычно указывают: "На время розыгрыша страница участника должна быть открыта".

2.5. Проверка подписки на сообщество

  • Метод 1 (пакетная проверка): groups.isMember
    • Параметры: group_id, user_id или user_ids (до 500 ID через запятую), extended: 1
    • Возвращает: member: 1/0, can_invite, can_post.
    • Высокая скорость: можно проверить сразу пачку из 500 участников.
  • Метод 2 (полный список подписчиков): groups.getMembers
    • Параметры: group_id, count (до 1000), offset, fields
    • Подходит для сверки базы подписчиков.

3. Оптимизация через execute (VK Script)

VK API предоставляет процедуру execute, позволяющую исполнять код на серверах VK (язык VKScript, подмножество JS/ActionScript).

  • Лимит: До 25 вызовов API внутри одного execute.
  • Эффективность:
    • likes.getList: 25 * 1000 = 25 000 лайков за 1 сетевой HTTP-запрос.
    • groups.isMember: 25 * 500 = 12 500 проверок подписки за 1 запрос.
    • wall.getComments: 25 * 100 = 2 500 комментариев за 1 запрос.

Пример VKScript для пакетного сбора лайков:

var owner_id = Args.owner_id;
var item_id = Args.item_id;
var offset = parseInt(Args.offset);
var i = 0;
var all_items = [];
while (i < 25) {
    var res = API.likes.getList({
        "type": "post",
        "owner_id": owner_id,
        "item_id": item_id,
        "count": 1000,
        "offset": offset + (i * 1000),
        "extended": 1
    });
    if (res.items.length == 0) {
        return {"items": all_items, "count": res.count, "done": 1};
    }
    all_items = all_items + res.items;
    i = i + 1;
}
return {"items": all_items, "offset": offset + (i * 1000), "done": 0};

4. Лимиты и Rate Limiting

  • Частота запросов:
    • Пользовательский токен: до 3 запросов в секунду.
    • Сервисный ключ / токен сообщества: до 20 (в некоторых случаях до 50) запросов в секунду.
    • При превышении возвращается Error 6: Too many requests per second.
  • Обработка ошибок:
    • Error 15: Access denied — закрытая группа/профиль.
    • Error 18: User was deleted or banned — деактивированные аккаунты (собачки), которые автоматически должны исключаться фильтрами.
    • Error 29: Rate limit reached — дневной лимит.

5. Выводы для Архитектуры приложения

  1. Многоуровневый сбор данных:
    • На этапе 1 создана модульная архитектура со слоем SocialMediaProvider.
    • Реализован VkMockProvider для детерминированного тестирования и работы без ключей API, и каркас VkProvider с чистыми контрактами.
  2. Асинхронность и очереди:
    • Для масштабных розыгрышей (10 000+ участников) сбор данных должен происходить поэтапно (лайки -> комменты -> подписка) с индикатором прогресса в UI.
  3. Требование открытых профилей:
    • В UI и аудит-отчете необходимо явно фиксировать причину недопуска (exclusionReason = "PRIVATE_PROFILE_OR_NO_REPOST", "NOT_SUBSCRIBED", "IS_ADMIN", "DUPLICATE_COMMENT").