💬 Чаты
Список чатов, история сообщений, создание, настройки, участники.
client.cached_chats
Список чатов из кэша LOGIN-ответа. Заполняется после успешного LOGIN, без дополнительных запросов. Подтверждено ✅
Структура объекта чата
| Ключ | Тип | Описание |
|---|---|---|
id | int | ID чата |
type | str | DIALOG, GROUP, CHANNEL |
status | str | ACTIVE, BLOCKED |
newMessages | int | Количество непрочитанных |
lastMessage | dict | Последнее сообщение чата |
lastEventTime | int | Время последнего события (Unix ms) |
participants | dict | uid → timestamp (для диалогов) |
owner | int | UID владельца (для групп) |
options | dict | Флаги: SERVICE_CHAT и др. |
chats = client.cached_chats for chat in chats: unread = chat.get('newMessages', 0) last = chat.get('lastMessage', {}).get('text', '') print(f"[{chat['type']}] id={chat['id']} unread={unread}") if last: print(f" └─ {last[:60]}")
get_chats()
Кэш LOGIN
Возвращает полный список чатов из кэша, полученного при входе (LOGIN, opcode 19). Никаких сетевых запросов не делает.
poll_chats(count=50)
CHATS_LIST · opcode 53
Delta-опрос: запрашивает у сервера чаты, изменившиеся с момента последнего маркера. Автоматически мёрджит изменения в кэш и обновляет маркер для следующего вызова.
Как работает delta-sync
Протокол реализует delta-синхронизацию через поле marker:
- При логине
LOGINотдаёт полный снапшот чатов +chatMarker=N poll_chats()отправляетCHATS_LIST{marker: N, count: 50}- Сервер возвращает только чаты с новой активностью начиная с маркера
N - В ответе приходит новый маркер — он сохраняется для следующего
poll_chats()
Wire-параметры (opcode 53)
{
"marker": 0, # обязательно! без него ошибка proto.payload
"count": 50
}
marker обязательно — его отсутствие вызывает ошибку
proto.payload: Field requirement failed: marker.Передача
types или withLastMessage вызывает немедленный
TCP-дисконнект (битые параметры сервера).
Пример
# Получить все чаты (снапшот при входе) chats = await client.get_chats() # Получить обновления чатов с момента последнего опроса delta = await client.poll_chats() if delta: print(f"Обновилось {len(delta)} чатов")
get_chat_history(chat_id, count=20, from_msg=None)
CHAT_HISTORY · opcode 49
Загружает историю сообщений чата. Подтверждено ✅
| Параметр | Тип | Описание |
|---|---|---|
chat_id | int | ID чата |
count | int | Количество сообщений (backward). По умолчанию 20. |
from_msg | int | Необязательно. Точка отчёта (Unix ms). По умолчанию — текущее время. |
messages (list)Wire-параметры запроса
{
"chatId": 34540359,
"from": 1774188368109, # текущее время в ms ← обязательно!
"backward": 20,
"forward": 0,
"getMessages": true,
"getChat": false,
"itemType": "REGULAR", # или "DELAYED"
"interactive": true
}
from обязательно. Без него сервер вернёт пустой ответ.
Допустимые значения itemType: "REGULAR" и "DELAYED".Структура сообщения в ответе
| Ключ | Тип | Описание |
|---|---|---|
id | int | ID сообщения (64-бит) |
time | int | Время отправки (Unix ms) |
type | str | USER, SYSTEM, BOT |
sender | int | UID отправителя |
text | str | Текст сообщения |
attaches | list | Вложения (фото, файлы и т.д.) |
elements | list | Форматирование (BOLD, LINK и т.д.) |
Пример
data = await client.get_chat_history(chat_id=34540359, count=10) for msg in data.get("messages", []): text = msg.get("text", "")[:80] print(f"[{msg['sender']}]: {text}")
get_chat_info(chat_id)
CHAT_INFO · opcode 48
Возвращает полную информацию о чате. Статус текущей Python-обёртки: проблемный / не подтверждён.
{"chatId": id} не совпадает с реальным ожидаемым wire-форматом сервера. Для DIALOG пришла ошибка {"error": "proto.payload", "message": "'chatIds' or 'link' must be present"}.CHANNEL с отрицательным id привела к TCP-дисконнекту. Поэтому метод пока нельзя считать рабочим ни для DIALOG, ни для групп/каналов, несмотря на более ранние предположения.get_chat_info() экспериментальным методом.info = await client.get_chat_info(chat_id=34540359)
create_chat(title, member_ids=None)
CHAT_CREATE · opcode 63
Создаёт новый групповой чат. Статус текущей Python-обёртки: проблемный / не подтверждён.
create_chat(title, member_ids=None) стабильно возвращает {"error": "proto.opcode", "message": "Unknown opcode"}. Это указывает на несоответствие между текущей Python-реализацией и фактическим серверным протоколом.| Параметр | Тип | Описание |
|---|---|---|
title | str | Название группы |
member_ids | list[int] | Необязательно. Список UID участников |
chat = await client.create_chat( title="Моя группа", member_ids=[27993802, 12277280] )
get_chat_members(chat_id, count=100)
CHAT_MEMBERS · opcode 59
Список участников чата. Подтверждено в бою ✅
CHAT-чатов метод успешно отработал и у владельца, и у обычного участника. Для некоторых CHANNEL сервер может вернуть chat.denied / User is not admin, если у сессии недостаточно прав.membersjoin_chat(link)
CHAT_JOIN · opcode 57
Присоединяется к публичному чату/каналу по invite-ссылке. Подтверждено в бою ✅
TEST через реальную invite-ссылку вернула объект chat и control event joinByLink в последнем сообщении чата.await client.join_chat("https://max.ru/join/...")
leave_chat(chat_id)
CHAT_LEAVE · opcode 58
Покидает чат. Подтверждено в бою ✅
{"_type": "CONTROL", "event": "leave"}.📡 Входящие уведомления (NOTIF)
| Константа | Opcode | Событие |
|---|---|---|
| NOTIF_CHAT | 135 | Изменение чата (название, аватар, участники) |
| NOTIF_PRESENCE | 132 | Онлайн-статус собеседника |
| NOTIF_CONTACT_SORT | 139 | Изменение сортировки контактов |
| NOTIF_FOLDERS | 277 | Изменение папок |
| NOTIF_LOCATION | 147 | Новая геопозиция |