Необработанный API Telegram может сбивать с толку, особенно когда речь идет о "чатах", "каналах", "группах", "мегагруппах" и всех этих понятиях.
В этом разделе объясняется, что представляет собой каждое из этих понятий.
Chat
можно использовать для обсуждения любых общих тем "подкласса", который используется как для чатов, так и для каналов, либо для конкретного типа Chat
.
Технически и Chat
, и Channels
являются разновидностью типа Chat
.
В большинстве случаев термин *Chat*
используется для обозначения небольших групповых чатов. Когда создается группа через официальное приложение, то получается именно такой тип. В официальных приложениях они называются "Группой".
И API бота, и Telethon добавят знак минус (-
) к реальному идентификатору чата, чтобы можно было с первого взгляда определить тип объекта с помощью числа.
Например, если создается чат с помощью functions.messages.CreateChatRequest
, реальный идентификатор чата может быть, например, 123. Если распечатать его из message.chat_id
, то увидим -123. Этот идентификатор помогает Telethon понять, что речь идет о чате.
from telethon.sync import TelegramClient from telethon import functions with TelegramClient(name, api_id, api_hash) as client: result = client(functions.messages.CreateChatRequest( users=['username'], title='My awesome title', ttl_period=42 )) print(result.stringify())
Официальные приложения создают канал трансляции при создании нового канала (используется для трансляции сообщений, сообщения могут публиковать только администраторы).
Официальные приложения неявно переносят существующий Chat
в Channel
мегагруппы, когда выполняются определенные действия (превышается лимит пользователей, добавляется общедоступное имя пользователя, устанавливаются определенные разрешения и т. д.).
Канал можно создать непосредственно с помощью functions.messages.CreateChannelRequest
как мегагруппу или трансляцию.
Официальные приложения используют термин Channel
только для каналов вещания.
API относится к различным типам каналов с определенными атрибутами:
channel.broadcast
, установленным в значение True
.channel.megagroup
, установленным в значение True
. В официальных приложениях это называется "супергруппой".channel.gigagroup
, установленным в значение True
. В официальных приложениях это называется "широковещательными группами" и используется, когда мегагруппа становится очень большой и администраторы хотят превратить ее во что-то, где только они могут публиковать сообщения.И API бота, и Telethon "объединят" -100
с реальным идентификатором чата, чтобы можно было с первого взгляда определить тип объекта по номеру.
Например, если создается новый широковещательный канал, то реальный идентификатор канала может быть, например, 456. Если распечатать его из message.chat_id
, увидим -1000000000456
. Этот идентификатор помогает Telethon понять, что речь идет о канале.
Можно конвертировать между "помеченными" идентификаторами (со знаком минус) и реальными с помощью utils.resolve_id()
. Метод вернет кортеж с реальным идентификатором и типом узла (классом):
from telethon import utils real_id, peer_type = utils.resolve_id(-1000000000456) print(real_id) # 456 print(peer_type) # <class 'telethon.tl.types.PeerChannel'> peer = peer_type(real_id) print(peer) # PeerChannel(channel_id=456)
Обратная операция может быть выполнена с помощью utils.get_peer_id()
:
print(utils.get_peer_id(types.PeerChannel(456))) # -1000000000456
Обратите внимание, что эта функция также может работать с другими типами, такими как экземпляры чата или канала.
Если нужно преобразовать другие типы, такие как имена пользователей, которым, возможно, потребуется выполнить вызовы API для определения идентификатора, то необходимо использовать client.get_peer_id()
:
print(await client.get_peer_id('me')) # напечатает собственный ID
Если "пометки" (знак минус) НЕТ, то Telethon
будет считать, что идентификатор относится к типу User
. Если это не так, то это можно исправить вручную:
from telethon import types # явный тип узла await client.send_message(types.PeerChannel(456), 'hello')
Некоторые методы работают только c типом Chat
, а некоторые другие работают только с Channel
(т.е. работают только в трансляции или мегагруппе). Скорее всего код знает, с чем работает, поэтому это не должно быть большой проблемой.
Если все таки нужно найти канал из чата, который был перенесен на него, то необходимо использовать chat.migrated_to
:
# chat это `Chat` channel = await client.get_entity(chat.migrated_to) # channel теперь является `Channel`
У типа Channel
нет метода .migrated_from
, но у ChannelFull
есть. Можно использовать GetFullChannelRequest
, чтобы это получить:
from telethon import functions full = await client(functions.channels.GetFullChannelRequest(your_channel)) full_channel = full.full_chat # переменная `full_channel` - имеет тип `ChannelFull` print(full_channel.migrated_from_chat_id)
Таким образом, также можно получить доступ к связанной дискуссионной мегагруппе вещательного канала:
# выводит идентификатор связанной дискуссионной группы или `None` print(full_channel.linked_chat_id)
Не нужно использовать метод client.get_entity()
для доступа к чату migred_from_chat_id
или каналу linked_chat_id
. Они находятся в атрибуте full.chats
:
if full_channel.migrated_from_chat_id: migrated_from_chat = next(c for c in full.chats if c.id == full_channel.migrated_from_chat_id) print(migrated_from_chat.title) if full_channel.linked_chat_id: linked_group = next(c for c in full.chats if c.id == full_channel.linked_chat_id) print(linked_group.username)