Custom package

The telethon.tl.custom package contains custom classes that the library uses in order to make working with Telegram easier. Only those that you are supposed to use will be documented here. You can use undocumented ones at your own risk.

More often than not, you don’t need to import these (unless you want type hinting), nor do you need to manually create instances of these classes. They are returned by client methods.

AdminLogEvent

class telethon.tl.custom.adminlogevent.AdminLogEvent(original, entities)

Bases: object

Represents a more friendly interface for admin log events.

Members:
original (ChannelAdminLogEvent):
The original ChannelAdminLogEvent.
entities (dict):

A dictionary mapping user IDs to User.

When old and new are ChannelParticipant, you can use this dictionary to map the user_id, kicked_by, inviter_id and promoted_by IDs to their User.

user (User):
The user that caused this action (entities[original.user_id]).
input_user (InputPeerUser):
Input variant of user.
__dict__ = mappingproxy({'__module__': 'telethon.tl.custom.adminlogevent', '__doc__': '\n Represents a more friendly interface for admin log events.\n\n Members:\n original (:tl:`ChannelAdminLogEvent`):\n The original :tl:`ChannelAdminLogEvent`.\n\n entities (`dict`):\n A dictionary mapping user IDs to :tl:`User`.\n\n When `old` and `new` are :tl:`ChannelParticipant`, you can\n use this dictionary to map the ``user_id``, ``kicked_by``,\n ``inviter_id`` and ``promoted_by`` IDs to their :tl:`User`.\n\n user (:tl:`User`):\n The user that caused this action (``entities[original.user_id]``).\n\n input_user (:tl:`InputPeerUser`):\n Input variant of `user`.\n ', '__init__': <function AdminLogEvent.__init__>, 'id': <property object>, 'date': <property object>, 'user_id': <property object>, 'action': <property object>, 'old': <property object>, 'new': <property object>, 'changed_about': <property object>, 'changed_title': <property object>, 'changed_username': <property object>, 'changed_photo': <property object>, 'changed_sticker_set': <property object>, 'changed_message': <property object>, 'deleted_message': <property object>, 'changed_admin': <property object>, 'changed_restrictions': <property object>, 'changed_invites': <property object>, 'changed_location': <property object>, 'joined': <property object>, 'joined_invite': <property object>, 'left': <property object>, 'changed_hide_history': <property object>, 'changed_signatures': <property object>, 'changed_pin': <property object>, 'changed_default_banned_rights': <property object>, 'stopped_poll': <property object>, '__str__': <function AdminLogEvent.__str__>, 'stringify': <function AdminLogEvent.stringify>, '__dict__': <attribute '__dict__' of 'AdminLogEvent' objects>, '__weakref__': <attribute '__weakref__' of 'AdminLogEvent' objects>})
__str__()

Return str(self).

__weakref__

list of weak references to the object (if defined)

action

The original ChannelAdminLogEventAction.

changed_about

Whether the channel’s about was changed or not.

If True, old and new will be present as str.

changed_admin

Whether the permissions for an admin in this channel changed or not.

If True, old and new will be present as ChannelParticipant.

changed_default_banned_rights

Whether the default banned rights were changed or not.

If True, old and new will be present as ChatBannedRights.

changed_hide_history

Whether hiding the previous message history for new members in the channel was toggled or not.

If True, old and new will be present as bool.

changed_invites

Whether the invites in the channel were toggled or not.

If True, old and new will be present as bool.

changed_location

Whether the location setting of the channel has changed or not.

If True, old and new will be present as ChannelLocation.

changed_message

Whether a message in this channel was edited or not.

If True, old and new will be present as Message.

changed_photo

Whether the channel’s photo was changed or not.

If True, old and new will be present as Photo.

changed_pin

Whether a new message in this channel was pinned or not.

If True, new will be present as Message.

changed_restrictions

Whether a message in this channel was edited or not.

If True, old and new will be present as ChannelParticipant.

changed_signatures

Whether the message signatures in the channel were toggled or not.

If True, old and new will be present as bool.

changed_sticker_set

Whether the channel’s sticker set was changed or not.

If True, old and new will be present as InputStickerSet.

changed_title

Whether the channel’s title was changed or not.

If True, old and new will be present as str.

changed_username

Whether the channel’s username was changed or not.

If True, old and new will be present as str.

date

The date when this event occured.

deleted_message

Whether a message in this channel was deleted or not.

If True, old will be present as Message.

id

The ID of this event.

joined

Whether user joined through the channel’s public username or not.

joined_invite

Whether a new user joined through an invite link to the channel or not.

If True, new will be present as ChannelParticipant.

left

Whether user left the channel or not.

new

The new value present in the event.

old

The old value from the event.

stopped_poll

Whether a poll was stopped or not.

If True, new will be present as Message.

stringify()
user_id

The ID of the user that triggered this event.

Button

class telethon.tl.custom.button.Button(button, *, resize, single_use, selective)

Bases: object

Note

This class is used to define reply markups, e.g. when sending a message or replying to events. When you access Message.buttons they are actually MessageButton, so you might want to refer to that class instead.

Helper class to allow defining reply_markup when sending a message with inline or keyboard buttons.

