130 lines
9.3 KiB
Markdown
130 lines
9.3 KiB
Markdown
# Исследование 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"`).
|