randomayzer/docs/VK_API_RESEARCH.md

130 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Исследование 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 для пакетного сбора лайков:
```javascript
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"`).