You should make use of the defined class methods to create button instances instead making them yourself (i.e. don’t do Button(...) but instead use methods line Button.inline(...) etc.

You can use inline, switch_inline and url together to create inline buttons (under the message).

You can use text, request_location and request_phone together to create a reply markup (replaces the user keyboard). You can also configure the aspect of the reply with these.

You cannot mix the two type of buttons together, and it will error if you try to do so.

The text for all buttons may be at most 142 characters. If more characters are given, Telegram will cut the text to 128 characters and add the ellipsis (…) character as the 129.

__dict__ = mappingproxy({'__module__': 'telethon.tl.custom.button', '__doc__': "\n .. note::\n\n This class is used to **define** reply markups, e.g. when\n sending a message or replying to events. When you access\n `Message.buttons <telethon.tl.custom.message.Message.buttons>`\n they are actually `MessageButton\n <telethon.tl.custom.messagebutton.MessageButton>`,\n so you might want to refer to that class instead.\n\n Helper class to allow defining ``reply_markup`` when\n sending a message with inline or keyboard buttons.\n\n You should make use of the defined class methods to create button\n instances instead making them yourself (i.e. don't do ``Button(...)``\n but instead use methods line `Button.inline(...) <inline>` etc.\n\n You can use `inline`, `switch_inline` and `url`\n together to create inline buttons (under the message).\n\n You can use `text`, `request_location` and `request_phone`\n together to create a reply markup (replaces the user keyboard).\n You can also configure the aspect of the reply with these.\n\n You **cannot** mix the two type of buttons together,\n and it will error if you try to do so.\n\n The text for all buttons may be at most 142 characters.\n If more characters are given, Telegram will cut the text\n to 128 characters and add the ellipsis (…) character as\n the 129.\n ", '__init__': <function Button.__init__>, '_is_inline': <staticmethod object>, 'inline': <staticmethod object>, 'switch_inline': <staticmethod object>, 'url': <staticmethod object>, 'auth': <staticmethod object>, 'text': <classmethod object>, 'request_location': <classmethod object>, 'request_phone': <classmethod object>, 'clear': <staticmethod object>, 'force_reply': <staticmethod object>, '__dict__': <attribute '__dict__' of 'Button' objects>, '__weakref__': <attribute '__weakref__' of 'Button' objects>})
__weakref__

list of weak references to the object (if defined)

static auth(text, url=None, *, bot=None, write_access=False, fwd_text=None)

Creates a new inline button to authorize the user at the given URL.

You should set the url to be on the same domain as the one configured for the desired bot via @BotFather using the /setdomain command.

For more information about letting the user login via Telegram to a certain domain, see https://core.telegram.org/widgets/login.

If no url is specified, it will default to text.

Args:
bot (hints.EntityLike):

The bot that requires this authorization. By default, this is the bot that is currently logged in (itself), although you may pass a different input peer.

Note

For now, you cannot use ID or username for this argument. If you want to use a different bot than the one currently logged in, you must manually use client.get_input_entity().

write_access (bool):
Whether write access is required or not. This is False by default (read-only access).
fwd_text (str):
The new text to show in the button if the message is forwarded. By default, the button text will be the same.
static clear()

Clears all keyboard buttons after sending a message with this markup. When used, no other button should be present or it will be ignored.

static force_reply()

Forces a reply to the message with this markup. If used, no other button should be present or it will be ignored.

static inline(text, data=None)

Creates a new inline button with some payload data in it.

If data is omitted, the given text will be used as data. In any case data should be either bytes or str.

Note that the given data must be less or equal to 64 bytes. If more than 64 bytes are passed as data, ValueError is raised.

classmethod request_location(text, *, resize=None, single_use=None, selective=None)

Creates a new keyboard button to request the user’s location on click.

resize, single_use and selective are documented in text.

classmethod request_phone(text, *, resize=None, single_use=None, selective=None)

Creates a new keyboard button to request the user’s phone on click.

resize, single_use and selective are documented in text.

static switch_inline(text, query='', same_peer=False)

Creates a new inline button to switch to inline query.

If query is given, it will be the default text to be used when making the inline query.

If same_peer is True the inline query will directly be set under the currently opened chat. Otherwise, the user will have to select a different dialog to make the query.

classmethod text(text, *, resize=None, single_use=None, selective=None)

Creates a new keyboard button with the given text.

Args:
resize (bool):
If present, the entire keyboard will be reconfigured to be resized and be smaller if there are not many buttons.
single_use (bool):
If present, the entire keyboard will be reconfigured to be usable only once before it hides itself.
selective (bool):
If present, the entire keyboard will be reconfigured to be “selective”. The keyboard will be shown only to specific users. It will target users that are @mentioned in the text of the message or to the sender of the message you reply to.
static url(text, url=None)

Creates a new inline button to open the desired URL on click.

If no url is given, the text will be used as said URL instead.

You cannot detect that the user clicked this button directly.

ChatGetter

class telethon.tl.custom.chatgetter.ChatGetter(chat_peer=None, *, input_chat=None, chat=None, broadcast=None)

Bases: abc.ABC

Helper base class that introduces the chat, input_chat and chat_id properties and get_chat and get_input_chat methods.

__dict__ = mappingproxy({'__module__': 'telethon.tl.custom.chatgetter', '__doc__': '\n Helper base class that introduces the `chat`, `input_chat`\n and `chat_id` properties and `get_chat` and `get_input_chat`\n methods.\n ', '__init__': <function ChatGetter.__init__>, 'chat': <property object>, 'get_chat': <function ChatGetter.get_chat>, 'input_chat': <property object>, 'get_input_chat': <function ChatGetter.get_input_chat>, 'chat_id': <property object>, 'is_private': <property object>, 'is_group': <property object>, 'is_channel': <property object>, '_refetch_chat': <function ChatGetter._refetch_chat>, '__dict__': <attribute '__dict__' of 'ChatGetter' objects>, '__weakref__': <attribute '__weakref__' of 'ChatGetter' objects>, '__abstractmethods__': frozenset(), '_abc_impl': <_abc_data object>})
__weakref__

list of weak references to the object (if defined)

chat

Returns the User, Chat or Channel where this object belongs to. It may be None if Telegram didn’t send the chat.

If you only need the ID, use chat_id instead.

If you need to call a method which needs this chat, use input_chat instead.

If you’re using telethon.events, use get_chat() instead.

chat_id

Returns the marked chat integer ID. Note that this value will be different from to_id for incoming private messages, since the chat to which the messages go is to your own person, but the chat itself is with the one who sent the message.

TL;DR; this gets the ID that you expect.

If there is a chat in the object, chat_id will always be set, which is why you should use it instead of chat.id.

get_chat()

Returns chat, but will make an API call to find the chat unless it’s already cached.

If you only need the ID, use chat_id instead.

If you need to call a method which needs this chat, use get_input_chat() instead.

get_input_chat()

Returns input_chat, but will make an API call to find the input chat unless it’s already cached.

input_chat

This InputPeer is the input version of the chat where the message was sent. Similarly to input_sender, this doesn’t have things like username or similar, but still useful in some cases.

Note that this might not be available if the library doesn’t have enough information available.

is_channel

True if the message was sent on a megagroup or channel.

is_group

True if the message was sent on a group or megagroup.

Returns None if there isn’t enough information (e.g. on events.MessageDeleted).

is_private

True if the message was sent as a private message.

Returns None if there isn’t enough information (e.g. on events.MessageDeleted).

Conversation

class telethon.tl.custom.conversation.Conversation(client, input_chat, *, timeout, total_timeout, max_messages, exclusive, replies_are_responses)

Bases: telethon.tl.custom.chatgetter.ChatGetter

Represents a conversation inside an specific chat.

A conversation keeps track of new messages since it was created until its exit and easily lets you query the current state.

If you need a conversation across two or more chats, you should use two conversations and synchronize them as you better see fit.

__aenter__()
__aexit__(exc_type, exc_val, exc_tb)
__enter__()

Helps to cut boilerplate on async context managers that offer synchronous variants.

__exit__(*args)
cancel()

Cancels the current conversation. Pending responses and subsequent calls to get a response will raise asyncio.CancelledError.

This method is synchronous and should not be awaited.

cancel_all()

Calls cancel on all conversations in this chat.

Note that you should await this method, since it’s meant to be used outside of a context manager, and it needs to resolve the chat.

get_edit(message=None, *, timeout=None)

Awaits for an edit after the last message to arrive. The arguments are the same as those for get_response.

get_reply(message=None, *, timeout=None)

Gets the next message that explicitly replies to a previous one.

get_response(message=None, *, timeout=None)

Gets the next message that responds to a previous one.

Args:
message (Message | int, optional):
The message (or the message ID) for which a response is expected. By default this is the last sent message.
timeout (int | float, optional):
If present, this timeout (in seconds) will override the per-action timeout defined for the conversation.
mark_read(message=None)

Marks as read the latest received message if message is None. Otherwise, marks as read until the given message (or message ID).

This is equivalent to calling client.send_read_acknowledge.

send_file(*args, **kwargs)

Sends a file in the context of this conversation. Shorthand for telethon.client.uploads.UploadMethods.send_file with entity already set.

send_message(*args, **kwargs)

Sends a message in the context of this conversation. Shorthand for telethon.client.messages.MessageMethods.send_message with entity already set.

wait_event(event, *, timeout=None)

Waits for a custom event to occur. Timeouts still apply.

Unless you’re certain that your code will run fast enough, generally you should get a “handle” of this special coroutine before acting. Generally, you should do this:

>>> from telethon import TelegramClient, events
>>>
>>> client = TelegramClient(...)
>>>
>>> async def main():
>>>     async with client.conversation(...) as conv:
>>>         response = conv.wait_event(events.NewMessage(incoming=True))
>>>         await conv.send_message('Hi')
>>>         response = await response

This way your event can be registered before acting, since the response may arrive before your event was registered. It depends on your use case since this also means the event can arrive before you send a previous action.

wait_read(message=None, *, timeout=None)

Awaits for the sent message to be marked as read. Note that receiving a response doesn’t imply the message was read, and this action will also trigger even without a response.

Dialog

class telethon.tl.custom.dialog.Dialog(client, dialog, entities, message)

Bases: object

Custom class that encapsulates a dialog (an open “conversation” with someone, a group or a channel) providing an abstraction to easily access the input version/normal entity/message etc. The library will return instances of this class when calling get_dialogs().

Args:
dialog (Dialog):
The original Dialog instance.
pinned (bool):
Whether this dialog is pinned to the top or not.
folder_id (folder_id):
The folder ID that this dialog belongs to.
archived (bool):
Whether this dialog is archived or not (folder_id is None).
message (Message):
The last message sent on this dialog. Note that this member will not be updated when new messages arrive, it’s only set on creation of the instance.
date (datetime):
The date of the last message sent on this dialog.
entity (entity):
The entity that belongs to this dialog (user, chat or channel).
input_entity (InputPeer):
Input version of the entity.
id (int):
The marked ID of the entity, which is guaranteed to be unique.
name (str):
Display name for this dialog. For chats and channels this is their title, and for users it’s “First-Name Last-Name”.
title (str):
Alias for name.
unread_count (int):
How many messages are currently unread in this dialog. Note that this value won’t update when new messages arrive.
unread_mentions_count (int):
How many mentions are currently unread in this dialog. Note that this value won’t update when new messages arrive.
draft (Draft):
The draft object in this dialog. It will not be None, so you can call draft.set_message(...).
is_user (bool):
True if the entity is a User.
is_group (bool):
True if the entity is a Chat or a Channel megagroup.
is_channel (bool):
True if the entity is a Channel.
__dict__ = mappingproxy({'__module__': 'telethon.tl.custom.dialog', '__doc__': '\n Custom class that encapsulates a dialog (an open "conversation" with\n someone, a group or a channel) providing an abstraction to easily\n access the input version/normal entity/message etc. The library will\n return instances of this class when calling :meth:`.get_dialogs()`.\n\n Args:\n dialog (:tl:`Dialog`):\n The original ``Dialog`` instance.\n\n pinned (`bool`):\n Whether this dialog is pinned to the top or not.\n\n folder_id (`folder_id`):\n The folder ID that this dialog belongs to.\n\n archived (`bool`):\n Whether this dialog is archived or not (``folder_id is None``).\n\n message (`Message <telethon.tl.custom.message.Message>`):\n The last message sent on this dialog. Note that this member\n will not be updated when new messages arrive, it\'s only set\n on creation of the instance.\n\n date (`datetime`):\n The date of the last message sent on this dialog.\n\n entity (`entity`):\n The entity that belongs to this dialog (user, chat or channel).\n\n input_entity (:tl:`InputPeer`):\n Input version of the entity.\n\n id (`int`):\n The marked ID of the entity, which is guaranteed to be unique.\n\n name (`str`):\n Display name for this dialog. For chats and channels this is\n their title, and for users it\'s "First-Name Last-Name".\n\n title (`str`):\n Alias for `name`.\n\n unread_count (`int`):\n How many messages are currently unread in this dialog. Note that\n this value won\'t update when new messages arrive.\n\n unread_mentions_count (`int`):\n How many mentions are currently unread in this dialog. Note that\n this value won\'t update when new messages arrive.\n\n draft (`Draft <telethon.tl.custom.draft.Draft>`):\n The draft object in this dialog. It will not be `None`,\n so you can call ``draft.set_message(...)``.\n\n is_user (`bool`):\n `True` if the `entity` is a :tl:`User`.\n\n is_group (`bool`):\n `True` if the `entity` is a :tl:`Chat`\n or a :tl:`Channel` megagroup.\n\n is_channel (`bool`):\n `True` if the `entity` is a :tl:`Channel`.\n ', '__init__': <function Dialog.__init__>, 'send_message': <function Dialog.send_message>, 'delete': <function Dialog.delete>, 'archive': <function Dialog.archive>, 'to_dict': <function Dialog.to_dict>, '__str__': <function Dialog.__str__>, 'stringify': <function Dialog.stringify>, '__dict__': <attribute '__dict__' of 'Dialog' objects>, '__weakref__': <attribute '__weakref__' of 'Dialog' objects>})
__str__()

Return str(self).

__weakref__

list of weak references to the object (if defined)

archive(folder=1)

Archives (or un-archives) this dialog.

Args:
folder (int, optional):

The folder to which the dialog should be archived to.

If you want to “un-archive” it, use folder=0.

Returns:
The Updates object that the request produces.

Example:

# Archiving
dialog.archive()

# Un-archiving
dialog.archive(0)
delete(revoke=False)

Deletes the dialog from your dialog list. If you own the channel this won’t destroy it, only delete it from the list.

Shorthand for telethon.client.dialogs.DialogMethods.delete_dialog with entity already set.

send_message(*args, **kwargs)

Sends a message to this dialog. This is just a wrapper around client.send_message(dialog.input_entity, *args, **kwargs).

stringify()
to_dict()

Draft

class telethon.tl.custom.draft.Draft(client, entity, draft)

Bases: object

Custom class that encapsulates a draft on the Telegram servers, providing an abstraction to change the message conveniently. The library will return instances of this class when calling get_drafts().

Args:
date (datetime):
The date of the draft.
link_preview (bool):
Whether the link preview is enabled or not.
reply_to_msg_id (int):
The message ID that the draft will reply to.
__dict__ = mappingproxy({'__module__': 'telethon.tl.custom.draft', '__doc__': '\n Custom class that encapsulates a draft on the Telegram servers, providing\n an abstraction to change the message conveniently. The library will return\n instances of this class when calling :meth:`get_drafts()`.\n\n Args:\n date (`datetime`):\n The date of the draft.\n\n link_preview (`bool`):\n Whether the link preview is enabled or not.\n\n reply_to_msg_id (`int`):\n The message ID that the draft will reply to.\n ', '__init__': <function Draft.__init__>, 'entity': <property object>, 'input_entity': <property object>, 'get_entity': <function Draft.get_entity>, 'get_input_entity': <function Draft.get_input_entity>, 'text': <property object>, 'raw_text': <property object>, 'is_empty': <property object>, 'set_message': <function Draft.set_message>, 'send': <function Draft.send>, 'delete': <function Draft.delete>, 'to_dict': <function Draft.to_dict>, '__str__': <function Draft.__str__>, 'stringify': <function Draft.stringify>, '__dict__': <attribute '__dict__' of 'Draft' objects>, '__weakref__': <attribute '__weakref__' of 'Draft' objects>})
__str__()

Return str(self).

__weakref__

list of weak references to the object (if defined)

delete()

Deletes this draft, and returns True on success.

entity

The entity that belongs to this dialog (user, chat or channel).

get_entity()

Returns entity but will make an API call if necessary.

get_input_entity()

Returns input_entity but will make an API call if necessary.

input_entity

Input version of the entity.

is_empty

Convenience bool to determine if the draft is empty or not.

raw_text

The raw (text without formatting) contained in the draft. It will be empty if there is no text (thus draft not set).

send(clear=True, parse_mode=())

Sends the contents of this draft to the dialog. This is just a wrapper around send_message(dialog.input_entity, *args, **kwargs).

set_message(text=None, reply_to=0, parse_mode=(), link_preview=None)

Changes the draft message on the Telegram servers. The changes are reflected in this object.

Parameters:
  • text (str) – New text of the draft. Preserved if left as None.
  • reply_to (int) – Message ID to reply to. Preserved if left as 0, erased if set to None.
  • link_preview (bool) – Whether to attach a web page preview. Preserved if left as None.
  • parse_mode (str) – The parse mode to be used for the text.
Return bool:

True on success.

stringify()
text

The markdown text contained in the draft. It will be empty if there is no text (and hence no draft is set).

to_dict()

File

class telethon.tl.custom.file.File(media)

Bases: object

Convenience class over media like photos or documents, which supports accessing the attributes in a more convenient way.

If any of the attributes are not present in the current media, the properties will be None.

The original media is available through the media attribute.

__dict__ = mappingproxy({'__module__': 'telethon.tl.custom.file', '__doc__': '\n Convenience class over media like photos or documents, which\n supports accessing the attributes in a more convenient way.\n\n If any of the attributes are not present in the current media,\n the properties will be `None`.\n\n The original media is available through the ``media`` attribute.\n ', '__init__': <function File.__init__>, 'id': <property object>, 'name': <property object>, 'ext': <property object>, 'mime_type': <property object>, 'width': <property object>, 'height': <property object>, 'duration': <property object>, 'title': <property object>, 'performer': <property object>, 'emoji': <property object>, 'sticker_set': <property object>, 'size': <property object>, '_size_for': <staticmethod object>, '_from_attr': <function File._from_attr>, '__dict__': <attribute '__dict__' of 'File' objects>, '__weakref__': <attribute '__weakref__' of 'File' objects>})
__weakref__

list of weak references to the object (if defined)

duration

The duration in seconds of the audio or video.

emoji

A string with all emoji that represent the current sticker.

ext

The extension from the mime type of this file.

If the mime type is unknown, the extension from the file name (if any) will be used.

height

The height in pixels of this media if it’s a photo or a video.

id

The bot-API style file_id representing this file.

mime_type

The mime-type of this file.

name

The file name of this document.

performer

The performer of the song.

size

The size in bytes of this file.

sticker_set

The InputStickerSet to which the sticker file belongs.

title

The title of the song.

width

The width in pixels of this media if it’s a photo or a video.

Forward

class telethon.tl.custom.forward.Forward(client, original, entities)

Bases: telethon.tl.custom.chatgetter.ChatGetter, telethon.tl.custom.sendergetter.SenderGetter

Custom class that encapsulates a MessageFwdHeader providing an abstraction to easily access information like the original sender.

Remember that this class implements ChatGetter and SenderGetter which means you have access to all their sender and chat properties and methods.

Attributes:

original_fwd (MessageFwdHeader):
The original MessageFwdHeader instance.
Any other attribute:
Attributes not described here are the same as those available in the original MessageFwdHeader.

InlineBuilder

class telethon.tl.custom.inlinebuilder.InlineBuilder(client)

Bases: object

Helper class to allow defining InlineQuery results.

Common arguments to all methods are explained here to avoid repetition:

text (str, optional):
If present, the user will send a text message with this text upon being clicked.
link_preview (bool, optional):
Whether to show a link preview in the sent text message or not.
geo (InputGeoPoint, GeoPoint, InputMediaVenue, MessageMediaVenue, optional):
If present, it may either be a geo point or a venue.
period (int, optional):
The period in seconds to be used for geo points.
contact (InputMediaContact, MessageMediaContact, optional):
If present, it must be the contact information to send.
game (bool, optional):
May be True to indicate that the game will be sent.
buttons (list, custom.Button, KeyboardButton, optional):
Same as buttons for client.send_message().
parse_mode (str, optional):
Same as parse_mode for client.send_message().
id (str, optional):

The string ID to use for this result. If not present, it will be the SHA256 hexadecimal digest of converting the created InputBotInlineResult with empty ID to bytes(), so that the ID will be deterministic for the same input.

Note

If two inputs are exactly the same, their IDs will be the same too. If you send two articles with the same ID, it will raise ResultIdDuplicateError. Consider giving them an explicit ID if you need to send two results that are the same.

__dict__ = mappingproxy({'__module__': 'telethon.tl.custom.inlinebuilder', '__doc__': '\n Helper class to allow defining `InlineQuery\n <telethon.events.inlinequery.InlineQuery>` ``results``.\n\n Common arguments to all methods are\n explained here to avoid repetition:\n\n text (`str`, optional):\n If present, the user will send a text\n message with this text upon being clicked.\n\n link_preview (`bool`, optional):\n Whether to show a link preview in the sent\n text message or not.\n\n geo (:tl:`InputGeoPoint`, :tl:`GeoPoint`, :tl:`InputMediaVenue`, :tl:`MessageMediaVenue`, optional):\n If present, it may either be a geo point or a venue.\n\n period (int, optional):\n The period in seconds to be used for geo points.\n\n contact (:tl:`InputMediaContact`, :tl:`MessageMediaContact`, optional):\n If present, it must be the contact information to send.\n\n game (`bool`, optional):\n May be `True` to indicate that the game will be sent.\n\n buttons (`list`, `custom.Button <telethon.tl.custom.button.Button>`, :tl:`KeyboardButton`, optional):\n Same as ``buttons`` for `client.send_message()\n <telethon.client.messages.MessageMethods.send_message>`.\n\n parse_mode (`str`, optional):\n Same as ``parse_mode`` for `client.send_message()\n <telethon.client.messageparse.MessageParseMethods.parse_mode>`.\n\n id (`str`, optional):\n The string ID to use for this result. If not present, it\n will be the SHA256 hexadecimal digest of converting the\n created :tl:`InputBotInlineResult` with empty ID to ``bytes()``,\n so that the ID will be deterministic for the same input.\n\n .. note::\n\n If two inputs are exactly the same, their IDs will be the same\n too. If you send two articles with the same ID, it will raise\n ``ResultIdDuplicateError``. Consider giving them an explicit\n ID if you need to send two results that are the same.\n ', '__init__': <function InlineBuilder.__init__>, 'article': <function InlineBuilder.article>, 'photo': <function InlineBuilder.photo>, 'document': <function InlineBuilder.document>, 'game': <function InlineBuilder.game>, '_message': <function InlineBuilder._message>, '__dict__': <attribute '__dict__' of 'InlineBuilder' objects>, '__weakref__': <attribute '__weakref__' of 'InlineBuilder' objects>})
__weakref__

list of weak references to the object (if defined)

article(title, description=None, *, url=None, thumb=None, content=None, id=None, text=None, parse_mode=(), link_preview=True, geo=None, period=60, contact=None, game=False, buttons=None)

Creates new inline result of article type.

Args:
title (str):
The title to be shown for this result.
description (str, optional):
Further explanation of what this result means.
url (str, optional):
The URL to be shown for this result.
thumb (InputWebDocument, optional):
The thumbnail to be shown for this result. For now it has to be a InputWebDocument if present.
content (InputWebDocument, optional):
The content to be shown for this result. For now it has to be a InputWebDocument if present.
document(file, title=None, *, description=None, type=None, mime_type=None, attributes=None, force_document=False, voice_note=False, video_note=False, use_cache=True, id=None, text=None, parse_mode=(), link_preview=True, geo=None, period=60, contact=None, game=False, buttons=None)

Creates a new inline result of document type.

use_cache, mime_type, attributes, force_document, voice_note and video_note are described in client.send_file.

Args:
file (obj):
Same as file for client.send_file().
title (str, optional):
The title to be shown for this result.
description (str, optional):
Further explanation of what this result means.
type (str, optional):

The type of the document. May be one of: photo, gif, mpeg4_gif, video, audio, voice, document, sticker.

See “Type of the result” in https://core.telegram.org/bots/api.

game(short_name, *, id=None, text=None, parse_mode=(), link_preview=True, geo=None, period=60, contact=None, game=False, buttons=None)

Creates a new inline result of game type.

Args:
short_name (str):
The short name of the game to use.
photo(file, *, id=None, text=None, parse_mode=(), link_preview=True, geo=None, period=60, contact=None, game=False, buttons=None)

Creates a new inline result of photo type.

Args:
file (obj, optional):
Same as file for client.send_file().

InlineResult

class telethon.tl.custom.inlineresult.InlineResult(client, original, query_id=None)

Bases: object

Custom class that encapsulates a bot inline result providing an abstraction to easily access some commonly needed features (such as clicking a result to select it).

Attributes:

result (BotInlineResult):
The original BotInlineResult object.
ARTICLE = 'article'
AUDIO = 'audio'
CONTACT = 'contact'
DOCUMENT = 'document'
GAME = 'game'
GIF = 'gif'
LOCATION = 'location'
PHOTO = 'photo'
VENUE = 'venue'
VIDEO = 'video'
VIDEO_GIF = 'mpeg4_gif'
__dict__ = mappingproxy({'__module__': 'telethon.tl.custom.inlineresult', '__doc__': '\n Custom class that encapsulates a bot inline result providing\n an abstraction to easily access some commonly needed features\n (such as clicking a result to select it).\n\n Attributes:\n\n result (:tl:`BotInlineResult`):\n The original :tl:`BotInlineResult` object.\n ', 'ARTICLE': 'article', 'PHOTO': 'photo', 'GIF': 'gif', 'VIDEO': 'video', 'VIDEO_GIF': 'mpeg4_gif', 'AUDIO': 'audio', 'DOCUMENT': 'document', 'LOCATION': 'location', 'VENUE': 'venue', 'CONTACT': 'contact', 'GAME': 'game', '__init__': <function InlineResult.__init__>, 'type': <property object>, 'message': <property object>, 'title': <property object>, 'description': <property object>, 'url': <property object>, 'photo': <property object>, 'document': <property object>, 'click': <function InlineResult.click>, 'download_media': <function InlineResult.download_media>, '__dict__': <attribute '__dict__' of 'InlineResult' objects>, '__weakref__': <attribute '__weakref__' of 'InlineResult' objects>})
__weakref__

list of weak references to the object (if defined)

click(entity, reply_to=None, silent=False, clear_draft=False, hide_via=False)

Clicks this result and sends the associated message.

Args:
entity (entity):
The entity to which the message of this result should be sent.
reply_to (int | Message, optional):
If present, the sent message will reply to this ID or message.
silent (bool, optional):
Whether the message should notify people with sound or not. Defaults to False (send with a notification sound unless the person has the chat muted). Set it to True to alter this behaviour.
clear_draft (bool, optional):
Whether the draft should be removed after sending the message from this result or not. Defaults to False.
hide_via (bool, optional):
Whether the “via @bot” should be hidden or not. Only works with certain bots (like @bing or @gif).
description

The description for this inline result. It may be None.

document

Returns either the WebDocument content for normal results or the Document for media results.

download_media(*args, **kwargs)

Downloads the media in this result (if there is a document, the document will be downloaded; otherwise, the photo will if present).

This is a wrapper around client.download_media.

message

The always-present BotInlineMessage that will be sent if click is called on this result.

photo

Returns either the WebDocument thumbnail for normal results or the Photo for media results.

title

The title for this inline result. It may be None.

type

The always-present type of this result. It will be one of: 'article', 'photo', 'gif', 'mpeg4_gif', 'video', 'audio', 'voice', 'document', 'location', 'venue', 'contact', 'game'.

You can access all of these constants through InlineResult, such as InlineResult.ARTICLE, InlineResult.VIDEO_GIF, etc.

url

The URL present in this inline results. If you want to “click” this URL to open it in your browser, you should use Python’s webbrowser.open(url) for such task.

InlineResults

class telethon.tl.custom.inlineresults.InlineResults(client, original)

Bases: list

Custom class that encapsulates BotResults providing an abstraction to easily access some commonly needed features (such as clicking one of the results to select it)

Note that this is a list of InlineResult so you can iterate over it or use indices to access its elements. In addition, it has some attributes.

Attributes:
result (BotResults):
The original BotResults object.
query_id (int):
The random ID that identifies this query.
cache_time (int):
For how long the results should be considered valid. You can call results_valid at any moment to determine if the results are still valid or not.
users (User):
The users present in this inline query.
gallery (bool):
Whether these results should be presented in a grid (as a gallery of images) or not.
next_offset (str, optional):
The string to be used as an offset to get the next chunk of results, if any.
switch_pm (InlineBotSwitchPM, optional):
If presents, the results should show a button to switch to a private conversation with the bot using the text in this object.
__dict__ = mappingproxy({'__module__': 'telethon.tl.custom.inlineresults', '__doc__': '\n Custom class that encapsulates :tl:`BotResults` providing\n an abstraction to easily access some commonly needed features\n (such as clicking one of the results to select it)\n\n Note that this is a list of `InlineResult\n <telethon.tl.custom.inlineresult.InlineResult>`\n so you can iterate over it or use indices to\n access its elements. In addition, it has some\n attributes.\n\n Attributes:\n result (:tl:`BotResults`):\n The original :tl:`BotResults` object.\n\n query_id (`int`):\n The random ID that identifies this query.\n\n cache_time (`int`):\n For how long the results should be considered\n valid. You can call `results_valid` at any\n moment to determine if the results are still\n valid or not.\n\n users (:tl:`User`):\n The users present in this inline query.\n\n gallery (`bool`):\n Whether these results should be presented\n in a grid (as a gallery of images) or not.\n\n next_offset (`str`, optional):\n The string to be used as an offset to get\n the next chunk of results, if any.\n\n switch_pm (:tl:`InlineBotSwitchPM`, optional):\n If presents, the results should show a button to\n switch to a private conversation with the bot using\n the text in this object.\n ', '__init__': <function InlineResults.__init__>, 'results_valid': <function InlineResults.results_valid>, '_to_str': <function InlineResults._to_str>, '__str__': <function InlineResults.__str__>, '__repr__': <function InlineResults.__repr__>, '__dict__': <attribute '__dict__' of 'InlineResults' objects>, '__weakref__': <attribute '__weakref__' of 'InlineResults' objects>})
__repr__()

Return repr(self).

__str__()

Return str(self).

__weakref__

list of weak references to the object (if defined)

results_valid()

Returns True if the cache time has not expired yet and the results can still be considered valid.

Message

class telethon.tl.custom.message.Message(id, to_id=None, date=None, out=None, mentioned=None, media_unread=None, silent=None, post=None, from_id=None, reply_to_msg_id=None, message=None, fwd_from=None, via_bot_id=None, media=None, reply_markup=None, entities=None, views=None, edit_date=None, post_author=None, grouped_id=None, from_scheduled=None, legacy=None, action=None)

Bases: telethon.tl.custom.chatgetter.ChatGetter, telethon.tl.custom.sendergetter.SenderGetter, telethon.tl.tlobject.TLObject, abc.ABC

This custom class aggregates both Message and MessageService to ease accessing their members.

Remember that this class implements ChatGetter and SenderGetter which means you have access to all their sender and chat properties and methods.

Members:
id (int):
The ID of this message. This field is always present. Any other member is optional and may be None.
out (bool):

Whether the message is outgoing (i.e. you sent it from another session) or incoming (i.e. someone else sent it).

Note that messages in your own chat are always incoming, but this member will be True if you send a message to your own chat. Messages you forward to your chat are not considered outgoing, just like official clients display them.

mentioned (bool):
Whether you were mentioned in this message or not. Note that replies to your own messages also count as mentions.
media_unread (bool):
Whether you have read the media in this message or not, e.g. listened to the voice note media.
silent (bool):
Whether the message should notify people with sound or not. Previously used in channels, but since 9 August 2019, it can also be used in private chats.
post (bool):
Whether this message is a post in a broadcast channel or not.
from_scheduled (bool):
Whether this message was originated from a scheduled one or not.
legacy (bool):
Whether this is a legacy message or not.
to_id (Peer):
The peer to which this message was sent, which is either PeerUser, PeerChat or PeerChannel. This will always be present except for empty messages.
date (datetime):
The UTC+0 datetime object indicating when this message was sent. This will always be present except for empty messages.
message (str):
The string text of the message for Message instances, which will be None for other types of messages.
action (MessageAction):
The message action object of the message for MessageService instances, which will be None for other types of messages.
from_id (int):
The ID of the user who sent this message. This will be None if the message was sent in a broadcast channel.
reply_to_msg_id (int):
The ID to which this message is replying to, if any.
fwd_from (MessageFwdHeader):
The original forward header if this message is a forward. You should probably use the forward property instead.
via_bot_id (int):
The ID of the bot used to send this message through its inline mode (e.g. “via @like”).
media (MessageMedia):

The media sent with this message if any (such as photos, videos, documents, gifs, stickers, etc.).

You may want to access the photo, document etc. properties instead.

If the media was not present or it was MessageMediaEmpty, this member will instead be None for convenience.

reply_markup (ReplyMarkup):
The reply markup for this message (which was sent either via a bot or by a bot). You probably want to access buttons instead.
entities (List[MessageEntity]):
The list of markup entities in this message, such as bold, italics, code, hyperlinks, etc.
views (int):
The number of views this message from a broadcast channel has. This is also present in forwards.
edit_date (datetime):
The date when this message was last edited.
post_author (str):
The display name of the message sender to show in messages sent to broadcast channels.
grouped_id (int):
If this message belongs to a group of messages (photo albums or video albums), all of them will have the same value here.
action_entities

Returns a list of entities that took part in this action.

Possible cases for this are MessageActionChatAddUser, types.MessageActionChatCreate, MessageActionChatDeleteUser, MessageActionChatJoinedByLink MessageActionChatMigrateTo and MessageActionChannelMigrateFrom.

If the action is neither of those, the result will be None. If some entities could not be retrieved, the list may contain some None items in it.

audio

The Document media in this message, if it’s an audio file.

button_count

Returns the total button count (sum of all buttons rows).

buttons

Returns a list of lists of MessageButton, if any.

Otherwise, it returns None.

click(i=None, j=None, *, text=None, filter=None, data=None)

Calls button.click on the specified button.

Does nothing if the message has no buttons.

Args:
i (int):

Clicks the i’th button (starting from the index 0). Will raise IndexError if out of bounds. Example:

>>> message = ...  # get the message somehow
>>> # Clicking the 3rd button
>>> # [button1] [button2]
>>> # [     button3     ]
>>> # [button4] [button5]
>>> await message.click(2)  # index
j (int):

Clicks the button at position (i, j), these being the indices for the (row, column) respectively. Example:

>>> # Clicking the 2nd button on the 1st row.
>>> # [button1] [button2]
>>> # [     button3     ]
>>> # [button4] [button5]
>>> await message.click(0, 1)  # (row, column)

This is equivalent to message.buttons[0][1].click().

text (str | callable):
Clicks the first button with the text “text”. This may also be a callable, like a re.compile(...).match, and the text will be passed to it.
filter (callable):
Clicks the first button for which the callable returns True. The callable should accept a single MessageButton argument.
data (bytes):
This argument overrides the rest and will not search any buttons. Instead, it will directly send the request to behave as if it clicked a button with said data. Note that if the message does not have this data, it will raise DataInvalidError.

Example:

# Click the first button
await message.click(0)

# Click some row/column
await message.click(row, column)

# Click by text
await message.click(text='👍')

# Click by data
await message.click(data=b'payload')
client

Returns the TelegramClient that patched this message. This will only be present if you use the friendly methods, it won’t be there if you invoke raw API methods manually, in which case you should only access members, not properties.

contact

The MessageMediaContact in this message, if it’s a contact.

delete(*args, **kwargs)

Deletes the message. You’re responsible for checking whether you have the permission to do so, or to except the error otherwise. Shorthand for telethon.client.messages.MessageMethods.delete_messages with entity and message_ids already set.

If you need to delete more than one message at once, don’t use this delete method. Use a telethon.client.telegramclient.TelegramClient instance directly.

document

The Document media in this message, if any.

download_media(*args, **kwargs)

Downloads the media contained in the message, if any. Shorthand for telethon.client.downloads.DownloadMethods.download_media with the message already set.

edit(*args, **kwargs)

Edits the message iff it’s outgoing. Shorthand for telethon.client.messages.MessageMethods.edit_message with both entity and message already set.

Returns None if the message was incoming, or the edited Message otherwise.

Note

This is different from client.edit_message and will respect the previous state of the message. For example, if the message didn’t have a link preview, the edit won’t add one by default, and you should force it by setting it to True if you want it.

This is generally the most desired and convenient behaviour, and will work for link previews and message buttons.

file

Returns a File wrapping the photo or document in this message. If the media type is different (polls, games, none, etc.), this property will be None.

This instance lets you easily access other properties, such as file.id, file.name, etc., without having to manually inspect the document.attributes.

forward

The Forward information if this message is a forwarded message.

forward_to(*args, **kwargs)

Forwards the message. Shorthand for telethon.client.messages.MessageMethods.forward_messages with both messages and from_peer already set.

If you need to forward more than one message at once, don’t use this forward_to method. Use a telethon.client.telegramclient.TelegramClient instance directly.

game

The Game media in this message, if it’s a game.

geo

The GeoPoint media in this message, if it has a location.

get_buttons()

Returns buttons when that property fails (this is rarely needed).

get_entities_text(cls=None)

Returns a list of (markup entity, inner text) (like bold or italics).

The markup entity is a MessageEntity that represents bold, italics, etc., and the inner text is the str inside that markup entity.

For example:

print(repr(message.text))  # shows: 'Hello **world**!'

for ent, txt in message.get_entities_text():
    print(ent)  # shows: MessageEntityBold(offset=6, length=5)
    print(txt)  # shows: world
Args:
cls (type):

Returns entities matching this type only. For example, the following will print the text for all code entities:

>>> from telethon.tl.types import MessageEntityCode
>>>
>>> m = ...  # get the message
>>> for _, inner_text in m.get_entities_text(MessageEntityCode):
>>>     print(inner_text)
get_reply_message()

The Message that this message is replying to, or None.

The result will be cached after its first use.

gif

The Document media in this message, if it’s a “gif”.

“Gif” files by Telegram are normally .mp4 video files without sound, the so called “animated” media. However, it may be the actual gif format if the file is too large.

invoice

The MessageMediaInvoice in this message, if it’s an invoice.

is_reply

True if the message is a reply to some other message.

Remember that you can access the ID of the message this one is replying to through reply_to_msg_id, and the Message object with get_reply_message().

mark_read()

Marks the message as read. Shorthand for client.send_read_acknowledge() with both entity and message already set.

photo

The Photo media in this message, if any.

This will also return the photo for MessageService if its action is MessageActionChatEditPhoto, or if the message has a web preview with a photo.

pin(*, notify=False)

Pins the message. Shorthand for telethon.client.messages.MessageMethods.pin_message with both entity and message already set.

poll

The MessageMediaPoll in this message, if it’s a poll.

raw_text

The raw message text, ignoring any formatting. Will be None for MessageService.

Setting a value to this field will erase the entities, unlike changing the message member.

reply(*args, **kwargs)

Replies to the message (as a reply). Shorthand for telethon.client.messages.MessageMethods.send_message with both entity and reply_to already set.

respond(*args, **kwargs)

Responds to the message (not as a reply). Shorthand for telethon.client.messages.MessageMethods.send_message with entity already set.

sticker

The Document media in this message, if it’s a sticker.

text

The message text, formatted using the client’s default parse mode. Will be None for MessageService.

venue

The MessageMediaVenue in this message, if it’s a venue.

via_bot

The bot User if the message was sent via said bot.

This will only be present if via_bot_id is not None and the entity is known.

via_input_bot

Returns the input variant of via_bot.

video

The Document media in this message, if it’s a video.

video_note

The Document media in this message, if it’s a video note.

voice

The Document media in this message, if it’s a voice note.

web_preview

The WebPage media in this message, if any.

MessageButton

class telethon.tl.custom.messagebutton.MessageButton(client, original, chat, bot, msg_id)

Bases: object

Note

Message.buttons are instances of this type. If you want to define a reply markup for e.g. sending messages, refer to Button instead.

Custom class that encapsulates a message button providing an abstraction to easily access some commonly needed features (such as clicking the button itself).

Attributes:

button (KeyboardButton):
The original KeyboardButton object.
__dict__ = mappingproxy({'__module__': 'telethon.tl.custom.messagebutton', '__doc__': '\n .. note::\n\n `Message.buttons <telethon.tl.custom.message.Message.buttons>`\n are instances of this type. If you want to **define** a reply\n markup for e.g. sending messages, refer to `Button\n <telethon.tl.custom.button.Button>` instead.\n\n Custom class that encapsulates a message button providing\n an abstraction to easily access some commonly needed features\n (such as clicking the button itself).\n\n Attributes:\n\n button (:tl:`KeyboardButton`):\n The original :tl:`KeyboardButton` object.\n ', '__init__': <function MessageButton.__init__>, 'client': <property object>, 'text': <property object>, 'data': <property object>, 'inline_query': <property object>, 'url': <property object>, 'click': <function MessageButton.click>, '__dict__': <attribute '__dict__' of 'MessageButton' objects>, '__weakref__': <attribute '__weakref__' of 'MessageButton' objects>})
__weakref__

list of weak references to the object (if defined)

click()

Emulates the behaviour of clicking this button.

If it’s a normal KeyboardButton with text, a message will be sent, and the sent Message returned.

If it’s an inline KeyboardButtonCallback with text and data, it will be “clicked” and the BotCallbackAnswer returned.

If it’s an inline KeyboardButtonSwitchInline button, the StartBotRequest will be invoked and the resulting updates returned.

If it’s a KeyboardButtonUrl, the URL of the button will be passed to webbrowser.open and return True on success.

client

Returns the telethon.client.telegramclient.TelegramClient instance that created this instance.

data

The bytes data for KeyboardButtonCallback objects.

inline_query

The query str for KeyboardButtonSwitchInline objects.

text

The text string of the button.

url

The url str for KeyboardButtonUrl objects.

SenderGetter

class telethon.tl.custom.sendergetter.SenderGetter(sender_id=None, *, sender=None, input_sender=None)

Bases: abc.ABC

Helper base class that introduces the sender, input_sender and sender_id properties and get_sender and get_input_sender methods.

__dict__ = mappingproxy({'__module__': 'telethon.tl.custom.sendergetter', '__doc__': '\n Helper base class that introduces the `sender`, `input_sender`\n and `sender_id` properties and `get_sender` and `get_input_sender`\n methods.\n ', '__init__': <function SenderGetter.__init__>, 'sender': <property object>, 'get_sender': <function SenderGetter.get_sender>, 'input_sender': <property object>, 'get_input_sender': <function SenderGetter.get_input_sender>, 'sender_id': <property object>, '_refetch_sender': <function SenderGetter._refetch_sender>, '__dict__': <attribute '__dict__' of 'SenderGetter' objects>, '__weakref__': <attribute '__weakref__' of 'SenderGetter' objects>, '__abstractmethods__': frozenset(), '_abc_impl': <_abc_data object>})
__weakref__

list of weak references to the object (if defined)

get_input_sender()

Returns input_sender, but will make an API call to find the input sender unless it’s already cached.

get_sender()

Returns sender, but will make an API call to find the sender unless it’s already cached.

If you only need the ID, use sender_id instead.

If you need to call a method which needs this sender, use get_input_sender() instead.

input_sender

This InputPeer is the input version of the user/channel who sent the message. Similarly to input_chat, this doesn’t have things like username or similar, but still useful in some cases.

Note that this might not be available if the library can’t find the input chat, or if the message a broadcast on a channel.

sender

Returns the User or Channel that sent this object. It may be None if Telegram didn’t send the sender.

If you only need the ID, use sender_id instead.

If you need to call a method which needs this chat, use input_sender instead.

If you’re using telethon.events, use get_sender() instead.

sender_id

Returns the marked sender integer ID, if present.

If there is a sender in the object, sender_id will always be set, which is why you should use it instead of sender.id.