# 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.

Contents

- Custom package

  - AdminLogEvent

  - Button

  - ChatGetter

  - Conversation

  - Dialog

  - Draft

  - File

  - Forward

  - InlineBuilder

  - InlineResult

  - InlineResults

  - Message

  - MessageButton

  - ParticipantPermissions

  - QRLogin

  - SenderGetter

## 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`.

  __str__()

    Return str(self).

  __weakref__

    list of weak references to the object (if defined)

  property action

    The original ChannelAdminLogEventAction.

  property changed_about

    Whether the channel’s about was changed or not.

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

  property changed_admin

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

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

  property changed_call_settings

    Whether the group call settings were changed or not.

    If `True`, `new` will be `True` if new users are muted on join.

  property changed_default_banned_rights

    Whether the default banned rights were changed or not.

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

  property 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`.

  property changed_history_ttl

    Whether the Time To Live of the message history has changed.

    Messages sent after this change will have a `ttl_period` in seconds indicating how long they should live for before being auto-deleted.

    If `True`, `old` will be the old TTL, and `new` the new TTL, in seconds.

  property changed_invites

    Whether the invites in the channel were toggled or not.

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

  property changed_location

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

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

  property changed_message

    Whether a message in this channel was edited or not.

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

  property changed_photo

    Whether the channel’s photo was changed or not.

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

  property changed_pin

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

    If `True`, `new` will be present as `Message`.

  property changed_restrictions

    Whether a message in this channel was edited or not.

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

  property changed_signatures

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

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

  property changed_sticker_set

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

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

  property changed_title

    Whether the channel’s title was changed or not.

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

  property changed_user_volume

    Whether a participant’s volume in a call has been changed.

    If `True`, `new` will be the updated GroupCallParticipant.

  property changed_username

    Whether the channel’s username was changed or not.

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

  property date

    The date when this event occurred.

  property deleted_exported_invite

    Whether the exported chat invite has been deleted.

    If `True`, `old` will be the deleted ExportedChatInvite.

  property deleted_message

    Whether a message in this channel was deleted or not.

    If `True`, `old` will be present as `Message`.

  property discarded_group_call

    Whether a group call was started or not.

    If `True`, `old` will be present as InputGroupCall.

  property edited_exported_invite

    Whether the exported chat invite has been edited.

    If `True`, `old` and `new` will be the old and new ExportedChatInvite, respectively.

  property id

    The ID of this event.

  property joined

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

  property joined_by_invite

    Whether a new participant has joined with the use of an invite link.

    If `True`, `old` will be pre-existing (old) ExportedChatInvite used to join.

  property joined_invite

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

    If `True`, `new` will be present as ChannelParticipant.

  property left

    Whether `user` left the channel or not.

  property new

    The new value present in the event.

  property old

    The old value from the event.

  property revoked_exported_invite

    Whether the exported chat invite has been revoked.

    If `True`, `old` will be the revoked ExportedChatInvite.

  property started_group_call

    Whether a group call was started or not.

    If `True`, `new` will be present as InputGroupCall.

  property stopped_poll

    Whether a poll was stopped or not.

    If `True`, `new` will be present as `Message`.

  stringify()
  property user_id

    The ID of the user that triggered this event.

  property user_muted

    Whether a participant was muted in the ongoing group call or not.

    If `True`, `new` will be present as GroupCallParticipant.

  property user_unmutted

    Whether a participant was unmuted from the ongoing group call or not.

    If `True`, `new` will be present as GroupCallParticipant.

## 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`, `url`, `auth`, `buy` and `game` together to create inline buttons (under the message).

  You can use `text`, `request_location`, `request_phone` and `request_poll` together to create a reply markup (replaces the user keyboard). You can also configure the aspect of the reply with these. The latest message with a reply markup will be the one shown to the user (messages contain the buttons, not the chat itself).

  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.

  __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.

    When the user clicks this button, a confirmation box will be shown to the user asking whether they want to login to the specified domain.

  static buy(text)

    Creates a new inline button to buy a product.

    This can only be used when sending files of type InputMediaInvoice, and must be the first button.

    If the button is not specified, Telegram will automatically add the button to the message. See the Payments API documentation for more information.

  static clear(selective=None)

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

    `selective` is as documented in `text`.

  static force_reply(single_use=None, selective=None, placeholder=None)

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

    `single_use` and `selective` are as documented in `text`.

    Args:
      placeholder (str):

        text to show the user at typing place of message.

        If the placeholder is too long, Telegram applications will crop the text (for example, to 64 characters and adding an ellipsis (…) character as the 65th).

  static game(text)

    Creates a new inline button to start playing a game.

    This should be used when sending files of type InputMediaGame, and must be the first button.

    See the Games documentation for more information on using games.

  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. If you need to store more than 64 bytes, consider saving the real data in a database and a reference to that data inside the button.

    When the user clicks this button, `events.CallbackQuery` will trigger with the same data that the button contained, so that you can determine which button was pressed.

  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`.

    When the user clicks this button, a confirmation box will be shown to the user asking whether they want to share their location with the bot, and if confirmed a message with geo media will be sent.

  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`.

    When the user clicks this button, a confirmation box will be shown to the user asking whether they want to share their phone with the bot, and if confirmed a message with contact media will be sent.

  classmethod request_poll(text, *, force_quiz=False, resize=None, single_use=None, selective=None)

    Creates a new keyboard button to request the user to create a poll.

    If `force_quiz` is `False`, the user will be allowed to choose whether they want their poll to be a quiz or not. Otherwise, the user will be forced to create a quiz when creating the poll.

    If a poll is a quiz, there will be only one answer that is valid, and the votes cannot be retracted. Otherwise, users can vote and retract the vote, and the pol might be multiple choice.

    `resize`, `single_use` and `selective` are documented in `text`.

    When the user clicks this button, a screen letting the user create a poll will be shown, and if they do create one, the poll will be sent.

  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.

    When the user clicks this button, after a chat is selected, their input field will be filled with the username of your bot followed by the query text, ready to make inline queries.

  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.

    When the user clicks this button, a text message with the same text as the button will be sent, and can be handled with `events.NewMessage`. You cannot distinguish between a button press and the user typing and sending exactly the same text on their own.

  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.

    When the user clicks this button, a confirmation box will be shown to the user asking whether they want to open the displayed URL unless the domain is trusted, and once confirmed the URL will open in their device.

