{"id":15134006,"url":"https://github.com/danyadev/longpoll-doc","last_synced_at":"2025-10-23T09:31:20.099Z","repository":{"id":44730041,"uuid":"229048663","full_name":"danyadev/longpoll-doc","owner":"danyadev","description":"Документация для последней версии User LongPoll API","archived":false,"fork":false,"pushed_at":"2024-04-26T15:19:45.000Z","size":233,"stargazers_count":83,"open_issues_count":0,"forks_count":7,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-01-30T17:38:26.229Z","etag":null,"topics":["longpoll","poll-api","polling","vk-api","vkontakte"],"latest_commit_sha":null,"homepage":"https://danyadev.github.io/longpoll-doc/","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/danyadev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-12-19T12:20:03.000Z","updated_at":"2024-11-14T08:00:13.000Z","dependencies_parsed_at":"2024-04-26T16:30:16.435Z","dependency_job_id":null,"html_url":"https://github.com/danyadev/longpoll-doc","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danyadev%2Flongpoll-doc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danyadev%2Flongpoll-doc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danyadev%2Flongpoll-doc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danyadev%2Flongpoll-doc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danyadev","download_url":"https://codeload.github.com/danyadev/longpoll-doc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237807464,"owners_count":19369596,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["longpoll","poll-api","polling","vk-api","vkontakte"],"created_at":"2024-09-26T05:01:55.658Z","updated_at":"2025-10-23T09:31:20.090Z","avatar_url":"https://github.com/danyadev.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# User LongPoll API\n\n__Long Polling__ — это технология, которая позволяет получать данные о новых событиях с помощью \"длинных запросов\".\nСервер получает запрос, но отправляет ответ на него не сразу, а лишь тогда, когда произойдет какое-либо событие (например, придёт новое сообщение),\nлибо истечет заданное время ожидания. После ответа клиент сразу же делает повторный запрос на сервер.  \nТаким образом поддерживается постоянное соединение с сервером, что позволяет получать новые события в реальном времени.\n\nНемного подробнее о технологии можно почитать [здесь](https://learn.javascript.ru/long-polling).\n\nДокументация написана для __21__ версии LongPoll.\n\n## План документации:\n\n0. [Отказ от ответственности](#отказ-от-ответственности)\n1. [Подключение](#подключение)\n2. [Получение истории событий](#получение-истории-событий)\n3. [Структура сообщения](#структура-сообщения)\n   - [Короткий кортеж сообщения](#короткий-кортеж-сообщения)\n4. [Описание событий](#описание-событий)\n   - [Событие 10002. Установка флагов сообщения](#событие-10002-установка-флагов-сообщения)\n   - [Событие 10003. Сброс флагов сообщения](#событие-10003-сброс-флагов-сообщения)\n   - [Событие 10004. Новое сообщение](#событие-10004-новое-сообщение)\n   - [Событие 10005. Редактирование сообщения](#событие-10005-редактирование-сообщения)\n   - [Событие 10006. Прочтение входящих сообщений](#событие-10006-прочтение-входящих-сообщений)\n   - [Событие 10007. Прочтение исходящих сообщений](#событие-10007-прочтение-исходящих-сообщений)\n   - [Событие 8. Друг появился в сети](#событие-8-друг-появился-в-сети) **[disabled]**\n   - [Событие 9. Друг вышел из сети](#событие-9-друг-вышел-из-сети) **[disabled]**\n   - [Событие 10. Сброс флагов беседы](#событие-10-сброс-флагов-беседы)\n   - [Событие 12. Установка флагов беседы](#событие-12-установка-флагов-беседы)\n   - [Событие 10013. Удаление всех сообщений в диалоге](#событие-10013-удаление-всех-сообщений-в-диалоге)\n   - [Событие 10018. Обновление сообщения](#событие-10018-обновление-сообщения)\n   - [Событие 10019. Сброс кеша сообщения](#событие-10019-сброс-кеша-сообщения)\n   - [Событие 20. Закрепление и открепление беседы (изменился majorId)](#событие-20-закрепление-и-открепление-беседы-изменился-majorid)\n   - [Событие 21. Изменился minorId](#событие-21-изменился-minorid)\n   - [Событие 50. Перевод сообщения](#событие-50-перевод-сообщения)\n   - [Событие 51. Изменение данных чата](#событие-51-изменение-данных-чата) **[deprecated]**\n   - [Событие 52. Изменение данных чата](#событие-52-изменение-данных-чата)\n   - [Событие 63. Статус набора сообщения](#событие-63-статус-набора-сообщения)\n   - [Событие 64. Статус записи голосового сообщения](#событие-64-статус-записи-голосового-сообщения)\n   - [Событие 65. Статус загрузки фотографии](#событие-65-статус-загрузки-фотографии)\n   - [Событие 66. Статус загрузки видеозаписи](#событие-66-статус-загрузки-видеозаписи)\n   - [Событие 67. Статус загрузки файла](#событие-67-статус-загрузки-файла)\n   - [Событие 68. Статус записи видеосообщения](#событие-68-статус-записи-видеосообщения)\n   - [Событие 80. Изменение количества непрочитанных диалогов](#событие-80-изменение-количества-непрочитанных-диалогов)\n   - [Событие 81. Изменение состояния невидимки друга](#событие-81-изменение-состояния-невидимки-друга)\n   - [Событие 90. Добавление или удаление из друзей](#событие-90-добавление-или-удаление-из-друзей)\n   - [Событие 91. Запрет писать в беседу одному участнику](#событие-91-запрет-писать-в-беседу-одному-участнику)\n   - [Событие 114. Изменение настроек пуш-уведомлений в беседе](#событие-114-изменение-настроек-пуш-уведомлений-в-беседе)\n   - [Событие 115. Звонок](#событие-115-звонок)\n   - [Событие 119. Ответ callback-кнопки](#событие-119-ответ-callback-кнопки)\n   - [Событие 501. Создание папки](#событие-501-создание-папки)\n   - [Событие 502. Удаление папки](#событие-502-удаление-папки)\n   - [Событие 503. Переименование папки](#событие-503-переименование-папки)\n   - [Событие 504. Добавление бесед в папку](#событие-504-добавление-бесед-в-папку)\n   - [Событие 505. Удаление бесед из папки](#событие-505-удаление-бесед-из-папки)\n   - [Событие 506. Изменение порядка папок](#событие-506-изменение-порядка-папок)\n   - [Событие 507. Изменение количества непрочитанных диалогов в папках](#событие-507-изменение-количества-непрочитанных-диалогов-в-папках)\n   - [Событие 601. Обновление реакций в сообщении](#событие-601-обновление-реакций-в-сообщении)\n   - [Событие 602. Обновление непрочитанных реакций в беседе](#событие-602-обновление-непрочитанных-реакций-в-беседе)\n5. [Дополнительная информация](#дополнительная-информация)\n   - [Флаги сообщений](#флаги-сообщений)\n   - [Флаги бесед](#флаги-бесед)\n   - [Сервисные сообщения](#сервисные-сообщения)\n   - [Клавиатура для ботов](#клавиатура-для-ботов)\n   - [Вложения](#вложения)\n   - [Права доступа в беседах](#права-доступа-в-беседах)\n   - [Зачем нужен random_id](#зачем-нужен-random_id)\n\n## Отказ от ответственности\n\nАвтор не несет ответственности за точность, полноту или качество предоставленной информации. Используйте последующую информацию на свой страх и риск.\n\n[Правила пользования сайтом](https://vk.com/terms), пункт 6.7:\n\n\u003e 6.7. Создаваемые Пользователями приложения API должны использовать **только опубликованные на Сайте методы API**, а также ID, защищенный ключ и сервисный ключ доступа, указанные в настройках данных приложений. Использование других методов API, а также ID, защищенного ключа и сервисного ключа доступа приложений API третьих лиц, в т.ч. приложения API Администрации Сайта, строго запрещено. Пользователь обязуется регулярно проверять перечень разрешённых методов и незамедлительно вносить корректировки в функциональность своих приложений API в соответствии с изменениями перечня. **За нарушение настоящего пункта Пользователь несет предусмотренную применимым законодательством, настоящими Правилами и иными документами Администрации Сайта ответственность**. Администрация Сайта при этом оставляет за собой право на защиту собственных прав и законных интересов.\n\n## Подключение\n\nСсылка для запроса составляется следующим образом:\n\n\u003e https://**`server`**?act=a_check\u0026key=**`key`**\u0026ts=**`ts`**\u0026wait=**`wait`**\u0026mode=**`mode`**\u0026version=**`version`**\n\n`server`, `key` и `ts` получаются методом [`messages.getLongPollServer`](https://dev.vk.com/method/messages.getLongPollServer)\n\n* `server` - Домен лонгполла. Индивидуален для каждого пользователя. Может отличаться у некоторых приложений, от имени которых получался токен\n* `key` - Ключ для идентификации активной сессии. Протухает через час и привязан к айпи адресу\n* `ts` - Номер последнего события. Лонгполл будет возвращать события, следующие за ним\n* `version` - Версия лонгполла\n* `wait` - Время ожидания нового события в секундах, максимум `90`. Рекомендуемое значение: `20`\n* `mode` - Настройка формата ответа. Рекомендуемое значение:  \n`(1 \u003c\u003c 1) | (1 \u003c\u003c 3) | (1 \u003c\u003c 5) | (1 \u003c\u003c 7) | (1 \u003c\u003c 9) | (1 \u003c\u003c 10)`\n\n| Бит       | Описание                                                                                              |\n|-----------|-------------------------------------------------------------------------------------------------------|\n| `1 \u003c\u003c 1`  | Возвращать кладжи (секции `additional` и `attachments` в [структуре сообщения](#структура-сообщения)) |\n| `1 \u003c\u003c 3`  | Возвращать расширенную информацию в [114], [115] и [119] событиях                                     |\n| `1 \u003c\u003c 5`  | Возвращать `pts`                                                                                      |\n| `1 \u003c\u003c 6`  | **[неактуально]** Возвращать события изменения онлайна друзей: [8] и [9]                              |\n| `1 \u003c\u003c 7`  | Возвращать [`random_id`](#зачем-нужен-random_id)                                                      |\n| `1 \u003c\u003c 9`  | Возвращать события о бизнес-уведомлениях                                                              |\n| `1 \u003c\u003c 10` | Возвращать тип `online` для `marked_users` при упоминании через `@online`                             |\n\nПосле выполнения запроса сервер вернет ответ следующего вида:\n```ts\ntype LongPollResult =\n  // pts приходит, если в mode выставлен бит (1 \u003c\u003c 5)\n  // updates - массив событий, которые описаны в разделе \"Описание событий\"\n  | { ts: number, pts: number, updates: unknown[] }\n  // ts слишком маленький (отстал более чем на 256 событий) или слишком большой (больше последнего существующего).\n  // Необходимо воспользоваться переданным ts (возвращается номер последнего события).\n  // Как получить пропущенные события можно узнать в разделе \"Получение истории событий\" чуть ниже\n  | { failed: 1, ts: number }\n  // Ключ инвалидировался. Необходимо получить новый key, используя метод messages.getLongPollServer\n  | { failed: 2, error: string }\n  // Указана неверная версия лонгполла\n  | { failed: 4, min_version: 0, max_version: 21 }\n```\n\nПосле обработки ответа нужно повторить запрос, но с новым значением `ts`.\n\n## Получение истории событий\n\nЕсли лонгполл вернул `failed: 1`, у вас все еще есть возможность получить пропущенные события.\n\n1) Включите получение `pts` при [подключении](#подключение) к лонгполлу, добавив флаг `1 \u003c\u003c 5` в `mode`\n2) Всегда сохраняйте возвращаемый лонгполлом `pts`\n3) С использованием `pts` и некоторых других параметров, описанных в документации, вызовите метод\n   [`messages.getLongPollHistory`](https://dev.vk.com/method/messages.getLongPollHistory).\n\nФормат ответа метода описан здесь:\nhttps://github.com/VKCOM/api-schema-typescript/blob/master/src/methods/messages.ts#L773\n\nПоле `history` похоже на поле `updates` из лонгполла, но в нем будут находиться только персистентные события.  \nТак же события из этого списка придут в урезанном виде:\n- `10003` - [Сброс флагов сообщения](#событие-10003-сброс-флагов-сообщения)\n- `10004` - [Новое сообщение](#событие-10004-новое-сообщение)\n- `10005` - [Редактирование сообщения](#событие-10005-редактирование-сообщения)\n- `10018` - [Обновление сообщения](#событие-10018-обновление-сообщения)\n\nСтруктура этих событий выглядит так:\n```ts\ntype LongPollHistoryMessageEvent = [\n  type: 10003 | 10004 | 10005 | 10018,\n  conversationMessageId: number,\n  flags: number,\n  peerId: number\n];\n```\n\nВ событиях [10006](#событие-10006-прочтение-входящих-сообщений) и [10007](#событие-10007-прочтение-исходящих-сообщений) поле `count` будет отсутствовать. \n\nВсю информацию о сообщениях и беседах можно взять из полей `messages` и `conversations`, где содержатся данные из API.\n\nЕсли в ответе придет поле `more`, то после обработки всех событий нужно будет повторить запрос, указав в поле `pts` пришедший `new_pts`.\n\n## Структура сообщения\n\nПодробнее про некоторые части структуры можно почитать здесь:\n\n- [Флаги сообщений](#флаги-сообщений)\n- [Шаблоны](https://dev.vk.com/api/bots/development/messages#Шаблоны%20сообщений)\n- [Клавиатура для ботов](#клавиатура-для-ботов)\n- [Сервисные сообщения](#сервисные-сообщения)\n- [Вложения](#вложения)\n- [random_id](#зачем-нужен-random_id)\n\n```ts\ntype LongPollMessage = [\n  type: 10003 | 10004 | 10005 | 10018,\n  // id сообщения относительно беседы\n  conversationMessageId: number,\n  flags: number,\n  // Этот элемент приходит только для события 10004\n  minorId?: number,\n  peerId: number,\n  timestamp: number,\n  // Переносы строк обозначаются как \u003cbr\u003e, а символы \" \u0026 \u003c \u003e экранируются\n  text: string,\n\n  // Объект приходит только при указании флага 2 при подключении к LongPoll\n  additional: {\n    // Устаревшее поле, не следует использовать\n    title?: string\n    // Наличие emoji в сообщении\n    emoji?: '1'\n    // id автора сообщения. Приходит только в беседах\n    from?: string\n    // Наличие шаблона (для получения шаблона нужно получить сообщение из API)\n    has_template?: '1'\n    marked_users?: Array\u003c\n      // Список из упомянутых людей/сообществ в сообщении. Ответ на другое сообщение так же считается как упоминание\n      | [1, number[]]\n      // @online\n      | [1, 'online', number[]]\n      // @all\n      | [1, 'all']\n      // Исчезающее сообщение в обычном чате\n      | [2, 'all']\n    \u003e\n    // Клавиатура для ботов (для беседы или сообщения)\n    keyboard?: MessageKeyboard\n    // Количество секунд до исчезновения сообщения в обычном чате\n    expire_ttl?: string\n    // Количество секунд до исчезновения сообщения в фантомном чате\n    ttl?: number\n    // Сообщение исчезло, приходит в 10018 событии\n    is_expired?: '1'\n    // Сообщение было переведено, приходит в 10018 событии \n    is_translated?: '1'\n    // Приходит, если при отправке сообщения указать параметр payload.\n    // Возвращает всегда JSON, который может содержать любую информацию.\n    // Там может содержаться отладочная информация, которая может пригодиться разработчику.\n    payload?: string\n\n    // Так же здесь могут быть поля, описывающие сервисное сообщение\n    // см. ссылку выше\n  },\n\n  // Объект приходит только при указании флага 2 при подключении к LongPoll\n  attachments: {\n    // Есть пересланное сообщение или ответ на сообщение\n    fwd?: '0_0'\n    // Ответ на сообщение: '{\"conversation_message_id\":number}'\n    // Приходит только в 10004 и 10018 событиях\n    reply?: string\n\n    // Количество вложений в поле attachments\n    // Число в строке\n    attachments_count?: string\n    // JSON с массивом вложений\n    // Приходит только для некоторых типов вложений\n    attachments?: string\n\n    // Описание вложений вида { attach1_type, attach1, ... }\n    // Все значения здесь имеют тип строки (и могут быть объектом в строке по типу '{\"id\":1}')\n    // см. ссылку выше\n  },\n\n  // Возвращается, если в mode есть флаг 128\n  randomId: number,\n  messageId: number,\n  // 0 (не редактировалось) или timestamp (время редактирования в секундах)\n  updateTimestamp: number\n];\n```\n\n### Короткий кортеж сообщения\n\nСуществует возможность возвращения укороченного кортежа с сообщением.\nТакое может произойти, если сообщение на момент ответа лонгполла уже было удалено для всех.\n\nЕсли вы отправили сообщение с определенным `random_id` и ждете ответа от лонгполла с этим же\n`random_id`, то с этим событием определенно возникнут проблемы, потому что в нем отсутствует\n`random_id`. Чтобы получить `random_id`, нужно запросить сообщение через апи:\nв случае `10004` события по `minorId` (в данном случае это синоним `message_id`),\nили в случае остальных событий по `conversationMessageId` и `peerId`.\nДалее, если сообщение было не нашим, апи вернет ошибку и мы ее проигнорируем, а если сообщение\nбыло нашим - вернет сообщение с полем `deleted: 1` и искомым `random_id`.\n\n```ts\ntype LongPollMessageShort = [\n  type: 10004,\n  conversationMessageId: number,\n  flags: number,\n  minorId: number\n];\n\ntype LongPollMessageShort = [\n  type: 10003 | 10005 | 10018,\n  conversationMessageId: number,\n  flags: number,\n  peerId: number\n];\n```\n\n## Описание событий\n\n### Событие 10002. Установка флагов сообщения\n\nВозможные значения [флагов сообщения](#флаги-сообщений):\n1. Пометка важным (`8 important`)\n2. Пометка как спам (`64 spam`)\n3. Удаление сообщения (`128 deleted`)\n4. Удаление для всех (`128 deleted` и `131072 deleted_all`)\n5. Прослушивание голосового сообщения (`4096 audio_listened`)\n\nСобытие приходит как при прослушивании собеседником вашего голосового сообщения,\nтак и при прослушивании вами голосового сообщения собеседника.\n\nВручную прослушать голосовое сообщение собеседника можно с помощью метода `messages.markAsListened`\nс параметром `message_id` или `cmid`. Метод вернет `1` при первом прослушивании голосового сообщения,\nа `0` при последующих или при попытке прослушать свое сообщение.\n\n```ts\ntype Event10002 = [\n  type: 10002,\n  conversationMessageId: number,\n  flags: number,\n  peerId: number\n];\n```\n\n### Событие 10003. Сброс флагов сообщения\n\nВозможные значения [флагов сообщения](#флаги-сообщений):\n1. Прочитано сообщение (`1 unread`). Устаревший флаг, не следует использовать\n2. Отмена пометки важным (`8 important`)\n3. Отмена пометки сообщения как спам (`64 spam` + `32768 cancel_spam`)\n4. Восстановление удаленного сообщения (`128 deleted`)\n\nВ 3 и 4 случаях возвращается [сообщение](#структура-сообщения).\n\n```ts\ntype Event10003 = [\n  type: 10003,\n  conversationMessageId: number,\n  flags: number,\n  peerId: number\n] | LongPollMessage;\n```\n\n### Событие 10004. Новое сообщение\n\nДанное событие возвращает новое [сообщение](#структура-сообщения).\n\n```ts\ntype Event10004 = LongPollMessage;\n```\n\n### Событие 10005. Редактирование сообщения\n\nДанное событие возвращает отредактированное [сообщение](#структура-сообщения).\n\n```ts\ntype Event10005 = LongPollMessage;\n```\n\n### Событие 10006. Прочтение входящих сообщений\n\nВы прочитали в диалоге `peerId` сообщения до `conversationMessageId` включительно.  \n`count` - количество непрочитанных сообщений в диалоге.\n\n```ts\ntype Event10006 = [\n  type: 10006,\n  peerId: number,\n  conversationMessageId: number,\n  count: number\n];\n```\n\n### Событие 10007. Прочтение исходящих сообщений\n\nСобеседник прочитал в диалоге `peerId` сообщения до `conversationMessageId` включительно.  \n`count` - количество __ваших__ непрочитанных сообщений в диалоге.\n\n```ts\ntype Event10007 = [\n  type: 10007,\n  peerId: number,\n  conversationMessageId: number,\n  count: number\n];\n```\n\n### Событие 8. Друг появился в сети\n[8]: #событие-8-друг-появился-в-сети\n\n__Это событие больше не приходит в LongPoll__\n\nСобытие не приходит, если у друга включена невидимка хотя бы для одного пользователя.\n\n```ts\ntype Event8 = [\n  type: 8,\n  // отрицательный id друга\n  userId: number,\n  // 1 - m.vk.com или неизвестное мобильное приложение\n  // 2 - iPhone\n  // 3 - iPad\n  // 4 - Android\n  // 5 - Windows Phone\n  // 6 - Windows 8\n  // 7 - vk.com или неизвестное десктопное приложение\n  platform: 1 | 2 | 3 | 4 | 5 | 6 | 7,\n  // время онлайна в секундах\n  timestamp: number,\n  // id приложения, с которого онлайн друг\n  // 0 если онлайн был вызван не приложением (например веб)\n  appId: 0 | number,\n  // 1 если онлайн с мобильного, 0 если нет\n  isMobile: 0 | 1,\n  // Всегда приходит 0\n  hasInvisibleMode: 0 | 1\n];\n```\n\n### Событие 9. Друг вышел из сети\n[9]: #событие-9-друг-вышел-из-сети\n\n__Это событие больше не приходит в LongPoll__\n\nСобытие не приходит, если у друга включена невидимка хотя бы для одного пользователя.\n\n```ts\ntype Event9 = [\n  type: 9,\n  // отрицательный id друга\n  userId: number,\n  // 1 если бездействовал 5 минут, 0 если покинул сайт\n  isTimeout: 0 | 1,\n  // время наступления офлайна в секундах\n  timestamp: number,\n  // id приложения, с которого был онлайн друг\n  // 0 если онлайн был вызван не приложением (например веб)\n  appId: 0 | number,\n  // 1 если онлайн с мобильного, 0 если нет\n  isMobile: 0 | 1,\n  // Всегда приходит 0\n  hasInvisibleMode: 0 | 1\n];\n```\n\n### Событие 10. Сброс флагов беседы\n\nФлаги бесед описаны [здесь](#флаги-бесед).\n\n```ts\ntype Event10 = [\n  type: 10,\n  peerId: number,\n  flags: number\n];\n```\n\n### Событие 12. Установка флагов беседы\n\nФлаги бесед описаны [здесь](#флаги-бесед).\n\n```ts\ntype Event12 = [\n  type: 12,\n  peerId: number,\n  flags: number\n];\n```\n\n### Событие 10013. Удаление всех сообщений в диалоге\n\nВ беседе `peerId` были удалены все сообщения до `conversationMessageId` включительно.\n\n```ts\ntype Event10013 = [\n  type: 10013,\n  peerId: number,\n  conversationMessageId: number\n];\n```\n\n### Событие 10018. Обновление сообщения\n[10018]: #событие-10018-обновление-сообщения\n\nПриходит при следующих событиях:\n1. Добавился сниппет (ссылка) — к вложениям добавляется `link`.\n2. Сообщение исчезло — удаляется текст и все вложения, добавляется ключ `is_expired: true`.\n3. Пришел перевод голосового сообщения.\n4. Пришёл перевод текста на другой язык (при первом запросе) — подробнее в [событии 50](#событие-50-перевод-сообщения).\n\nДанное событие возвращает [сообщение](#структура-сообщения).\n\n```ts\ntype Event10018 = LongPollMessage;\n```\n\n### Событие 10019. Сброс кеша сообщения\n\nПо какой-либо причине изменилось сообщение (без явного редактирования).\nНеобходимо переполучить сообщение через API.\n\n```ts\ntype Event10019 = [\n  type: 10019,\n  conversationMessageId: number,\n  peerId: number\n];\n```\n\n### Событие 20. Закрепление и открепление беседы (изменился majorId)\n\n`majorId` и `minorId` - это дополнительные айдишники для беседы, которые используются для ее сортировки\nв списке всех бесед.\n\nСначала список сортируется по `majorId`, а если есть беседы с одинаковыми `majorId`, то они сортируются\nпо `minorId`\n\n`majorId` принимает следующие значения: `0`, `16`, `32`, `48`, `64`, `80`.\nЧем больше значение, тем выше беседа в списке закрепленных.\n`0` означает незакрепленную беседу.\n\nПри закреплении беседы ей присваивается наибольшее доступное значение `majorId`,\nто есть она закрепляется в самый верх списка.\n\nЕсли закрепленная беседа всего одна, то ей присваивается `majorId = 16`,\nесли две — верхней присваивается `32` и так далее.\n\n```ts\ntype Event20 = [\n  type: 20,\n  peerId: number,\n  majorId: number,\n  0\n];\n```\n\n### Событие 21. Изменился minorId\n\nДля `10` версии LongPoll событие приходит только в методе\n[`messages.getLongPollHistory`](https://dev.vk.com/method/messages.getLongPollHistory)\n\nВ версиях LongPoll выше `10` событие приходит еще в некоторых сценариях, но это будет подробно расписано только\nпри обновлении документации на новую версию LongPoll\n\n`minorId` означает `id` последнего сообщения в беседе, но с одним отличием. В фантомном чате последнее сообщение\nможет исчезнуть, и чтобы диалог после этого полностью не пропал из списка, `minorId` сохраняет в себе `id`\nпоследнего даже исчезнувшего сообщения.\n\n```ts\ntype Event21 = [\n  type: 21,\n  peerId: number,\n  minorId: number\n];\n```\n\n### Событие 50. Перевод сообщения\n\nЭто событие приходит, если пользователь запросил перевод сообщения.\n\nЕсли для определённого сообщения перевод запрашивается в первый раз, то вместе с данным событием приходит и [событие 10018](#событие-10018-обновление-сообщения), где в объекте `additional` будет поле `is_translated`.\n\n```ts\ntype Event50 = [\n  type: 50,\n  data: {\n    peer_id: number,\n    cmid: number,\n    translation: string,\n    language: string\n  }\n];\n```\n\nПоле `language` представляет собой языковую пару, который выглядит так: `ru-en`.\nПеред дефисом прописан исходный язык переводимого текста, после дефиса — язык, на который переведён текст.\n\nСписок поддерживаемых языковых пар можно получить, выполнив метод `account.getInfo`. В ответе будет поле `messages_translation_language_pairs`.\n\nЧтобы запросить перевод сообщения, выполните метод `messages.translate` (доступен только официальным клиентам).\n\nПараметры метода `messages.translate`:\n```ts\ninterface MessagesTranslateParams {\n  peer_id: number,\n  cmids: string,\n  language: string\n}\n```\n\n### Событие 51. Изменение данных чата\n\nСобытие означает, что в беседе `chatId` изменились какие-то данные.\nБолее подробно все расписано в [52 событии](#событие-52-изменение-данных-чата),\nкоторое приходит одновременно с этим событии.\n\n```ts\ntype Event51 = [\n  type: 51,\n  chatId: number\n];\n```\n\n### Событие 52. Изменение данных чата\n\n| Тип |                            Описание                            |  Дополнительная информация  |\n| :-: |:--------------------------------------------------------------:|:---------------------------:|\n| 0   |               Из беседы был создан фантомный чат               |             `0`             |\n| 1   |                   Изменилось название беседы                   |             `0`             |\n| 2   |                   Обновилась аватарка беседы                   |             `0`             |\n| 3   |                  Назначен новый администратор                  |     `id` администратора     |\n| 4   |  Изменение [прав доступа](#права-доступа-в-беседах) в беседе   |  `mask` с правами доступа   |\n| 5   |             Закрепление или открепление сообщения              | `conversationMsgId` или `0` |\n| 6   |                      Вступление в беседу                       |      `id` вступившего       |\n| 7   |                        Выход из беседы                         |       `id` вышедшего        |\n| 8   |                      Исключение из беседы                      |      `id` исключенного      |\n| 9   |                    Разжалован администратор                    |     `id` бывшего админа     |\n| 10  |                        Изменился баннер                        |             `0`             |\n| 11  |                Появление или скрытие клавиатуры                |          `peerId`           |\n| 12  | Отозвано / подтверждено / отклонено / пришло приглашение в чат |    `0` / `1` / `2` / `3`    |\n| 13  |  Контакт был сконвертирован в юзера (`contactId` -\u003e `userId`)  |         `contactId`         |\n| 14  |         Произошло любое действие с бизнес-уведомлением         |             `0`             |\n| 15  |        Вы отозвали приглашение контакта или юзера в чат        |  `contactId` или `userId`   |\n| 16  |          Контакт или юзер отклонил приглашение в чат           |  `contactId` или `userId`   |\n| 17  |           Контакт или юзер принял приглашение в чат            |  `contactId` или `userId`   |\n| 18  |               Контакт или юзера пригласили в чат               |  `contactId` или `userId`   |\n| 19  |             Начало или окончание группового звонка             |  `1` в начале, `0` в конце  |\n| 22  |   Чат больше не новый: пришло первое сообщение (только в лс)   |             `0`             |\n| 23  |                    Изменено оформление чата                    |             `0`             |\n| 24  |                    Изменилось описание чата                    |             `0`             |\n| 25  |   Изменилось состояние `chat_settings.short_poll_reactions`    |          `0` / `1`          |\n| 26  |                Добавление инкогнито юзера в чат                |        `incognitoId`        |\n| 27  |          Конвертация инкогнито юзера в обычного юзера          |        `incognitoId`        |\n| 28  |                Удаление инкогнито юзера из чата                |        `incognitoId`        |\n\nПри изменении названия (`1`) и обновлении аватарки беседы (`2`) нужные данные можно взять из\n[сервисного сообщения](#сервисные-сообщения) в [4 событии](#событие-4-новое-сообщение).\n\n```ts\ntype Event52 = [\n  type: 52,\n  updateType: number,\n  peerId: number,\n  extra: number\n];\n```\n\n### Событие 63. Статус набора сообщения\n\nОзначает, что в беседе `peerId` начали писать текст `totalCount` людей. Их `id` записаны в `userIds`.\nВ массиве `userIds` может появиться и ваш `id`, так что нужно фильтровать этот список.\n\n```ts\ntype Event63 = [\n  type: 63,\n  peerId: number,\n  userIds: number[],\n  totalCount: number,\n  timestamp: number\n];\n```\n\n### Событие 64. Статус записи голосового сообщения\n\nВызывается при записи голосового сообщения.  \nИдентичен [событию 63](#событие-63-статус-набора-сообщения).\n\n### Событие 65. Статус загрузки фотографии\n\nВызывается при загрузке фотографии.  \nИдентичен [событию 63](#событие-63-статус-набора-сообщения).\n\n### Событие 66. Статус загрузки видеозаписи\n\nВызывается при загрузке видеозаписи.  \nИдентичен [событию 63](#событие-63-статус-набора-сообщения).\n\n### Событие 67. Статус загрузки файла\n\nВызывается при загрузке файла.  \nИдентичен [событию 63](#событие-63-статус-набора-сообщения).\n\n### Событие 68. Статус записи видеосообщения\n\nВызывается при записи видеосообщения (кружочка).  \nИдентичен [событию 63](#событие-63-статус-набора-сообщения).\n\n### Событие 80. Изменение количества непрочитанных диалогов\n\nВсе счетчики возвращаются без учета сообщений в архиве\n\n```ts\ntype Event80 = [\n  type: 80,\n  // Количество непрочитанных бесед\n  unreadCount: number,\n  // Количество непрочитанных незамьюченных бесед\n  unreadUnmutedCount: number,\n  // 0 - показывать количество всех бесед, 1 - только незамьюченные\n  showOnlyUnmuted: 0 | 1,\n  // Количество непрочитанных бизнес-уведомлений\n  businessNotifyUnreadCount: number,\n  // Количество непрочитанных бесед в мессенджере в шапке\n  // Эти два счетчика можно сбросить, просто открыв мессенджер в шапке на вебе\n  headerUnreadCount: number,\n  // Количество непрочитанных незамьюченных бесед в мессенджере в шапке\n  headerUnreadUnmutedCount: number,\n  // Количество непрочитанных бесед в архиве\n  archiveUnreadCount: number,\n  // Количество непрочитанных незамьюченных бесед в архиве\n  archiveUnreadUnmutedCount: number,\n  // Количество бесед с упоминаниями в архиве\n  archiveMentionsCount: number\n];\n```\n\n### Событие 81. Изменение состояния невидимки друга\n\nЕсли невидимка будет выключена не для всех, то метод так же вернет `state: 1`,\nхотя для нас онлайн может быть так же виден\n\n```ts\ntype Event81 = [\n  type: 81,\n  // Отрицательный id друга\n  userId: number,\n  // 0 - невидимка выключена, 1 - включена\n  state: 0 | 1,\n  // время последнего онлайна друга\n  timestamp: number,\n  -1,\n  // При настройке невидимки через VK Me приходит 0, в других случаях не проверял\n  appId: 0 | number\n];\n```\n\n### Событие 90. Добавление или удаление из друзей\n\nСобытие возвращается только для действий с вашей стороны.\n\nЗначения `actionType`:\n  * `2` - вы приняли заявку пользователя\n  * `3` - вы удалили из друзей или отклонили заявку в друзья пользователя\n\n```ts\ntype Event90 = [\n  type: 90,\n  actionType: 2 | 3,\n  userId: number\n];\n```\n\n### Событие 91. Запрет писать в беседу одному участнику\n\nЗначения `actionType`:\n  * `1` - участнику `memberId` запрещено писать в беседу `peerId` на `seconds` секунд — до `untilTime`\n  * `2` - участнику `memberId` запрещено писать в беседу `peerId` навсегда\n  * `3` - участнику `memberId` разрешено писать в беседу `peerId`\n\nПоля `seconds` и `untilTime` возвращаются только при `actionType = 1`\n\n```ts\ntype Event91 = [\n  type: 91,\n  actionType: 1 | 2 | 3,\n  peerId: number,\n  memberId: number,\n  seconds: number,\n  untilTime: number\n];\n```\n\n### Событие 114. Изменение настроек пуш-уведомлений в беседе\n[114]: #событие-114-изменение-настроек-пуш-уведомлений-в-беседе\n\nДля работы необходимо использовать в `mode` флаг `8` при [выполнении запроса](#подключение).\n\n- `peer_id` - `id` беседы, в которой включили или выключили уведомления\n- `sound` - нестабильный параметр, не рекомендую его обрабатывать\n- `disabled_until` может быть трех видов:\n   - `0` - Уведомления включены\n   - `-1` - Уведомления выключены\n   - `number, \u003e 0`, - Уведомления выключены до указанного `timestamp`\n\n```ts\ntype Event114 = [\n  type: 114,\n  data: {\n    peer_id: number\n    sound: 0 | 1\n    disabled_until: 0 | -1 | number\n  }\n];\n```\n\n### Событие 115. Звонок\n[115]: #событие-115-звонок\n\nДля работы необходимо использовать в `mode` флаг `8` при [выполнении запроса](#подключение).\n\n¯\\\\\\_(ツ)\\_/¯\n\n### Событие 119. Ответ callback-кнопки\n[119]: #событие-119-ответ-callback-кнопки\n\nДля работы необходимо использовать в `mode` флаг `8` при [выполнении запроса](#подключение).\n\n[Callback-кнопки](https://dev.vk.com/api/bots/development/keyboard#Callback-кнопки) работают следующим образом:\n\n1. Бот отправляет клавиатуру (обычную или инлайн), где находится callback-кнопка;\n2. Пользователь нажимает на эту кнопку и клиент вызывает метод `messages.sendMessageEvent` (параметры см. ниже).\nМетод возвращает строку - `event_id`;\n3. Бот получает событие `message_event` и вызывает метод [`messages.sendMessageEventAnswer`](https://dev.vk.com/method/messages.sendMessageEventAnswer);\n4. Этот метод вызывает `119` событие LongPoll у пользователя, где в `action` прописано действие, которое необходимо выполнить клиенту.\n\nПараметры метода `messages.sendMessageEvent`:\n```ts\ninterface MessagesSendMessageEventParams {\n  peer_id: number\n  // Находится в кнопке клавиатуры\n  payload: string\n\n  // Нужно передать один из двух параметров,\n  // если это инлайн клавиатура в сообщении или карусели\n  message_id?: number\n  conversation_message_id?: number\n\n  // Находится в объекте клавиатуры беседы\n  // Нужно передать, если это клавиатура беседы\n  author_id?: number\n}\n```\n\nПосле получения `event_id` на 2 стадии нужно начать ждать `119` событие LongPoll с нужным `event_id`.\nЕсли за минуту бот так и не пришлет событие, то ожидание ответа следует прекратить.\n\n```ts\ntype Event119 = [\n  type: 119,\n  data: {\n    // Отрицательный ID бота, который ответил на клик по кнопке\n    owner_id: number\n    // ID беседы, в которой находится сообщение\n    peer_id: number\n    // Уникальный ID события, действующий 1 минуту.\n    // Нужен для идентификации кликнутой кнопки\n    event_id: string\n    // Не приходит, если не нужно выполнять никакое действие\n    // т.е. бот отправил пустой payload или неизвестный тип действия\n    action?:\n      // Показать снекбар с текстом `text`\n      | { type: 'show_snackbar', text: string }\n      // Открыть ссылку `link`\n      | { type: 'open_link', link: string }\n      // Открыть приложение по ссылке\n      // https://vk.com/app${app_id}_${owner_id}#${hash}\n      // https://vk.com/app${app_id}_${owner_id} (если hash = '')\n      // https://vk.com/app${app_id} (если owner_id = undefined и hash = '')\n      | { type: 'open_app', app_id: number, owner_id?: number, hash: string }\n  }\n];\n```\n\n### Событие 501. Создание папки\n\n```ts\ntype Event501 = [\n  type: 501,\n  folderId: number,\n  folderName: string,\n  randomId: number\n];\n```\n\n### Событие 502. Удаление папки\n\n```ts\ntype Event502 = [\n  type: 502,\n  folderId: number\n];\n```\n\n### Событие 503. Переименование папки\n\n```ts\ntype Event503 = [\n  type: 503,\n  folderId: number,\n  newFolderName: string\n];\n```\n\n### Событие 504. Добавление бесед в папку\n\n```ts\ntype Event504 = [\n  type: 504,\n  folderId: number,\n  ...addedFolderIds: number[]\n];\n```\n\nНапример, если в папку с `id = 5` добавить три беседы: `88262293`, `172894294` и `2000000346`,\nто событие будет выглядеть вот так:\n```js\n[504, 5, 88262293, 172894294, 2000000346]\n```\n\n### Событие 505. Удаление бесед из папки\n\n```ts\ntype Event505 = [\n  type: 505,\n  folderId: number,\n  ...deletedFolderIds: number[]\n];\n```\n\nНапример, если из папки с `id = 5` удалить три беседы: `88262293`, `172894294` и `2000000346`,\nто событие будет выглядеть вот так:\n```js\n[505, 5, 88262293, 172894294, 2000000346]\n```\n\n### Событие 506. Изменение порядка папок\n\n```ts\ntype Event506 = [\n  type: 506,\n  ...folderIds: number[]\n];\n```\n\nНапример, если у нас есть три папки с `id` `1`, `2` и `4`, то нам может прийти такое событие:\n```js\n[506, 1, 4, 2]\n```\n\n### Событие 507. Изменение количества непрочитанных диалогов в папках\n\n```ts\ntype Event507 = [\n  type: 507,\n  ...foldersCounters: FolderCountersTuple[]\n];\n\ntype FolderCountersTuple = [\n  folderId: number,\n  unreadCount: number,\n  unreadUnmutedCount: number\n];\n```\n\nСобытие возвращает данные только для тех папок, в которых изменились каунтеры.\n\nНапример, если в папке с `id = 2` стало 3 непрочитанных замьюченных чата,\nа в папке с `id = 3` стало 2 непрочитанных чата: один замьючен, а другой нет,\nто событие будет выглядеть так:\n```js\n[507, [2, 3, 0], [3, 2, 1]]\n```\n\n### Событие 601. Обновление реакций в сообщении\n\nЗначения `actionType`:\n  * `1` - текущий пользователь поставил реакцию\n  * `2` - другой участник поставил реакцию\n  * `3` - текущий пользователь удалил реакцию\n  * `4` - другой участник удалил реакцию\n\nПри `actionType = 1`, 4-ый (с нуля) элемент массива содержит `id` реакции, которую поставил пользователь, 5-ый — кол-во реакций, а с 6-го идут данные:\n\n```ts\ntype Event601 = [\n  type: 601,\n  actionType: 1,\n  peerId: number,\n  conversationMessageId: number,\n  myReactionId: number,\n  reactionsCount: number,\n  ...data: number[]\n];\n```\n\nВ остальных случаях 4-ый элемент массива это кол-во реакций, а с 5-го идут данные:\n\n```ts\ntype Event601 = [\n  type: 601,\n  actionType: 2 | 3 | 4,\n  peerId: number,\n  conversationMessageId: number,\n  reactionsCount: number,\n  ...data: number[]\n];\n```\n\n#### Подробнее о поле data\n\nЭто поле содержит в себе несколько блоков, количество которых задается `reactionsCount`:\n```ts\ntype Event601DataBlock = [\n  // Количество полей в блоке, не считая это поле\n  length: number,\n  reactionId: number,\n  // Общее количество пользователей, поставивших эту реакцию\n  count: number,\n  // Количество пользователей, поставивших реакцию, которые будут перечислены ниже.\n  // Может не совпадать с count выше или быть 0, в таком случае далее айдишников ниже не будет\n  usersCount: number,\n  ...userIds: number[]\n];\n```\n\nПример события с `actionType = 1`:\n\n`reactionsCount` выставлен как `4`, поэтому далее будет 4 блока.\n\nУ каждого блока сначала указывается количество полей далее, и далее идут сами поля блока. В каждом блоке указывается количество юзеров, и перечисляется указанное количество юзеров.\n\n```ts\n[\n  601, 1, 2000000153, 1841767, 2, 4,\n  5, 4, 2, 2, 443182555, 63518289,\n  4, 32, 1, 1, 138269465,\n  6, 2, 3, 3, 131819250, 172894294, 647599618,\n  4, 15, 1, 1, 355807901\n]\n```\n\n__Обратите внимание!__ Если реакций в сообщении много, то не будут приходить `id` юзеров, поставивших реакцию, и `usersCount` будет равен `0`:\n\n```ts\n[\n  601, 2, 2000000153, 1841767, 5,\n  3, 2, 3, 0,\n  3, 4, 2, 0,\n  3, 5, 1, 0,\n  3, 6, 1, 0,\n  3, 15, 1, 0,\n  0, 6\n]\n```\n\nПри `actionType = 2` в конце массива, после последней реакции, могут быть дополнительные элементы. В них содержатся `id` реакции и участника, который поставил эту реакцию и тем самым вызвал это событие. Выглядит это вот так:\n\n```ts\n[..., 1, 88262293, 30] // если id участников возвращаются\n[..., 0, 6]            // в ином случае (как в примере выше)\n```\n\nПервый элемент, _возможно_, кол-во `id`-ов участников, которые идут далее. \n* Если он равен `1`, то вторым элементом будет `id` участника, а третьим — `id` реакции;\n* Если он равен `0`, то вторым элементом будет `id` реакции.\n\n### Событие 602. Обновление непрочитанных реакций в беседе\n\nСобытие приходит, когда другой участник поставил реакцию на ваше сообщение, либо когда вы [«прочли»](https://dev.vk.com/ru/method/messages.markReactionsAsRead) реакции на ваше сообщение.\n\n```ts\ntype Event602 = [\n  type: 602,\n  peerId: number,\n  // Кол-во ваших сообщений с непрочитанными реакциями\n  messagesCount: number,\n  // cmid-ы этих сообщений\n  ...conversationMessageIds: number[]\n];\n```\n\n## Дополнительная информация\n\n### Флаги сообщений\n\nМаской называют сумму некоторых флагов (степеней двойки), которую можно использовать как хорошую замену для объектов или массивов.\n\n```js\n// Обычно маску записывают подобным образом:\nconst mask = 1 | 2 | 8 | 64 | 1024;\n// Что эквивалентно сложению чисел:\nconst mask = 1 + 2 + 8 + 64 + 1024;\n// А еще можно не писать магические цифры, а записывать степени двойки в таком формате:\nconst mask = (1 \u003c\u003c 0) | (1 \u003c\u003c 1) | (1 \u003c\u003c 3) | (1 \u003c\u003c 6) | (1 \u003c\u003c 10);\n```\n\n|    Бит    |  Значение  |                                        Описание                                        |\n|:---------:|:----------:|:--------------------------------------------------------------------------------------:|\n| `1 \u003c\u003c 0`  |    `1`     |                                Непрочитанное сообщение                                 |\n| `1 \u003c\u003c 1`  |    `2`     |                                  Исходящее сообщение                                   |\n| `1 \u003c\u003c 3`  |    `8`     |                                    Важное сообщение                                    |\n| `1 \u003c\u003c 4`  |    `16`    |                     **[deprecated]** Сообщение из группового чата                      |\n| `1 \u003c\u003c 5`  |    `32`    |                          **[deprecated]** Сообщение от друга                           |\n| `1 \u003c\u003c 6`  |    `64`    |                              Сообщение помечено как спам                               |\n| `1 \u003c\u003c 7`  |   `128`    |                               Сообщение удалено локально                               |\n| `1 \u003c\u003c 12` |   `4096`   |                             Прослушано голосовое сообщение                             |\n| `1 \u003c\u003c 13` |   `8192`   |                              Сообщение из группового чата                              |\n| `1 \u003c\u003c 15` |  `32768`   |                         🤔 Сообщение перемещено в список спама                         |\n| `1 \u003c\u003c 16` |  `65536`   |                Не обновлять `minor_id`, т.е. не поднимать чат в списке                 |\n| `1 \u003c\u003c 17` |  `131072`  |                               Сообщение удалено для всех                               |\n| `1 \u003c\u003c 18` |  `262144`  |                                     **[internal]**                                     |\n| `1 \u003c\u003c 19` |  `524288`  |                                     **[internal]**                                     |\n| `1 \u003c\u003c 20` | `1048576`  |                   Не показывать пуш/уведомление для этого сообщения                    |\n| `1 \u003c\u003c 21` | `2097152`  |                        Сообщение с ответом на другое сообщение                         |\n| `1 \u003c\u003c 22` | `4194304`  |                       Сообщение будет удалено при окончании TTL                        |\n| `1 \u003c\u003c 23` | `8388608`  | Сообщение придет автоматически прочитанным, если ранее не было непрочитанных сообщений |\n| `1 \u003c\u003c 24` | `16777216` |                              Наличие реакции у сообщения                               |\n| `1 \u003c\u003c 26` | `67108864` |                                     **[internal]**                                     |\n\nБесшумное сообщение можно отправить, добавив к параметрам метода [`messages.send`](https://dev.vk.com/method/messages.send) ключ `silent: true`:\n- Такое сообщение отправится без уведомления пользователю, даже если у него включены уведомления\n- Упоминание или ответ на сообщение тоже не отправит уведомления\n- Сообщение о выходе из беседы автоматически приходит без уведомления\n\nПример определения наличия флага в маске:\n```js\nconst mask = 1 | 2 | 32; // = 35\n\n8 \u0026 mask // вернет 0 (false)\n2 \u0026 mask // вернет 2 (true)\n```\n\n### Флаги бесед\n\n|    Бит    |  Значение  |                                  Описание                                  |\n|:---------:|:----------:|:--------------------------------------------------------------------------:|\n| `1 \u003c\u003c 4`  |    `16`    |                         Отключение пуш уведомлений                         |\n| `1 \u003c\u003c 5`  |    `32`    |                        Отключение звука уведомлений                        |\n| `1 \u003c\u003c 8`  |   `256`    |             Входящий запрос на переписку / вступление в беседу             |\n| `1 \u003c\u003c 9`  |   `512`    |           Отклоненный запрос на переписку / вступление в беседу            |\n| `1 \u003c\u003c 10` |   `1024`   |                             Наличие упоминания                             |\n| `1 \u003c\u003c 11` |   `2048`   |                      Не отображать беседу при поиске                       |\n| `1 \u003c\u003c 12` |   `4096`   |                               **[internal]**                               |\n| `1 \u003c\u003c 13` |   `8192`   |                       Беседа с бизнес-уведомлениями                        |\n| `1 \u003c\u003c 14` |  `16384`   |   Наличие маркированного сообщения: упоминание или исчезающее сообщение    |\n| `1 \u003c\u003c 16` |  `65536`   | Беседа, которая не пропадает из списка чатов (не сбрасывается `minor_id`)  |\n| `1 \u003c\u003c 18` |  `262144`  |               Не присылать уведомления об `@all` и `@online`               |\n| `1 \u003c\u003c 19` |  `524288`  |                Не присылать уведомления о всех упоминаниях                 |\n| `1 \u003c\u003c 20` | `1048576`  |                     Беседа помечена как непрочитанная                      |\n| `1 \u003c\u003c 22` | `4194304`  |                               **[internal]**                               |\n| `1 \u003c\u003c 23` | `8388608`  |                          Беседа помещена в архив                           |\n| `1 \u003c\u003c 24` | `16777216` |                       Беседа, в которой идет звонок                        |\n| `1 \u003c\u003c 26` | `67108864` | Признак того, что это чат: при создании старого канала снимается этот флаг |\n\n### Сервисные сообщения\n\nСервисное сообщение описывается ключом `source_act` и ключами с дополнительными данными в объекте `additional` из [структуры сообщения](#структура-сообщения).\n\nУ некоторых сервисных сообщений в поле `text` приходит сообщение вида `Сообщение не поддерживается Вашим приложением.`,\nпоэтому при обработке сервисных сообщений __не__ нужно обрабатывать текст сообщения.\n\nВместе с сервисными сообщениями `chat_title_update` и `chat_photo_remove` в каналах приходит поле\n`source_is_channel: \"1\"`. Сервисное сообщение `chat_photo_update` для каналов не приходит\n(только [52 событие](#событие-52-изменение-данных-чата)).\n\nВозможные значения `source_act`:\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003eТип\u003c/th\u003e\n    \u003cth\u003eДополнительные ключи\u003c/th\u003e\n  \u003c/tr\u003e\n\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003echat_create\u003c/code\u003e\u003cbr\u003eСоздание беседы\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ccode\u003esource_text\u003c/code\u003e - название беседы\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003echat_photo_update\u003c/code\u003e\u003cbr\u003eОбновление фотографии беседы\u003c/td\u003e\n    \u003ctd\u003eФото можно получить во вложении сообщения\u003c/td\u003e\n  \u003c/tr\u003e\n\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003echat_photo_remove\u003c/code\u003e\u003cbr\u003eУдаление фотографии беседы\u003c/td\u003e\n    \u003ctd\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003echat_title_update\u003c/code\u003e\u003cbr\u003eОбновление названия беседы\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ccode\u003esource_old_text\u003c/code\u003e - старое название беседы\u003cbr\u003e\n      \u003ccode\u003esource_text\u003c/code\u003e - новое название беседы\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003echat_pin_message\u003c/code\u003e\u003cbr\u003eЗакрепление сообщения\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ccode\u003esource_mid\u003c/code\u003e - \u003ccode\u003eid\u003c/code\u003e закрепившего сообщение\u003cbr\u003e\n      \u003ccode\u003esource_message\u003c/code\u003e - обрезанное закрепленное сообщение\u003cbr\u003e\n      \u003ccode\u003esource_chat_local_id\u003c/code\u003e - локальный \u003ccode\u003eid\u003c/code\u003e сообщения\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003echat_unpin_message\u003c/code\u003e\u003cbr\u003eОткрепление сообщения\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ccode\u003esource_mid\u003c/code\u003e - \u003ccode\u003eid\u003c/code\u003e открепившего сообщение\u003cbr\u003e\n      \u003ccode\u003esource_chat_local_id\u003c/code\u003e - локальный \u003ccode\u003eid\u003c/code\u003e сообщения\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003echat_invite_user\u003c/code\u003e\u003cbr\u003eВступление в беседу\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ccode\u003esource_mid\u003c/code\u003e - \u003ccode\u003eid\u003c/code\u003e вступившего в беседу\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003echat_invite_user_by_link\u003c/code\u003e\u003cbr\u003eВступление в беседу по ссылке\u003c/td\u003e\n    \u003ctd\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003echat_kick_user\u003c/code\u003e\u003cbr\u003eВыход или исключение из беседы\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ccode\u003esource_mid\u003c/code\u003e - \u003ccode\u003eid\u003c/code\u003e вышедшего или исключенного\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003echat_kick_don\u003c/code\u003e\u003cbr\u003eИсключение дона из беседы\u003c/td\u003e\n    \u003ctd\u003eПриходит, начиная с версии API \u003ccode\u003e5.154\u003c/code\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003echat_screenshot\u003c/code\u003e\u003cbr\u003eСоздание скриншота с фантомным сообщением\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ccode\u003esource_mid\u003c/code\u003e - \u003ccode\u003eid\u003c/code\u003e создавшего скриншот\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003echat_group_call_started\u003c/code\u003e\u003cbr\u003eНачало группового звонка в беседе\u003c/td\u003e\n    \u003ctd\u003e\n      \u003cb\u003eБольше не приходит в LongPoll\u003c/b\u003e\u003cbr\u003e\n      Вместо него создается сообщение с вложением \u003ccode\u003egroup_call_in_progress\u003c/code\u003e\u003cbr\u003e\n      Приходит для старых сообщений через API при получении через токен VK для Android\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003echat_invite_user_by_call\u003c/code\u003e\u003cbr\u003eПриглашение пользователя в звонок\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ccode\u003esource_mid\u003c/code\u003e - \u003ccode\u003eid\u003c/code\u003e приглашенного юзера\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003echat_invite_user_by_call_join_link\u003c/code\u003e\u003cbr\u003eПрисоединение пользователя к звонку по ссылке\u003c/td\u003e\n    \u003ctd\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003echat_invite_user_by_message_request\u003c/code\u003e\u003cbr\u003eЗапрос на добавление в беседу\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ccode\u003esource_mid\u003c/code\u003e - \u003ccode\u003eid\u003c/code\u003e пригласившего в беседу\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003econversation_style_update\u003c/code\u003e\u003cbr\u003eОбновление стиля беседы\u003c/td\u003e\n    \u003ctd\u003e\n      \u003ccode\u003esource_style\u003c/code\u003e - название стиля\u003cbr\u003e\n      Поле не приходит в случае сброса стиля\u003cbr\u003e\n      Возможные варианты можно посмотреть\n      \u003ca href=\"https://elorucov.github.io/laney/v2/chat_styles.json\"\u003eздесь\u003c/a\u003e, либо вызвав метод \u003ccode\u003emessages.enumerateAppearances\u003c/code\u003e (доступен только официальным приложениям)\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\nПример описания сервисного сообщения:\n```js\nconst longpollServiceMessage = {\n  source_act: 'chat_pin_message',\n  source_mid: '88262293',\n  source_message: 'Сообщение, которое будет в закрепе',\n  source_chat_local_id: '5517'\n}\n```\n\n### Клавиатура для ботов\n\nКлавиатура для ботов представляет собой объект с описанием ее типа и кнопок.\nОсновная структура представлена ниже, остальную информацию можно узнать в [документации](https://dev.vk.com/api/bots/development/keyboard).\n```ts\n// TODO: новые тайпинги\n// Типы у объекта клавиатуры:\n// https://github.com/danyadev/vk-types/blob/master/src/objects/VKKeyboard.ts\ninterface LongPollKeyboard {\n  // Приходит, если это клавиатура сообщения или карусели\n  inline?: true\n  // Скрывать ли клавиатуру при клике на кнопку (не работает для inline)\n  one_time: boolean\n  buttons?: VKKeyboardButton[][]\n}\n```\n\n### Вложения\n\n#### Список существующих вложений\n\nСписок известных на данный момент вложений:\n`geo`, `doc`, `link`, `poll`, `wall`, `call`, `gift`, `story`, `photo`, `audio`, `video`, `event`, `market`, `artist`, `widget`, `sticker`,\n`article`, `podcast`, `curator`, `graffiti`, `mini_app`, `narrative`, `wall_reply`, `audio_message`, `money_request`, `audio_playlist`,\n`group_call_in_progress`.\n\nОднако названия вложений, полученных через LongPoll, могут не совпадать с теми, что приходят через API:\n- `event`, приходящий в API, в LongPoll обозначается как `group`\n- `graffiti` и `audio_message` из LongPoll обозначаются как `doc`, но при этом добавляется ключ `attach*_kind` со значением `graffiti` или `audiomsg`\n- `artist`, `article`, `narrative` и `audio_playlist`, которые приходят в LongPoll, через API отображаются как `link`\n- `mini_app` не приходит в LongPoll, вместо него приходит `link`\n- `narrative` приходят в API начиная с версии `5.154`\n\nВложения `artist`, `article`, `mini_app` и `audio_playlist` приходят в API только через токен VK для Android.\n\nВложение `geo` (прикрепленное местоположение) приходит в виде ключей `geo` и `geo_provider` вместо `attach*`\n(см. [структуру](#структура-сообщения)). Также при получении сообщения через [`messages.getById`](https://dev.vk.com/method/messages.getById)\nключ `geo` будет находиться не во вложениях, а в \"корне\" сообщения.\n\nСообщение с вложением `group_call_in_progress` создается, когда пользователь начинает групповой звонок.\nПри окончании группового звонка сообщение с этим вложением удаляется и создается новое сообщение с вложением `call`.\n\n#### Работа с вложениями в LongPoll\n\nПример вложений, состоящих из фотографии, документа и аудиозаписи:\n```js\nconst longpollAttachments = {\n  attach1: '88262293_457290160',\n  attach1_type: 'photo',\n  attach2: '88262293_532324610',\n  attach2_type: 'doc',\n  attach3: '88262293_535133534',\n  attach3_kind: 'audiomsg',\n  attach3_type: 'doc'\n}\n```\n\nОбычно дополнительная информация о вложении не нужна, поэтому можно ограничиться получением названий вложений для предварительного отображения сообщения\nи анализа списка вложений, чтобы в случае необходимости получить сообщение через [API](https://dev.vk.com/method/messages.getById).\n\n\u003cdetails\u003e\n\u003csummary markdown=\"span\"\u003eПример кода для получения массива с названиями вложений\u003c/summary\u003e\n\n```js\nfunction getAttachments(data) {\n  const attachments = [];\n\n  if (data.geo) {\n    attachments.push('geo');\n  }\n\n  for (const key in data) {\n    const match = key.match(/attach(\\d+)$/);\n\n    if (match) {\n      const id = match[1];\n      const kind = data[`attach${id}_kind`];\n      let type = data[`attach${id}_type`];\n\n      if (kind === 'audiomsg') type = 'audio_message';\n      if (kind === 'graffiti') type = 'graffiti';\n      if (type === 'group') type = 'event';\n\n      attachments.push(type);\n    }\n  }\n\n  return attachments;\n}\n```\n\u003c/details\u003e\n\n#### Ответ на сообщение\n\nОпределить наличие ответа на сообщение можно с помощью проверки наличия `attachments.reply` ([структура](#структура-сообщения))\nили [флага](#флаги-сообщений) `reply_msg`.\n\nВ некоторых случаях получать сообщение через API для получения ответа на сообщение не нужно:\nесли сообщение, на которое пришло ответ, пришло недавно, то оно наверняка уже должно быть в локальном списке сообщений.\nНайти сообщение можно с помощью `conversation_message_id` из `attachments.reply`.\n\n#### Пересланные сообщения\n\nОпределить наличие пересланных сообщений можно с помощью проверки на отсутствие ответа на сообщение и на наличие `attachments.fwd`.\nID пересланных сообщений, как и их количество, пока что не приходит через LongPoll.\n\n#### Оптимизация получения вложений\n\nДля получения некоторых вложений необязательно получать сообщение через API - в объект `attachments` ([структура](#структура-сообщения))\nприходят поля `attachments_count` и `attachments`, где и содержатся объекты вложений из API.\nК примеру, в списке вложений можно найти стикер и голосовое сообщение.\n\nПри работе с вложениями можно попробовать найти необходимый элемент в [документации](https://dev.vk.com/reference/objects),\nоднако у некоторых вложений документация не обновлена или вовсе отсутствует.\n\n### Права доступа в беседах\n\nВ списке представлены все возможные параметры прав доступа с их флагом из 4 действия\n[52 события](#событие-52-изменение-данных-чата).\n\n* Кто может приглашать участников в беседу\n  * Только создатель: `2097152` (`1 \u003c\u003c 21`)\n  * Создатель и администраторы: `1` (`1 \u003c\u003c 0`)\n  * Все участники: `0`\n* Кто может редактировать информацию беседы\n  * Только создатель: `4194304` (`1 \u003c\u003c 22`)\n  * Создатель и администраторы: `8` (`1 \u003c\u003c 3`)\n  * Все участники: `0`\n* Кто может менять закреплённое сообщение\n  * Только создатель: `8388608` (`1 \u003c\u003c 23`)\n  * Создатель и администраторы: `4` (`1 \u003c\u003c 2`)\n  * Все участники: `0`\n* Кто может отправлять массовые упоминания\n  * Только создатель: `1048576` (`1 \u003c\u003c 20`)\n  * Создатель и администраторы: `524288` (`1 \u003c\u003c 19`)\n  * Все участники: `0`\n* Кто может видеть ссылку на беседу\n  * Только создатель: `0`\n  * Создатель и администраторы: `16777216` (`1 \u003c\u003c 24`)\n  * Все участники: `33554432` (`1 \u003c\u003c 25`)\n* Кто может начинать групповые звонки\n  * Только создатель: `134217728` (`1 \u003c\u003c 27`)\n  * Создатель и администраторы: `67108864` (`1 \u003c\u003c 26`)\n  * Все участники: `0`\n* Кто может назначать администраторов\n  * Только создатель: `0`\n  * Создатель и администраторы: `16` (`1 \u003c\u003c 4`)\n\nДополнительные флаги:\n* Имеется фантомная копия чата: `65536` (`1 \u003c\u003c 16`)\n* Является фантомным чатом: `32768` (`1 \u003c\u003c 15`)\n* Всем участникам, кроме администраторов, запрещено отправлять сообщения в беседу: `137438953472` (`1 \u003c\u003c 37`)\n* Автовоспроизведение анимации всплывающих стикеров в беседе _отключено_: `549755813888` (`1 \u003c\u003c 39`)\n\n__Обратите внимание!__ LongPoll не возвращает длительность запрета на отправку сообщений. После получения флага вам придётся запрашивать из API беседу и в нём узнать длительность запрета.\n\n### Зачем нужен random_id\n\n`random_id` начиная с версии API `5.90` стал обязательным параметром.\nНо это не означает, что всем нужно генерировать уникальные значения для этого параметра.\nЕсли вы не собираетесь его использовать, то можете указать в его значении число `0`.\n\nЗначение `random_id` должно быть уникальным в течение __одного часа__ в рамках `app_id`, `id` пользователя и `peer_id` диалога.\n\nЗначение `random_id` может принимать числа от `-2147483648` (`-(2^31)`) до `2147483647` (`2^31 - 1`).\nЕсли число будет больше или меньше данного порога, то из переданного числа отнимется этот лимит.\n\nОсновная задача этого параметра заключается в гарантировании идемпотентности API для отправки сообщений.\nЭто означает, что при отправке запросов с одинаковым `random_id` и, чаще всего, одинаковыми параметрами,\nсервер не будет создавать новое сообщение и вернет ID уже созданного.\nПро необходимость данной технологии с убедительными примерами рассказывается в [данной](https://habr.com/ru/company/yandex/blog/442762/) статье.\n\nНаверняка вы уже видели, что во всех мессенджерах ВКонтакте при отправке сообщения само сообщение отображается сразу,\nно около сообщения некоторое время видно иконку часов. Эта иконка означает, что запрос на сервер с новым сообщением отправлен,\nно сообщение еще не пришло обратно через LongPoll.\n\nЧтобы реализовать подобную фичу, нужно определить, какое именно сообщение, приходящее из LongPoll, было только что отправлено.\nДля этого нужно:\n1) Создать `random_id` и сохранить его в списке с отправляемыми сообщениями\n2) Отправить сообщение\n3) Дождаться прихода из LongPoll сообщения с нашим `random_id`\n4) Удалить `random_id` из списка, тем самым пометив сообщение как отправленное.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanyadev%2Flongpoll-doc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanyadev%2Flongpoll-doc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanyadev%2Flongpoll-doc/lists"}