👥 Контакты

Список контактов, поиск, блокировки, информация о пользователях.

property client.cached_contacts

Список активных контактов из кэша LOGIN-ответа. Загружается при connect().

→ list[dict]
for contact in client.cached_contacts:
    print(contact.get('id'), contact.get('name'))
async get_contacts(status="BLOCKED") CONTACT_LIST · opcode 36

Возвращает список контактов по статусу с сервера. Подтверждено ✅

ПараметрТипОписание
status str Фильтр статуса:
"BLOCKED" — заблокированные контакты
"REMOVED" — удалённые контакты
→ list[dict] — список контактов
ℹ️
Обычные активные контакты загружаются из LOGIN-кэша через cached_contacts. Запрос CONTACT_LIST используется только для заблокированных и удалённых.
⚠️
Сервер принимает строго count=40 в wire-параметрах. Другие значения вызывают разрыв соединения.
# Заблокированные контакты
blocked = await client.get_contacts(status="BLOCKED")
print(f"Заблокировано: {len(blocked)}")

# Удалённые контакты
removed = await client.get_contacts(status="REMOVED")
async get_contact_by_phone(phone) CONTACT_INFO_BY_PHONE · opcode 46

Ищет аккаунт по номеру телефона. Подтверждено ✅

ПараметрТипОписание
phonestrНомер в формате "+79999999999" или "79999999999"
→ dict
ℹ️
Живая проверка на реальной сессии подтвердила, что метод отличает существующий номер от несуществующего. Для найденного аккаунта сервер обычно возвращает {"contact": {...}}, а для отсутствующего — обычный dict с error="contact.not.found".
result = await client.get_contact_by_phone("+79999999999")

if result.get("contact"):
    print("Аккаунт найден", result["contact"]["id"])
else:
    print(result.get("error"))

Пример успешного ответа

{
  "contact": {
    "id": 61091213,
    "updateTime": 1774268217766,
    "names": [
      {
        "name": "Телеграм",
        "firstName": "Телеграм",
        "lastName": "",
        "type": "ONEME"
      }
    ],
    "options": ["TT", "ONEME"],
    "accountStatus": 0,
    "country": ""
  }
}

Пример ответа, если номер не найден

{
  "error": "contact.not.found",
  "message": "Cannot found contact by phone",
  "localizedMessage": "Контакт не найден",
  "title": "Контакт не найден"
}
async search_contacts(query) CONTACT_SEARCH · opcode 37

Поиск пользователей по имени или номеру телефона.

ПараметрТипОписание
querystrПоисковый запрос: имя, фамилия или номер телефона
→ dict с ключами result и total
ℹ️
Внутри обёртка автоматически добавляет обязательный параметр count. Голый wire-запрос CONTACT_SEARCH без него сервер отклоняет ошибкой proto.payload.
results = await client.search_contacts("Новости")

print(results["total"])
for c in results.get("result", []):
    print(c.get("id"), c.get("name"))

Пример реального ответа

{
  "result": [],
  "total": 0
}
async search(query) CONTACT_SEARCH + PUBLIC_SEARCH · глобальный

Глобальный поиск — аналог get_entity() в Telethon. Одновременно ищет в кэше чатов, серверных контактах и публичных чатах.

ПараметрТипОписание
querystrИмя, ник или часть названия чата
→ dict с ключами: chats, contacts, public, contacts_total, public_total, public_ucpQId, contacts_raw, public_raw

Источники результатов

КлючИсточникСеть?
chatsКэш LOGIN — поиск по названию/имени/id❌ нет
contactsCONTACT_SEARCH (opcode 37)✅ да
publicPUBLIC_SEARCH (opcode 60) — каналы и группы✅ да

contacts и public запрашиваются параллельно через asyncio.gather().

ℹ️
Если один из серверных источников вернул ошибку, метод не валится целиком: библиотека подставляет пустой список только для проблемного источника и возвращает частичный результат.
ℹ️
contacts берётся из CONTACT_SEARCH.result, а public — из PUBLIC_SEARCH.result. Чтобы не терять служебные поля вроде total и ucpQId, метод также возвращает полные wire-ответы в contacts_raw и public_raw.
ℹ️
Внутри элементов public/public_raw может встречаться сырое поле previewData типа bytes, поэтому прямой json.dumps(...) без default=... может падать.
results = await client.search("Новости")

    print(results["public_total"])
    print(results["public_ucpQId"])
    print(results["public_raw"]["total"])

for chat in results["chats"]:
    print("Чат:", chat["id"])

for c in results["contacts"]:
    print("Контакт:", c.get("name"), c["id"])

for p in results["public"]:
    chat = p.get("chat", {})
    print("Публичный чат:", chat.get("title"), chat.get("link"))

Пример реального PUBLIC_SEARCH-ответа

{
  "result": [
    {
      "chat": {
        "id": -69106129488590,
        "type": "CHANNEL",
        "title": "Новости",
        "link": "https://max.ru/politics_today",
        "participantsCount": 30205,
        "description": "Главные новости из России и мира"
      },
      "highlights": ["Новости", "новости"]
    }
  ],
  "total": 7,
  "ucpQId": "f75fa88e0e24be98"
}

Вывод по живой проверке

search_contacts("Новости") -> {"result": [], "total": 0}
PUBLIC_SEARCH("Новости") -> 7 публичных результатов
    search("Новости") -> chats=2, contacts=0, public=7

Другие контактные методы

async _send_command(OpCode.CONTACT_INFO, {"uid": uid}) CONTACT_INFO · opcode 32

Получить информацию о конкретном пользователе по UID. Высокоуровневой обёртки нет — используйте напрямую:

info = await client._send_command(
    OpCode.CONTACT_INFO,
    {"uid": 27993802}
)
async _send_command(OpCode.CONTACT_PRESENCE, {"uid": uid}) CONTACT_PRESENCE · opcode 35

Получить онлайн-статус пользователя.

Все контактные OpCode

КонстантаOpcodeОписание
CONTACT_INFO32Информация о пользователе
CONTACT_ADD33Добавить контакт
CONTACT_UPDATE34Обновить контакт
CONTACT_PRESENCE35Статус онлайн
CONTACT_LIST36Список контактов по статусу
CONTACT_SEARCH37Поиск контактов
CONTACT_MUTUAL38Общие контакты
CONTACT_PHOTOS39Фотографии контакта
CONTACT_SORT30Сортировка контактов
CONTACT_VERIFY42Верификация контакта
CONTACT_INFO_BY_PHONE46Поиск по номеру телефона
NOTIF_CONTACT131Входящее: изменение контакта
NOTIF_PRESENCE132Входящее: изменение онлайн-статуса
NOTIF_CONTACT_SORT139Входящее: новый порядок контактов
NOTIF_PROFILE159Входящее: изменение профиля

Структура объекта контакта

{
  "id":           27993802,
  "phone":        "+79999999999",
  "firstName":    "Иван",
  "lastName":     "Петров",
  "name":         "Иван Петров",
  "updateTime":   1774000000000,   # Unix ms
  "accountStatus": 0,
  "country":      "RU"
}