## 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.

  __annotations__ = {}
  __weakref__

    list of weak references to the object (if defined)

  property 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.

  property chat_id

    Returns the marked chat integer ID. Note that this value will be different from `peer_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`.

  async 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.

  async get_input_chat()

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

  property 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.

  property is_channel

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

  property 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`).

  property 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.

  async __aenter__()
  async __aexit__(exc_type, exc_val, exc_tb)
  __annotations__ = {}
  __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.

  async 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. This is the method you need most of the time, along with `get_edit`.

    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.

        async with client.conversation(...) as conv:
            await conv.send_message('Hey, what is your name?')

            response = await conv.get_response()
            name = response.text

            await conv.send_message('Nice to meet you, {}!'.format(name))

  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.

  async wait_event(event, *, timeout=None)

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

    Note

    Only use this if there isn’t another method available! For example, don’t use `wait_event` for new messages, since `get_response` already exists, etc.

    Unless you’re certain that your code will run fast enough, generally you should get a “handle” of this special coroutine before acting. In this example you will see how to wait for a user to join a group with proper use of `wait_event`:

        from telethon import TelegramClient, events

        client = TelegramClient(...)
        group_id = ...

        async def main():
            # Could also get the user id from an event; this is just an example
            user_id = ...

            async with client.conversation(user_id) as conv:
                # Get a handle to the future event we'll wait for
                handle = conv.wait_event(events.ChatAction(
                    group_id,
                    func=lambda e: e.user_joined and e.user_id == user_id
                ))

                # Perform whatever action in between
                await conv.send_message('Please join this group before speaking to me!')

                # Wait for the event we registered above to fire
                event = await handle

                # Continue with the conversation
                await conv.send_message('Thanks!')

    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.

  __str__()

    Return str(self).

  __weakref__

    list of weak references to the object (if defined)

  async 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)

  async 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.

  async 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.

  __str__()

    Return str(self).

  __weakref__

    list of weak references to the object (if defined)

  async delete()

    Deletes this draft, and returns `True` on success.

  property entity

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

  async get_entity()

    Returns `entity` but will make an API call if necessary.

  async get_input_entity()

    Returns `input_entity` but will make an API call if necessary.

  property input_entity

    Input version of the entity.

  property is_empty

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

  property raw_text

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

  async 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)`.

  async 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()
  property 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.

  __weakref__

    list of weak references to the object (if defined)

  property duration

    The duration in seconds of the audio or video.

  property emoji

    A string with all emoji that represent the current sticker.

  property 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.

  property height

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

  property id

    The bot-API style `file_id` representing this file.

    Note

    This file ID may not work under user accounts, but should still be usable by bot accounts.

    You can, however, still use it to identify a file in for example a database.

  property mime_type

    The mime-type of this file.

  property name

    The file name of this document.

  property performer

    The performer of the song.

  property size

    The size in bytes of this file.

    For photos, this is the heaviest thumbnail, as it often repressents the largest dimensions.

  property sticker_set

    The InputStickerSet to which the sticker file belongs.

  property title

    The title of the song.

  property 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.

  __annotations__ = {}

