Skip to content

Commit

Permalink
актуализация данных
Browse files Browse the repository at this point in the history
  • Loading branch information
danyadev committed Aug 26, 2023
1 parent ff6a150 commit bda1016
Showing 1 changed file with 36 additions and 66 deletions.
102 changes: 36 additions & 66 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,41 +77,32 @@ __Long Polling__ — это технология, которая позволя
`server`, `key` и `ts` получаются методом [`messages.getLongPollServer`](https://dev.vk.com/method/messages.getLongPollServer)

Важные параметры при вызове метода:
- в `need_pts` следует указать `1`
- в `lp_version` следует указать актуальную версию - 19

* `server` - Домен лонгполла. Индивидуален для каждого пользователя, а так же может различаться у некоторых приложений
* `server` - Домен лонгполла. Индивидуален для каждого пользователя. Может отличаться у некоторых приложений, от имени которых получался токен
* `key` - Ключ для идентификации активной сессии. Протухает через час и привязан к айпи адресу
* `ts` - Номер последнего события. Лонгполл будет возвращать события, следующие за ним
* `version` - Версия LongPoll, актуальная версия - 19.
Поведение предыдущих версий может измениться или их поддержка может быть прекращена
* `version` - Версия лонгполла
* `wait` - Время ожидания нового события в секундах, максимум `90`. Рекомендуемое значение: `20`
* `mode` - Настройка формата ответа. Рекомендуемое значение:
`(1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | (1 << 10)`

TODO: информация о бизнес-уведомлениях

| Бит | Описание |
|-----------|-------------------------------------------------------------------------------------------------------|
| `1 << 1` | Возвращать кладжи (секции `additional` и `attachments` в [структуре сообщения](#структура-сообщения)) |
| `1 << 3` | Возвращать расширенную информацию в [114], [115] и [119] событиях |
| `1 << 5` | Возвращать `pts` |
| `1 << 6` | **[deprecated]** Возвращать события изменения онлайна друзей: [8] и [9] |
| `1 << 6` | **[неактуально]** Возвращать события изменения онлайна друзей: [8] и [9] |
| `1 << 7` | Возвращать [`random_id`](#зачем-нужен-random_id) |
| `1 << 9` | Возвращать события о бизнес-уведомлениях |
| `1 << 10` | Возвращать тип `online` для `marked_users` при упоминании через `@online` |

**[deprecated]** у `1 << 6` бита выставлен, потому что события [8] и [9] больше не возвращаются из лонгполла

После выполнения запроса сервер вернет ответ следующего вида:
```ts
type LongPollResult =
// pts приходит, если в mode выставлен бит (1 << 5)
// updates - массив событий, которые описаны в разделе "Описание событий"
| { ts: number, pts: number, updates: unknown[] }
// ts слишком маленький (отстал более чем на 256 событий) или слишком большой.
// Необходимо воспользоваться переданным ts (лонгполл возвращает номер последнего события).
// ts слишком маленький (отстал более чем на 256 событий) или слишком большой (больше последнего существующего).
// Необходимо воспользоваться переданным ts (возвращается номер последнего события).
// Как получить пропущенные события можно узнать в разделе "Получение истории событий" чуть ниже
| { failed: 1, ts: number }
// Ключ инвалидировался. Необходимо получить новый key, используя метод messages.getLongPollServer
Expand All @@ -122,42 +113,17 @@ type LongPollResult =
После обработки ответа нужно повторить запрос, но с новым значением `ts`.
Также необходимо сохранить полученный `pts`, чтобы при получении ошибки от лонгполла иметь возможность
[получить пропущенные события](#получение-истории-событий).
Очень важно обработать описанные ошибки, потому что вы с ними обязательно столкнетесь.
Напомню, что время жизни ключа лонгполла всего час, и после его протухания придет 2 ошибка.
А с 1 ошибкой вы столкнетесь, когда на некоторое время приостановите походы в лонгполл, например когда
система уйдет в спящий режим, либо пропадет соединение с сетью по иным причинам.
## Получение истории событий
Получать историю событий необходимо в том случае, когда лонгполл вернул `failed: 1` из-за слишком большого числа новых событий.
Если лонгполл вернул `failed: 1`, у вас все еще есть возможность получить пропущенные события.
Для получения истории событий нам необходим `pts` последнего известного вам события. С этим параметром нужно вызвать метод
[`messages.getLongPollHistory`](https://dev.vk.com/method/messages.getLongPollHistory).
1) Включите получение `pts` при [подключении](#подключение) к лонгполлу, добавив флаг `1 << 5` в `mode`
2) Всегда сохраняйте возвращаемый лонгполлом `pts`
3) С использованием `pts` и некоторых других параметров, описанных в документации, вызовите метод
[`messages.getLongPollHistory`](https://dev.vk.com/method/messages.getLongPollHistory).
Ответ выглядит следующим образом:
```ts
// TODO: новые тайпинги
// Описание типов:
// https://github.com/danyadev/vk-types#объекты
interface LongPollHistoryResult {
history: any[][]
from_pts: number
new_pts: number
conversations: VKConversation[]
messages: {
count: number
items: VKMessage[]
}
profiles?: VKUser[]
groups?: VKGroup[]
more?: true
}
```

TODO: рассказать подробнее про обработку поля `history`
Формат ответа метода описан здесь:
https://github.com/VKCOM/api-schema-typescript/blob/master/src/methods/messages.ts#L773
Поле `history` похоже на поле `updates` из лонгполла, но в нем будут находиться только персистентные события.
Так же события из этого списка придут в урезанном виде:
Expand All @@ -166,9 +132,12 @@ TODO: рассказать подробнее про обработку поля
- `5` - [Редактирование сообщения](#событие-10005-редактирование-сообщения)
- `18` - [Обновление сообщения](#событие-10018-обновление-сообщения)
Как можно заметить, вместо `10000 + eventId` событий приходят события 3, 4, 5 и 18.
Соответственно вместо `conversationMessageId` приходит просто `messageId`.
Сам `conversationMessageId` при необходимости можно достать из поля `messages` в ответе метода.
Структура этих событий выглядит так:
```ts
// TODO: да, здесь приходят такие события, а не 10000 + type
type LongPollHistoryMessageEvent = [
type: 3 | 4 | 5 | 18,
messageId: number,
Expand All @@ -192,8 +161,6 @@ type LongPollHistoryMessageEvent = [
- [Вложения](#вложения)
- [random_id](#зачем-нужен-random_id)
> Структура описывает массив, ключи используются для упрощения визуального восприятия
```ts
type LongPollMessage = [
type: 10003 | 10004 | 10005 | 10018,
Expand All @@ -204,6 +171,7 @@ type LongPollMessage = [
minorId?: number,
peerId: number,
timestamp: number,
// Переносы строк обозначаются как <br>, а символы " & < > экранируются
text: string,

// Объект приходит только при указании флага 2 при подключении к LongPoll
Expand Down Expand Up @@ -271,8 +239,6 @@ type LongPollMessage = [
];
```
Стоит отметить, что в поле `text` переносы строк обозначаются как `<br>`, а символы `"`, `&`, `<` и `>` экранируются.

### Короткий кортеж сообщения
Существует возможность возвращения укороченного кортежа с сообщением.
Expand All @@ -282,7 +248,7 @@ type LongPollMessage = [
`random_id`, то с этим событием определенно возникнут проблемы, потому что в нем отсутствует
`random_id`. Чтобы получить `random_id`, нужно запросить сообщение через апи:
в случае `10004` события по `minorId` (в данном случае это синоним `message_id`),
или в случае остальных событий по `cmid` (`conversationMessageId`) и `peerId`.
или в случае остальных событий по `conversationMessageId` и `peerId`.
Далее, если сообщение было не нашим, апи вернет ошибку и мы ее проигнорируем, а если сообщение
было нашим - вернет сообщение с полем `deleted: 1` и искомым `random_id`.
Expand Down Expand Up @@ -526,6 +492,7 @@ type Event10013 = [
```
### Событие 10018. Обновление сообщения
[10018]: #событие-10018-обновление-сообщения
Приходит при следующих событиях:
1. Добавился сниппет (ссылка) - к вложениям добавляется `link`.
Expand Down Expand Up @@ -599,9 +566,9 @@ type Event21 = [
### Событие 50. Перевод сообщения
Это событие приходит, если пользователь запросил перевод сообщения. Для этого надо выполнить метод `messages.translate` (доступен только официальным клиентам, параметры см. ниже). Метод возвращает `1`.
Это событие приходит, если пользователь запросил перевод сообщения.
Если для определённого сообщения перевод запрашивается в первый раз, то вместе с событием `50` приходит и [событие `10018`](#событие-10018-обновление-сообщения), где в объекте `additional` будет поле `is_translated`.
Если для определённого сообщения перевод запрашивается в первый раз, то вместе с событием `50` приходит и событие [10018], где в объекте `additional` будет поле `is_translated`.
```ts
type Event50 = [
Expand All @@ -615,16 +582,13 @@ type Event50 = [
];
```
Пример события:

```js
[50, {"peer_id": 2000000026, "cmid":476587, "translation":"There are 253 reactions", "language":"ru-en"}]
```

Поле `language` представляет собой языковую пару, который выглядит так: `ru-en`. Перед дефисом прописан исходный язык переводимого текста, после дефиса — язык, на который будет переведён текст.
Поле `language` представляет собой языковую пару, который выглядит так: `ru-en`.
Перед дефисом прописан исходный язык переводимого текста, после дефиса — язык, на который будет переведён текст.
Список поддерживаемых языковых пар можно получить, выполнив метод `account.getInfo`. В ответе будет поле `messages_translation_language_pairs`.
Чтобы запросить перевод сообщения, нужно выполнить метод `messages.translate` (доступен только официальным клиентам).
Параметры метода `messages.translate`:
```ts
interface MessagesTranslateParams {
Expand Down Expand Up @@ -661,7 +625,7 @@ type Event51 = [
| 7 | Выход из беседы | `id` вышедшего |
| 8 | Исключение из беседы | `id` исключенного |
| 9 | Разжалован администратор | `id` бывшего админа |
| 10 | Изменился баннер (какая-то инфа под шапкой в личке) | `0` |
| 10 | Изменился баннер | `0` |
| 11 | Появление или скрытие клавиатуры | `peerId` |
| 12 | Отозвано / подтверждено / отклонено / пришло приглашение в чат | `0` / `1` / `2` / `3` |
| 13 | Контакт был сконвертирован в юзера (`contactId` -> `userId`) | `contactId` |
Expand All @@ -673,14 +637,18 @@ type Event51 = [
| 19 | Начало или окончание группового звонка | `1` в начале, `0` в конце |
| 22 | Чат больше не новый: пришло первое сообщение (только в лс) | `0` |
| 23 | Изменено оформление чата | `0` |
| 24 | Изменилось описание чата | `0` |
| 25 | Изменилось состояние `chat_settings.short_poll_reactions` | `0` / `1` |
| 26 | _soon_ | _soon_ |
| 27 | _soon_ | _soon_ |
| 28 | _soon_ | _soon_ |
При изменении названия (`1`) и обновлении аватарки беседы (`2`) нужные данные можно взять из
[сервисного сообщения](#сервисные-сообщения) в [4 событии](#событие-4-новое-сообщение).
```ts
type Event52 = [
type: 52,
// 0-19, 22, 23
updateType: number,
peerId: number,
extra: number
Expand Down Expand Up @@ -1191,7 +1159,10 @@ interface LongPollKeyboard {
#### Список существующих вложений
Список известных на данный момент вложений: `geo`, `doc`, `link`, `poll`, `wall`, `call`, `gift`, `story`, `photo`, `audio`, `video`, `event`, `market`, `artist`, `widget`, `sticker`, `article`, `podcast`, `curator`, `graffiti`, `mini_app`, `narrative`, `wall_reply`, `audio_message`, `money_request`, `audio_playlist`, `group_call_in_progress`.
Список известных на данный момент вложений:
`geo`, `doc`, `link`, `poll`, `wall`, `call`, `gift`, `story`, `photo`, `audio`, `video`, `event`, `market`, `artist`, `widget`, `sticker`,
`article`, `podcast`, `curator`, `graffiti`, `mini_app`, `narrative`, `wall_reply`, `audio_message`, `money_request`, `audio_playlist`,
`group_call_in_progress`.
Однако названия вложений, полученных через LongPoll, могут не совпадать с теми, что приходят через API:
- `event`, приходящий в API, в LongPoll обозначается как `group`
Expand Down Expand Up @@ -1228,8 +1199,7 @@ const longpollAttachments = {
и анализа списка вложений, чтобы в случае необходимости получить сообщение через [API](https://dev.vk.com/method/messages.getById).
<details>
<summary markdown="span">Пример кода для получения массива с названиями вложений
</summary>
<summary markdown="span">Пример кода для получения массива с названиями вложений</summary>
```js
function getAttachments(data) {
Expand Down

0 comments on commit bda1016

Please sign in to comment.