## 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.

  __weakref__

    list of weak references to the object (if defined)

  async 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.

    Example:

          results = [
              # Option with title and description sending a message.
              builder.article(
                  title='First option',
                  description='This is the first option',
                  text='Text sent after clicking this option',
              ),
              # Option with title URL to be opened when clicked.
              builder.article(
                  title='Second option',
                  url='https://example.com',
                  text='Text sent if the user clicks the option and not the URL',
              ),
              # Sending a message with buttons.
              # You can use a list or a list of lists to include more buttons.
              builder.article(
                  title='Third option',
                  text='Text sent with buttons below',
                  buttons=Button.url('https://example.com'),
              ),
          ]

  async 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, include_media=True)

    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: article, audio, contact, file, geo, gif, photo, sticker, venue, video, voice. It will be automatically set if `mime_type` is specified, and default to `'file'` if no matching mime type is found. you may need to pass `attributes` in order to use `type` effectively.

      attributes (`list`, optional):

        Optional attributes that override the inferred ones, like DocumentAttributeFilename and so on.

      include_media (`bool`, optional):

        Whether the document file used to display the result should be included in the message itself or not. By default, the document is included, and the text parameter alters the caption.

    Example:

          results = [
              # Sending just the file when the user selects it.
              builder.document('/path/to/file.pdf'),

              # Including a caption with some in-memory file.
              file_bytesio = ...
              builder.document(
                  file_bytesio,
                  text='This will be the caption of the sent file',
              ),

              # Sending just the message without including the file.
              builder.document(
                  photo,
                  text='This will be a normal text message',
                  include_media=False,
              ),
          ]

  async 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.

  async photo(file, *, id=None, include_media=True, 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:
      include_media (`bool`, optional):

        Whether the photo file used to display the result should be included in the message itself or not. By default, the photo is included, and the text parameter alters the caption.

      file (`obj`, optional):

        Same as `file` for `client.send_file()`.

    Example:

          results = [
              # Sending just the photo when the user selects it.
              builder.photo('/path/to/photo.jpg'),

              # Including a caption with some in-memory photo.
              photo_bytesio = ...
              builder.photo(
                  photo_bytesio,
                  text='This will be the caption of the sent photo',
              ),

              # Sending just the message without including the photo.
              builder.photo(
                  photo,
                  text='This will be a normal text message',
                  include_media=False,
              ),
          ]

## InlineResult

class telethon.tl.custom.inlineresult.InlineResult(client, original, query_id=None, *, entity=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'
  __weakref__

    list of weak references to the object (if defined)

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

    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.

      comment_to (`int` | `Message`, optional):

        Similar to `reply_to`, but replies in the linked group of a broadcast channel instead (effectively leaving a “comment to” the specified 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).

      background (`bool`, optional):

        Whether the message should be send in background.

  property description

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

  property document

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

  async 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`.

  property message

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

  property photo

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

  property title

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

  property 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.

  property 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, *, entity=None)

  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.

  __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: int, peer_id: Optional[Union[telethon.tl.types.PeerUser, telethon.tl.types.PeerChat, telethon.tl.types.PeerChannel]] = None, date: Optional[datetime.datetime] = None, out: Optional[bool] = None, mentioned: Optional[bool] = None, media_unread: Optional[bool] = None, silent: Optional[bool] = None, post: Optional[bool] = None, from_id: Optional[Union[telethon.tl.types.PeerUser, telethon.tl.types.PeerChat, telethon.tl.types.PeerChannel]] = None, reply_to: Optional[telethon.tl.types.MessageReplyHeader] = None, ttl_period: Optional[int] = None, message: Optional[str] = None, fwd_from: Optional[telethon.tl.types.MessageFwdHeader] = None, via_bot_id: Optional[int] = None, media: Optional[Union[telethon.tl.types.MessageMediaEmpty, telethon.tl.types.MessageMediaPhoto, telethon.tl.types.MessageMediaGeo, telethon.tl.types.MessageMediaContact, telethon.tl.types.MessageMediaUnsupported, telethon.tl.types.MessageMediaDocument, telethon.tl.types.MessageMediaWebPage, telethon.tl.types.MessageMediaVenue, telethon.tl.types.MessageMediaGame, telethon.tl.types.MessageMediaInvoice, telethon.tl.types.MessageMediaGeoLive, telethon.tl.types.MessageMediaPoll, telethon.tl.types.MessageMediaDice]] = None, reply_markup: Optional[Union[telethon.tl.types.ReplyKeyboardHide, telethon.tl.types.ReplyKeyboardForceReply, telethon.tl.types.ReplyKeyboardMarkup, telethon.tl.types.ReplyInlineMarkup]] = None, entities: Optional[List[Union[telethon.tl.types.MessageEntityUnknown, telethon.tl.types.MessageEntityMention, telethon.tl.types.MessageEntityHashtag, telethon.tl.types.MessageEntityBotCommand, telethon.tl.types.MessageEntityUrl, telethon.tl.types.MessageEntityEmail, telethon.tl.types.MessageEntityBold, telethon.tl.types.MessageEntityItalic, telethon.tl.types.MessageEntityCode, telethon.tl.types.MessageEntityPre, telethon.tl.types.MessageEntityTextUrl, telethon.tl.types.MessageEntityMentionName, telethon.tl.types.InputMessageEntityMentionName, telethon.tl.types.MessageEntityPhone, telethon.tl.types.MessageEntityCashtag, telethon.tl.types.MessageEntityUnderline, telethon.tl.types.MessageEntityStrike, telethon.tl.types.MessageEntityBlockquote, telethon.tl.types.MessageEntityBankCard]]] = None, views: Optional[int] = None, edit_date: Optional[datetime.datetime] = None, post_author: Optional[str] = None, grouped_id: Optional[int] = None, from_scheduled: Optional[bool] = None, legacy: Optional[bool] = None, edit_hide: Optional[bool] = None, pinned: Optional[bool] = None, restriction_reason: Optional[telethon.tl.types.RestrictionReason] = None, forwards: Optional[int] = None, replies: Optional[telethon.tl.types.MessageReplies] = None, action: Optional[Union[telethon.tl.types.MessageActionEmpty, telethon.tl.types.MessageActionChatCreate, telethon.tl.types.MessageActionChatEditTitle, telethon.tl.types.MessageActionChatEditPhoto, telethon.tl.types.MessageActionChatDeletePhoto, telethon.tl.types.MessageActionChatAddUser, telethon.tl.types.MessageActionChatDeleteUser, telethon.tl.types.MessageActionChatJoinedByLink, telethon.tl.types.MessageActionChannelCreate, telethon.tl.types.MessageActionChatMigrateTo, telethon.tl.types.MessageActionChannelMigrateFrom, telethon.tl.types.MessageActionPinMessage, telethon.tl.types.MessageActionHistoryClear, telethon.tl.types.MessageActionGameScore, telethon.tl.types.MessageActionPaymentSentMe, telethon.tl.types.MessageActionPaymentSent, telethon.tl.types.MessageActionPhoneCall, telethon.tl.types.MessageActionScreenshotTaken, telethon.tl.types.MessageActionCustomAction, telethon.tl.types.MessageActionBotAllowed, telethon.tl.types.MessageActionSecureValuesSentMe, telethon.tl.types.MessageActionSecureValuesSent, telethon.tl.types.MessageActionContactSignUp, telethon.tl.types.MessageActionGeoProximityReached, telethon.tl.types.MessageActionGroupCall, telethon.tl.types.MessageActionInviteToGroupCall, telethon.tl.types.MessageActionSetMessagesTTL, telethon.tl.types.MessageActionGroupCallScheduled, telethon.tl.types.MessageActionSetChatTheme]] = None)

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

  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:
    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 previously-scheduled message or not.

    legacy (`bool`):

      Whether this is a legacy message or not.

    edit_hide (`bool`):

      Whether the edited mark of this message is edited should be hidden (e.g. in GUI clients) or shown.

    pinned (`bool`):

      Whether this message is currently pinned or not.

    id (`int`):

      The ID of this message. This field is always present. Any other member is optional and may be `None`.

    from_id (Peer):

      The peer who sent this message, which is either PeerUser, PeerChat or PeerChannel. This value will be `None` for anonymous messages.

    peer_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.

    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”).

    reply_to (MessageReplyHeader):

      The original reply header if this message is replying to another.

    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.

    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.

    forwards (`int`):

      The number of times this message has been forwarded.

    replies (`int`):

      The number of times another message has replied to this message.

    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.

    restriction_reason (List[RestrictionReason])

      An optional list of reasons why this message was restricted. If the list is `None`, this message has not been restricted.

    ttl_period (`int`):

      The Time To Live period configured for this message. The message should be erased from wherever it’s stored (memory, a local database, etc.) when `datetime.now() > message.date + timedelta(seconds=message.ttl_period)`.

    action (MessageAction):

      The message action object of the message for MessageService instances, which will be `None` for other types of messages.

  __annotations__ = {}
  property 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.

  property audio

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

  property button_count

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

  property buttons

    Returns a list of lists of `MessageButton`, if any.

    Otherwise, it returns `None`.

  async click(i=None, j=None, *, text=None, filter=None, data=None, share_phone=None, share_geo=None, password=None)

    Calls SendVote with the specified poll option or `button.click` on the specified button.

    Does nothing if the message is not a poll or has no buttons.

    Args:
      i (`int` | `list`):

        Clicks the i’th button or poll option (starting from the index 0). For multiple-choice polls, a list with the indices should be used. 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 or poll option with the text “text”. This may also be a callable, like a `re.compile(...).match`, and the text will be passed to it.

        If you need to select multiple options in a poll, pass a list of indices to the `i` parameter.

      filter (`callable`):

        Clicks the first button or poll option for which the callable returns `True`. The callable should accept a single `MessageButton` or `PollAnswer` argument.

        If you need to select multiple options in a poll, pass a list of indices to the `i` parameter.

      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`.

      share_phone (`bool` | `str` | tl:`InputMediaContact`):

        When clicking on a keyboard button requesting a phone number (KeyboardButtonRequestPhone), this argument must be explicitly set to avoid accidentally sharing the number.

        It can be `True` to automatically share the current user’s phone, a string to share a specific phone number, or a contact media to specify all details.

        If the button is pressed without this, `ValueError` is raised.

      share_geo (`tuple` | `list` | tl:`InputMediaGeoPoint`):

        When clicking on a keyboard button requesting a geo location (KeyboardButtonRequestGeoLocation), this argument must be explicitly set to avoid accidentally sharing the location.

        It must be a `tuple` of `float` as `(longitude, latitude)`, or a InputGeoPoint instance to avoid accidentally using the wrong roder.

        If the button is pressed without this, `ValueError` is raised.

      password (`str`):

        When clicking certain buttons (such as BotFather’s confirmation button to transfer ownership), if your account has 2FA enabled, you need to provide your account’s password. Otherwise, `teltehon.errors.PasswordHashInvalidError` is raised.

      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')

      >     # Click on a button requesting a phone
      >     await message.click(0, share_phone=True)

  property 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.

  property contact

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

  async 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.

  property dice

    The MessageMediaDice in this message, if it’s a dice roll.

  property document

    The Document media in this message, if any.

  async 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.

  async 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.

  property 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`.

  property forward

    The `Forward` information if this message is a forwarded message.

  async 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.

  property game

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

  property geo

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

  async 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)

  async get_reply_message()

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

    The result will be cached after its first use.

  property 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.

  property invoice

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

  property 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.reply_to_msg_id`, and the `Message` object with `get_reply_message()`.

  async mark_read()

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

  property 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.

  async pin(*, notify=False, pm_oneside=False)

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

  property poll

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

  property 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.

  async 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.

  property reply_to_msg_id

    Returns the message ID this message is replying to, if any. This is equivalent to accessing `.reply_to.reply_to_msg_id`.

  async respond(*args, **kwargs)

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

  property sticker

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

  property text

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

  property to_id

    Returns the peer to which this message was sent to. This used to exist to infer the `.peer_id`.

  async unpin()

    Unpins the message. Shorthand for `telethon.client.messages.MessageMethods.unpin_message` with both `entity` and `message` already set.

  property venue

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

  property 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.

  property via_input_bot

    Returns the input variant of `via_bot`.

  property video

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

  property video_note

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

  property voice

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

  property 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.

  __weakref__

    list of weak references to the object (if defined)

  async click(share_phone=None, share_geo=None, *, password=None)

    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.

    If it’s a KeyboardButtonRequestPhone, you must indicate that you want to `share_phone=True` in order to share it. Sharing it is not a default because it is a privacy concern and could happen accidentally.

    You may also use `share_phone=phone` to share a specific number, in which case either `str` or InputMediaContact should be used.

    If it’s a KeyboardButtonRequestGeoLocation, you must pass a tuple in `share_geo=(longitude, latitude)`. Note that Telegram seems to have some heuristics to determine impossible locations, so changing this value a lot quickly may not work as expected. You may also pass a InputGeoPoint if you find the order confusing.

  property client

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

  property data

    The `bytes` data for KeyboardButtonCallback objects.

  property inline_query

    The query `str` for KeyboardButtonSwitchInline objects.

  property text

    The text string of the button.

  property url

    The url `str` for KeyboardButtonUrl objects.

## ParticipantPermissions

class telethon.tl.custom.participantpermissions.ParticipantPermissions(participant, chat: bool)

  Bases: `object`

  Participant permissions information.

  The properties in this objects are boolean values indicating whether the user has the permission or not.

  Example

        permissions = ...

        if permissions.is_banned:
            "this user is banned"
        elif permissions.is_admin:
            "this user is an administrator"

  __weakref__

    list of weak references to the object (if defined)

  property add_admins

    Whether the administrator can add new administrators with the same or less permissions than them.

  property anonymous

    Whether the administrator will remain anonymous when sending messages.

  property ban_users

    Whether the administrator can ban other users or not.

  property change_info

    Whether the administrator can change the information about the chat, such as title or description.

  property delete_messages

    Whether the administrator can delete messages from other participants.

  property edit_messages

    Whether the administrator can edit messages.

  property has_default_permissions

    Whether the user is a normal user of the chat (not administrator, but not banned either, and has no restrictions applied).

  property has_left

    Whether the user left the chat.

  property invite_users

    Whether the administrator can add new users to the chat.

  property is_admin

    Whether the user is an administrator of the chat or not. The creator also counts as begin an administrator, since they have all permissions.

  property is_banned

    Whether the user is banned in the chat.

  property is_creator

    Whether the user is the creator of the chat or not.

  property manage_call

    Whether the user will be able to manage group calls.

  property pin_messages

    Whether the administrator can pin messages or not.

  property post_messages

    Whether the administrator can post messages in the broadcast channel.

## QRLogin

class telethon.tl.custom.qrlogin.QRLogin(client, ignored_ids)

  Bases: `object`

  QR login information.

  Most of the time, you will present the `url` as a QR code to the user, and while it’s being shown, call `wait`.

  __weakref__

    list of weak references to the object (if defined)

  property expires: datetime.datetime

    The `datetime` at which the QR code will expire.

    If you want to try again, you will need to call `recreate`.

  async recreate()

    Generates a new token and URL for a new QR code, useful if the code has expired before it was imported.

  property token: bytes

    The binary data representing the token.

    It can be used by a previously-authorized client in a call to auth.importLoginToken to log the client that originally requested the QR login.

  property url: str

    The `tg://login` URI with the token. When opened by a Telegram application where the user is logged in, it will import the login token.

    If you want to display a QR code to the user, this is the URL that should be launched when the QR code is scanned (the URL that should be contained in the QR code image you generate).

    Whether you generate the QR code image or not is up to you, and the library can’t do this for you due to the vast ways of generating and displaying the QR code that exist.

    The URL simply consists of `token` base64-encoded.

  async wait(timeout: Optional[float] = None)

    Waits for the token to be imported by a previously-authorized client, either by scanning the QR, launching the URL directly, or calling the import method.

    This method must be called before the QR code is scanned, and must be executing while the QR code is being scanned. Otherwise, the login will not complete.

    Will raise `asyncio.TimeoutError` if the login doesn’t complete on time.

    Arguments
      timeout (float):

        The timeout, in seconds, to wait before giving up. By default the library will wait until the token expires, which is often what you want.

    Returns

      On success, an instance of User. On failure it will raise.

## 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.

  __annotations__ = {}
  __weakref__

    list of weak references to the object (if defined)

  async get_input_sender()

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

  async 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.

  property 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.

  property 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.

  property 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`.