from .Functionals import *

class Update:
    '''
    This object represents an incoming update.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.update_id : int = kwargs["update_id"]

        Okwargs = OptionalKwargs(kwargs)
        self.message : Message = Message(**CleanObject(Okwargs["message"]))
        self.edited_message : Message = Message(**CleanObject(Okwargs["edited_message"]))
        self.channel_post : Message = Message(**CleanObject(Okwargs["channel_post"]))
        self.edited_channel_post : Message = Message(**CleanObject(Okwargs["edited_channel_post"]))
        self.inline_query : InlineQuery = InlineQuery(**CleanObject(Okwargs["inline_query"]))
        self.chosen_inline_result : ChosenInlineResult = ChosenInlineResult(**CleanObject(Okwargs["chosen_inline_result"]))
        self.callback_query : CallbackQuery = CallbackQuery(**CleanObject(Okwargs["callback_query"]))
        self.shipping_query : ShippingQuery = ShippingQuery(**CleanObject(Okwargs["shipping_query"]))
        self.pre_checkout_query : PreCheckoutQuery = PreCheckoutQuery(**CleanObject(Okwargs["pre_checkout_query"]))
        self.poll : Poll = Poll(**CleanObject(Okwargs["poll"]))
        self.poll_answer : PollAnswer = PollAnswer(**CleanObject(Okwargs["poll_answer"]))
        self.my_chat_member : ChatMemberUpdated = ChatMemberUpdated(**CleanObject(Okwargs["my_chat_member"]))
        self.chat_member : ChatMemberUpdated = ChatMemberUpdated(**CleanObject(Okwargs["chat_member"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.Update object @{hex(id(self))} update_id={self.update_id}>"

class WebhookInfo:
    '''
    Contains information about the current status of a webhook.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.url : str = kwargs["url"]
        self.has_custom_certificate : bool = kwargs["has_custom_certificate"]
        self.pending_update_count : int = kwargs["pending_update_count"]

        Okwargs = OptionalKwargs(kwargs)
        self.ip_address : str = Okwargs["ip_address"]
        self.last_error_date : int = Okwargs["last_error_date"]
        self.last_error_message : str = Okwargs["last_error_message"]
        self.max_connections : int = Okwargs["max_connections"]
        self.allowed_updates : List[str] = Okwargs["allowed_updates"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.WebhookInfo object @{hex(id(self))} url={self.url}>"

class User:
    '''
    This object represents a Telegram user or bot.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.id : int = kwargs["id"]
        self.is_bot : bool = kwargs["is_bot"]
        self.first_name : str = kwargs["first_name"]

        Okwargs = OptionalKwargs(kwargs)
        self.last_name : str = Okwargs["last_name"]
        self.username : str = Okwargs["username"]
        self.language_code : str = Okwargs["language_code"]
        self.can_join_groups : bool = Okwargs["can_join_groups"]
        self.can_read_all_group_messages : bool = Okwargs["can_read_all_group_messages"]
        self.supports_inline_queries : bool = Okwargs["supports_inline_queries"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.User object @{hex(id(self))} id={self.id} first_name={self.first_name}>"

class Chat:
    '''
    This object represents a chat.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.id : int = kwargs["id"]
        self.type : str = kwargs["type"]

        Okwargs = OptionalKwargs(kwargs)
        self.title : str = Okwargs["title"]
        self.username : str = Okwargs["username"]
        self.first_name : str = Okwargs["first_name"]
        self.last_name : str = Okwargs["last_name"]
        self.photo : ChatPhoto = ChatPhoto(**CleanObject(Okwargs["photo"]))
        self.bio : str = Okwargs["bio"]
        self.description : str = Okwargs["description"]
        self.invite_link : str = Okwargs["invite_link"]
        self.pinned_message : ChatPermissions = ChatPermissions(**CleanObject(Okwargs["pinned_message"]))
        self.permissions : int = Okwargs["permissions"]
        self.slow_mode_delay : int = Okwargs["slow_mode_delay"]
        self.message_auto_delete_time : int = Okwargs["message_auto_delete_time"]
        self.sticker_set_name : str = Okwargs["sticker_set_name"]
        self.can_set_sticker_set : bool = Okwargs["can_set_sticker_set"]
        self.linked_chat_id : int = Okwargs["linked_chat_id"]
        self.location : ChatLocation = ChatLocation(**CleanObject(Okwargs["location"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.Chat object @{hex(id(self))} id={self.id} type={self.type}>"

class Message:
    '''
    This object represents a message.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return

        self.message_id : int = kwargs["message_id"]
        self.date : int = kwargs["date"]

        Okwargs = OptionalKwargs(kwargs)
        self.From : User = User(**CleanObject(Okwargs["from"]))
        self.sender_chat : Chat = Chat(**CleanObject(Okwargs["sender_chat"]))
        self.chat : Chat = Chat(**CleanObject(Okwargs["chat"]))
        self.forward_from : User = User(**CleanObject(Okwargs["forward_from"]))
        self.forward_from_chat : Chat = Chat(**CleanObject(Okwargs["forward_from_chat"]))
        self.forward_from_message_id : int = Okwargs["forward_from_message_id"]
        self.forward_signature : str = Okwargs["forward_signature"]
        self.forward_sender_name : str = Okwargs["forward_sender_name"]
        self.forward_date : int = Okwargs["forward_date"]
        self.reply_to_message : Message = Message(**CleanObject(Okwargs["reply_to_message"]))
        self.via_bot : User = User(**CleanObject(Okwargs["via_bot"]))
        self.edit_date : int = Okwargs["edit_date"]
        self.media_group_id : str = Okwargs["media_group_id"]
        self.author_signature : str = Okwargs["author_signature"]
        self.text : str = Okwargs["text"]
        self.entities : MessageEntity = [MessageEntity(**entity) for entity in CleanObject(Okwargs["entities"])]
        self.animation : Animation = Animation(**CleanObject(Okwargs["animation"]))
        self.audio : Audio = Audio(**CleanObject(Okwargs["audio"]))
        self.document : Document = Document(**CleanObject(Okwargs["document"]))
        self.photo : PhotoSize = [PhotoSize(**photo) for photo in CleanObject(Okwargs["photo"])]
        self.sticker : Sticker = Sticker(**CleanObject(Okwargs["sticker"]))
        self.video : Video = Video(**CleanObject(Okwargs["video"]))
        self.video_note : VideoNote = VideoNote(**CleanObject(Okwargs["video_note"]))
        self.voice : Voice = Voice(**CleanObject(Okwargs["voice"]))
        self.caption : str = Okwargs["caption"]
        self.caption_entities: MessageEntity = [MessageEntity(**entity) for entity in CleanObject(Okwargs["caption_entities"])]
        self.contact : Contact = Contact(**CleanObject(Okwargs["contact"]))
        self.dice : Dice = Dice(**CleanObject(Okwargs["dice"]))
        self.game : Game = Game(**CleanObject(Okwargs["game"]))
        self.poll : Poll = Poll(**CleanObject(Okwargs["poll"]))
        self.venue : Venue = Venue(**CleanObject(Okwargs["venue"]))
        self.location : Location = Location(**CleanObject(Okwargs["location"]))
        self.new_chat_members : User = [User(**user) for user in CleanObject(Okwargs["new_chat_members"])]
        self.left_chat_member : User = User(**CleanObject(Okwargs["left_chat_member"]))
        self.new_chat_title : str = Okwargs["new_chat_title"]
        self.new_chat_photo : PhotoSize = [PhotoSize(**photo) for photo in CleanObject(Okwargs["new_chat_photo"])]
        self.delete_chat_photo : bool = Okwargs["delete_chat_photo"]
        self.group_chat_created : bool = Okwargs["group_chat_created"]
        self.supergroup_chat_created : bool = Okwargs["supergroup_chat_created"]
        self.channel_chat_created : bool = Okwargs["channel_chat_created"]
        self.message_auto_delete_timer_changed : MessageAutoDeleteTimerChanged = MessageAutoDeleteTimerChanged(**CleanObject(Okwargs["message_auto_delete_timer_changed"]))
        self.migrate_to_chat_id : int = Okwargs["migrate_to_chat_id"]
        self.migrate_from_chat_id : int = Okwargs["migrate_from_chat_id"]
        self.pinned_message : Message = Message(**CleanObject(Okwargs["pinned_message"]))
        self.invoice : Invoice = Okwargs["invoice"]
        self.successful_payment : SuccessfulPayment = SuccessfulPayment(**CleanObject(Okwargs["successful_payment"]))
        self.connected_website : str = Okwargs["connected_website"]
        self.passport_data : PassportData = PassportData(**CleanObject(Okwargs["passport_data"]))
        self.proximity_alert_triggered : ProximityAlertTriggered = ProximityAlertTriggered(**CleanObject(Okwargs["proximity_alert_triggered"]))
        self.voice_chat_scheduled : VoiceChatScheduled = VoiceChatScheduled(**CleanObject(Okwargs["voice_chat_scheduled"]))
        self.voice_chat_started : VoiceChatStarted = VoiceChatStarted(**CleanObject(Okwargs["voice_chat_started"]))
        self.voice_chat_ended : VoiceChatEnded = VoiceChatEnded(**CleanObject(Okwargs["voice_chat_ended"]))
        self.voice_chat_participants_invited : VoiceChatParticipantsInvited = VoiceChatParticipantsInvited(**CleanObject(Okwargs["voice_chat_participants_invited"]))
        self.reply_markup : 	InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.Message object @{hex(id(self))} message_id={self.message_id} date={self.date}>"

class MessageId:
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.message_id : str = kwargs["message_id"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.MessageId object @{hex(id(self))} message_id={self.message_id}>"

class MessageEntity:
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.offset : int = kwargs["offset"]
        self.length : int = kwargs["length"]

        Okwargs = OptionalKwargs(kwargs)
        self.url : str = Okwargs["url"]
        self.user : User = User(**CleanObject(Okwargs["user"]))
        self.language : str = Okwargs["language"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.MessageEntity object @{hex(id(self))} type={self.type} offset={self.offset} length={self.length}>"

class PhotoSize:
    '''
    This object represents one size of a photo or a file / sticker thumbnail.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.file_id : str = kwargs["file_id"]
        self.file_unique_id : str = kwargs["file_unique_id"]
        self.width : int = kwargs["width"]
        self.height : int = kwargs["height"]

        Okwargs = OptionalKwargs(kwargs)
        self.file_size : int = Okwargs["file_size"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.MessageEntity object @{hex(id(self))} file_id={self.file_id} file_unique_id={self.file_unique_id} width={self.width} height={self.height}>"

class Animation:
    '''
    This object represents an animation file (GIF or H.264/MPEG-4 AVC video without sound).
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.file_id : str = kwargs["file_id"]
        self.file_unique_id : str = kwargs["file_unique_id"]
        self.width : int = kwargs["width"]
        self.height : int = kwargs["height"]
        self.duration : int = kwargs["duration"]

        Okwargs = OptionalKwargs(kwargs)
        self.thumb : PhotoSize = PhotoSize(**CleanObject(Okwargs["thumb"]))
        self.file_name : str = Okwargs["file_name"]
        self.mime_type : str = Okwargs["mime_type"]
        self.file_size : int = Okwargs["file_size"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.Animation object @{hex(id(self))} file_id={self.file_id} file_unique_id={self.file_unique_id} width={self.width} height={self.height} duration={self.duration}>"

class Audio:
    '''
    This object represents an audio file to be treated as music by the Telegram clients.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.file_id : str = kwargs["file_id"]
        self.file_unique_id : str = kwargs["file_unique_id"]
        self.duration : int = kwargs["duration"]

        Okwargs = OptionalKwargs(kwargs)
        self.performer : str = Okwargs["performer"]
        self.title : str = Okwargs["title"]
        self.file_name : str = Okwargs["file_name"]
        self.mime_type : str = Okwargs["mime_type"]
        self.file_size : int = Okwargs["file_size"]
        self.thumb : PhotoSize = PhotoSize(**CleanObject(Okwargs["thumb"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.Audio object @{hex(id(self))} file_id={self.file_id} file_unique_id={self.file_unique_id} duration={self.duration}>"

class Document:
    '''
    This object represents a general file (as opposed to photos, voice messages and audio files).
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.file_id : str = kwargs["file_id"]
        self.file_unique_id : str = kwargs["file_unique_id"]

        Okwargs = OptionalKwargs(kwargs)
        self.thumb : PhotoSize = PhotoSize(**CleanObject(Okwargs["thumb"]))
        self.file_name : str = Okwargs["file_name"]
        self.mime_type : str = Okwargs["mime_type"]
        self.file_size : int = Okwargs["file_size"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.Document object @{hex(id(self))} file_id={self.file_id} file_unique_id={self.file_unique_id}>"

class Video:
    '''
    This object represents a video file.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.file_id : str = kwargs["file_id"]
        self.file_unique_id : str = kwargs["file_unique_id"]
        self.width : int = kwargs["width"]
        self.height : int = kwargs["height"]
        self.duration : int = kwargs["duration"]

        Okwargs = OptionalKwargs(kwargs)
        self.thumb : PhotoSize = PhotoSize(**CleanObject(Okwargs["thumb"]))
        self.file_name : str = Okwargs["file_name"]
        self.mime_type : str = Okwargs["mime_type"]
        self.file_size : int = Okwargs["file_size"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.Video object @{hex(id(self))} file_id={self.file_id} file_unique_id={self.file_unique_id} width={self.width} height={self.height} duration={self.duration}>"

class VideoNote:
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.file_id : str = kwargs["file_id"]
        self.file_unique_id : str = kwargs["file_unique_id"]
        self.length : int = kwargs["length"]
        self.duration : int = kwargs["duration"]

        Okwargs = OptionalKwargs(kwargs)
        self.thumb : PhotoSize = PhotoSize(**CleanObject(Okwargs["thumb"]))
        self.file_size : int = Okwargs["file_size"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.VideoNote object @{hex(id(self))} file_id={self.file_id} file_unique_id={self.file_unique_id} length={self.length} duration={self.duration}>"

class Voice:
    '''
    This object represents a voice note.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.file_id : str = kwargs["file_id"]
        self.file_unique_id : str = kwargs["file_unique_id"]
        self.duration : int = kwargs["duration"]

        Okwargs = OptionalKwargs(kwargs)
        self.mime_type : str = Okwargs["mime_type"]
        self.file_size : int = Okwargs["file_size"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.Voice object @{hex(id(self))} file_id={self.file_id} file_unique_id={self.file_unique_id} duration={self.duration}>"

class Contact:
    '''
    This object represents a phone contact.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.phone_number : str = kwargs["phone_number"]
        self.first_name : str = kwargs["first_name"]

        Okwargs = OptionalKwargs(kwargs)
        self.last_name : str = Okwargs["last_name"]
        self.user_id : int = Okwargs["user_id"]
        self.vcard : str = Okwargs["vcard"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.Contact object @{hex(id(self))} phone_number={self.phone_number} first_name={self.first_name}>"

class Dice:
    '''
    This object represents an animated emoji that displays a random value.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.emoji : str = kwargs["emoji"]
        self.value : int = kwargs["value"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.Dice object @{hex(id(self))} emoji={self.emoji} value={self.value}>"

class PollOption:
    '''
    This object contains information about one answer option in a poll.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.text : str = kwargs["text"]
        self.voter_count : int = kwargs["voter_count"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.PollOption object @{hex(id(self))} text={self.text} voter_count={self.voter_count}>"

class PollAnswer:
    '''
    This object represents an answer of a user in a non-anonymous poll.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.poll_id : str = kwargs["poll_id"]
        self.user : User = User(**CleanObject(kwargs["user"]))
        self.option_ids : int = kwargs["option_ids"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.PollAnswer object @{hex(id(self))} poll_id={self.poll_id} user={self.user} option_ids={self.option_ids}>"

class Poll:
    '''
    This object contains information about a poll.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.id : str = kwargs["id"]
        self.question : str = kwargs["question"]
        self.options : List[PollOption] = [PollOption(**option) for option in CleanObject(Okwargs["options"])]
        self.total_voter_count : int = kwargs["total_voter_count"]
        self.is_closed : bool = kwargs["is_closed"]
        self.is_anonymous : bool = kwargs["is_anonymous"]
        self.type : str = kwargs["type"]
        self.allows_multiple_answers : bool = kwargs["allows_multiple_answers"]

        Okwargs = OptionalKwargs(kwargs)
        self.correct_option_id : int = Okwargs["correct_option_id"]
        self.explanation : str = Okwargs["explanation"]
        self.explanation_entities : List[MessageEntity] = [MessageEntity(**messageentity) for messageentity in CleanObject(Okwargs["explanation_entities"])]
        self.open_period : int = Okwargs["open_period"]
        self.close_date : int = Okwargs["close_date"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.Poll object @{hex(id(self))} id={self.id} question={self.question} total_voter_count={self.total_voter_count} is_closed={self.is_closed} is_anonymous={self.is_anonymous} type={self.type} allows_multiple_answers={self.allows_multiple_answers}>"

class Location:
    '''
    This object represents a point on the map.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.longitude : float = kwargs["longitude"]
        self.latitude : float = kwargs["latitude"]

        Okwargs = OptionalKwargs(kwargs)
        self.horizontal_accuracy : float = Okwargs["horizontal_accuracy"]
        self.live_period : int = Okwargs["live_period"]
        self.heading : int = Okwargs["heading"]
        self.proximity_alert_radius : int = Okwargs["proximity_alert_radius"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.Location object @{hex(id(self))} longitude={self.longitude} latitude={self.latitude}>"

class Venue:
    '''
    This object represents a venue.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.location : Location = Location(**CleanObject(kwargs["location"]))
        self.title : str = kwargs["title"]
        self.address : str = kwargs["address"]

        Okwargs = OptionalKwargs(kwargs)
        self.foursquare_id : str = Okwargs["foursquare_id"]
        self.foursquare_type : str = Okwargs["foursquare_type"]
        self.google_place_id : str = Okwargs["google_place_id"]
        self.google_place_type : str = Okwargs["google_place_type"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.Venue object @{hex(id(self))} title={self.title} address={self.address}>"

class ProximityAlertTriggered:
    '''
    This object represents the content of a service message, sent whenever a user in the chat triggers a proximity alert set by another user.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.traveler : User = User(**CleanObject(kwargs["traveler"]))
        self.watcher : User = User(**CleanObject(kwargs["watcher"]))
        self.distance : int = kwargs["distance"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.ProximityAlertTriggered object @{hex(id(self))} distance={self.distance}>"

class MessageAutoDeleteTimerChanged:
    '''
    This object represents a service message about a change in auto-delete timer settings.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.message_auto_delete_time : int = kwargs["message_auto_delete_time"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.MessageAutoDeleteTimerChanged object @{hex(id(self))} message_auto_delete_time={self.message_auto_delete_time}>"

class VoiceChatScheduled:
    '''
    This object represents a service message about a voice chat scheduled in the chat.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.start_date : int = kwargs["start_date"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.VoiceChatScheduled object @{hex(id(self))} start_date={self.start_date}>"

class VoiceChatStarted:
    '''
    This object represents a service message about a voice chat started in the chat. Currently holds no information.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        pass

    def __repr__(self):
        return f"<Telpy.extension.Objects.VoiceChatStarted object @{hex(id(self))}"

class VoiceChatEnded:
    '''
    This object represents a service message about a voice chat ended in the chat.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.duration : int = kwargs["duration"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.VoiceChatEnded object @{hex(id(self))} duration={self.duration}>"

class VoiceChatParticipantsInvited:
    '''
    This object represents a service message about new members invited to a voice chat.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return

        Okwargs = OptionalKwargs(kwargs)
        self.users : List[User] = [User(**user) for user in CleanObject(Okwargs["users"])]

    def __repr__(self):
        return f"<Telpy.extension.Objects.VoiceChatParticipantsInvited object @{hex(id(self))}>"

class UserProfilePhotos:
    '''
    This object represent a user's profile pictures.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.total_count : int = kwargs["total_count"]
        self.photos : List[List[PhotoSize]] = [[PhotoSize(**CleanObject(obj)) for obj in row] for row in Okwargs["photos"]]

    def __repr__(self):
        return f"<Telpy.extension.Objects.UserProfilePhotos object @{hex(id(self))} total_count={self.total_count}>"

class File:
    '''
    This object represents a file ready to be downloaded. It is guaranteed that the url_link will be valid for at least 1 hour. When the link expires, a new one can be requested by calling get_file.
    Maximum file size to download is 20 MB
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.file_id : str = kwargs["file_id"]
        self.file_unique_id : str = kwargs["file_unique_id"]

        Okwargs = OptionalKwargs(kwargs)
        self.file_size : int = Okwargs["file_size"]
        self.file_path : str = Okwargs["file_path"]

        # Special
        self.url_link = f"https://api.telegram.org/file/bot{token}/{self.file_path}"

    def __repr__(self):
        return f"<Telpy.extension.Objects.File object @{hex(id(self))} url_link={self.url_link} file_id={self.file_id} file_unique_id={self.file_unique_id}>"

class ReplyKeyboardMarkup:
    '''
    This object represents a custom keyboard with reply options (see Introduction to bots for details and examples).
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.keyboard : List[List[KeyboardButton]] = [[KeyboardButton(**CleanObject(obj)) for obj in row] for row in Okwargs["keyboard"]]

        Okwargs = OptionalKwargs(kwargs)
        self.resize_keyboard : bool = Okwargs["resize_keyboard"]
        self.one_time_keyboard : bool = Okwargs["one_time_keyboard"]
        self.input_field_placeholder : str = Okwargs["input_field_placeholder"]
        self.selective : bool = Okwargs["selective"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.ReplyKeyboardMarkup object @{hex(id(self))}>"

class KeyboardButton:
    '''
    This object represents one button of the reply keyboard. For simple text buttons String can be used instead of this object to specify text of the button. Optional fields request_contact, request_location, and request_poll are mutually exclusive.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.text : str = kwargs["text"]

        Okwargs = OptionalKwargs(kwargs)
        self.request_contact : bool = Okwargs["request_contact"]
        self.request_location : bool = Okwargs["request_location"]
        self.request_poll : KeyboardButtonPollType = Okwargs["request_poll"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.KeyboardButton object @{hex(id(self))} text={self.text}>"

class KeyboardButtonPollType:
    '''
    This object represents type of a poll, which is allowed to be created and sent when the corresponding button is pressed.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return

        Okwargs = OptionalKwargs(kwargs)
        self.type : str = Okwargs["type"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.KeyboardButtonPollType object @{hex(id(self))}>"

class ReplyKeyboardRemove:
    '''
    Upon receiving a message with this object, Telegram clients will remove the current custom keyboard and display the default letter-keyboard. By default, custom keyboards are displayed until a new keyboard is sent by a bot. An exception is made for one-time keyboards that are hidden immediately after the user presses a button (see ReplyKeyboardMarkup).
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.remove_keyboard : bool = kwargs["remove_keyboard"]

        Okwargs = OptionalKwargs(kwargs)
        self.selective : bool = Okwargs["selective"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.ReplyKeyboardRemove object @{hex(id(self))} remove_keyboard={self.remove_keyboard}>"

class InlineKeyboardMarkup:
    '''
    This object represents an inline keyboard that appears right next to the message it belongs to.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.inline_keyboard : List[List[InlineKeyboardButton]] = [[InlineKeyboardButton(**CleanObject(obj)) for obj in row] for row in Okwargs["inline_keyboard"]]

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineKeyboardMarkup object @{hex(id(self))}>"

class InlineKeyboardButton:
    '''
    This object represents one button of an inline keyboard. You must use exactly one of the optional fields.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.text : str = kwargs["text"]

        Okwargs = OptionalKwargs(kwargs)
        self.url : str = Okwargs["url"]
        self.login_url : LoginUrl = Okwargs["login_url"]
        self.callback_data : str = Okwargs["callback_data"]
        self.switch_inline_query : str = Okwargs["switch_inline_query"]
        self.switch_inline_query_current_chat : str = Okwargs["switch_inline_query_current_chat"]
        self.callback_game : CallbackGame = Okwargs["callback_game"]
        self.pay : bool = Okwargs["pay"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineKeyboardButton object @{hex(id(self))} text={self.text}>"
class LoginUrl:
    '''
    This object represents a parameter of the inline keyboard button used to automatically authorize a user. Serves as a great replacement for the Telegram Login Widget when the user is coming from Telegram. All the user needs to do is tap/click a button and confirm that they want to log in:
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.url : str = kwargs["url"]

        Okwargs = OptionalKwargs(kwargs)
        self.forward_text : str = Okwargs["forward_text"]
        self.bot_username : str = Okwargs["bot_username"]
        self.request_write_access : bool = Okwargs["request_write_access"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.LoginUrl object @{hex(id(self))} url={self.url}>"

class CallbackQuery:
    '''
    This object represents an incoming callback query from a callback button in an inline keyboard. If the button that originated the query was attached to a message sent by the bot, the field message will be present. If the button was attached to a message sent via the bot (in inline mode), the field inline_message_id will be present. Exactly one of the fields data or game_short_name will be present.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.id : str = kwargs["id"]
        self._from : User = User(**CleanObject(kwargs["from"]))
        self.chat_instance : str = kwargs["chat_instance"]

        Okwargs = OptionalKwargs(kwargs)
        self.message : Message = Message(**CleanObject(Okwargs["message"]))
        self.inline_message_id : str = Okwargs["inline_message_id"]
        self.data : str = Okwargs["data"]
        self.game_short_name : str = Okwargs["game_short_name"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.CallbackQuery object @{hex(id(self))} id={self.id} chat_instance={self.chat_instance}>"

class ForceReply:
    '''
    Upon receiving a message with this object, Telegram clients will display a reply interface to the user (act as if the user has selected the bot's message and tapped 'Reply'). This can be extremely useful if you want to create user-friendly step-by-step interfaces without having to sacrifice privacy mode.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.force_reply : bool = kwargs["force_reply"]

        Okwargs = OptionalKwargs(kwargs)
        self.input_field_placeholder : str = Okwargs["input_field_placeholder"]
        self.selective : bool = Okwargs["selective"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.ForceReply object @{hex(id(self))} force_reply={self.force_reply}>"

class ChatPhoto:
    '''
    This object represents a chat photo.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.small_file_id : str = kwargs["small_file_id"]
        self.small_file_unique_id : str = kwargs["small_file_unique_id"]
        self.big_file_id : str = kwargs["big_file_id"]
        self.big_file_unique_id : str = kwargs["big_file_unique_id"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.ChatPhoto object @{hex(id(self))} small_file_id={self.small_file_id} small_file_unique_id={self.small_file_unique_id} big_file_id={self.big_file_id} big_file_unique_id={self.big_file_unique_id}>"

class ChatInviteLink:
    '''
    Represents an invite link for a chat.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.invite_link : str = kwargs["invite_link"]
        self.creator : User = User(**CleanObject(kwargs["creator"]))
        self.creates_join_request : bool = kwargs["creates_join_request"]
        self.is_primary : bool = kwargs["is_primary"]
        self.is_revoked : bool = kwargs["is_revoked"]

        Okwargs = OptionalKwargs(kwargs)
        self.name : str = Okwargs["name"]
        self.expire_date : int = Okwargs["expire_date"]
        self.member_limit : int = Okwargs["member_limit"]
        self.pending_join_request_count : int = Okwargs["pending_join_request_count"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.ChatInviteLink object @{hex(id(self))} invite_link={self.invite_link} creates_join_request={self.creates_join_request} is_primary={self.is_primary} is_revoked={self.is_revoked}>"

class ChatMemberOwner:
    '''
    Represents a chat member that owns the chat and has all administrator privileges.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.status : str = kwargs["status"]
        self.user : User = User(**CleanObject(kwargs["user"]))
        self.is_anonymous : bool = kwargs["is_anonymous"]

        Okwargs = OptionalKwargs(kwargs)
        self.custom_title : str = Okwargs["custom_title"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.ChatMemberOwner object @{hex(id(self))} status={self.status} is_anonymous={self.is_anonymous}>"

class ChatMemberAdministrator:
    '''
    Represents a chat member that has some additional privileges.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.status : str = kwargs["status"]
        self.user : User = User(**CleanObject(kwargs["user"]))
        self.can_be_edited : bool = kwargs["can_be_edited"]
        self.is_anonymous : bool = kwargs["is_anonymous"]
        self.can_manage_chat : bool = kwargs["can_manage_chat"]
        self.can_delete_messages : bool = kwargs["can_delete_messages"]
        self.can_manage_voice_chats : bool = kwargs["can_manage_voice_chats"]
        self.can_restrict_members : bool = kwargs["can_restrict_members"]
        self.can_promote_members : bool = kwargs["can_promote_members"]
        self.can_change_info : bool = kwargs["can_change_info"]
        self.can_invite_users : bool = kwargs["can_invite_users"]

        Okwargs = OptionalKwargs(kwargs)
        self.can_post_messages : bool = Okwargs["can_post_messages"]
        self.can_edit_messages : bool = Okwargs["can_edit_messages"]
        self.can_pin_messages : bool = Okwargs["can_pin_messages"]
        self.custom_title : str = Okwargs["custom_title"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.ChatMemberAdministrator object @{hex(id(self))} status={self.status} can_be_edited={self.can_be_edited} is_anonymous={self.is_anonymous} can_manage_chat={self.can_manage_chat} can_delete_messages={self.can_delete_messages} can_manage_voice_chats={self.can_manage_voice_chats} can_restrict_members={self.can_restrict_members} can_promote_members={self.can_promote_members} can_change_info={self.can_change_info} can_invite_users={self.can_invite_users}>"

class ChatMemberMember:
    '''
    Represents a chat member that has no additional privileges or restrictions.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.status : str = kwargs["status"]
        self.user : User = User(**CleanObject(kwargs["user"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.ChatMemberMember object @{hex(id(self))} status={self.status}>"

class ChatMemberRestricted:
    '''
    Represents a chat member that is under certain restrictions in the chat. Supergroups only.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.status : str = kwargs["status"]
        self.user : User = User(**CleanObject(kwargs["user"]))
        self.is_member : bool = kwargs["is_member"]
        self.can_change_info : bool = kwargs["can_change_info"]
        self.can_invite_users : bool = kwargs["can_invite_users"]
        self.can_pin_messages : bool = kwargs["can_pin_messages"]
        self.can_send_messages : bool = kwargs["can_send_messages"]
        self.can_send_media_messages : bool = kwargs["can_send_media_messages"]
        self.can_send_polls : bool = kwargs["can_send_polls"]
        self.can_send_other_messages : bool = kwargs["can_send_other_messages"]
        self.can_add_web_page_previews : bool = kwargs["can_add_web_page_previews"]
        self.until_date : int = kwargs["until_date"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.ChatMemberRestricted object @{hex(id(self))} status={self.status} is_member={self.is_member} can_change_info={self.can_change_info} can_invite_users={self.can_invite_users} can_pin_messages={self.can_pin_messages} can_send_messages={self.can_send_messages} can_send_media_messages={self.can_send_media_messages} can_send_polls={self.can_send_polls} can_send_other_messages={self.can_send_other_messages} can_add_web_page_previews={self.can_add_web_page_previews} until_date={self.until_date}>"

class ChatMemberLeft:
    '''
    Represents a chat member that isn't currently a member of the chat, but may join it themselves.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.status : str = kwargs["status"]
        self.user : User = User(**CleanObject(kwargs["user"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.ChatMemberLeft object @{hex(id(self))} status={self.status}>"

class ChatMemberBanned:
    '''
    Represents a chat member that was banned in the chat and can't return to the chat or view chat messages.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.status : str = kwargs["status"]
        self.user : User = User(**CleanObject(kwargs["user"]))
        self.until_date : int = kwargs["until_date"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.ChatMemberBanned object @{hex(id(self))} status={self.status} until_date={self.until_date}>"

class ChatMemberUpdated:
    '''
    This object represents changes in the status of a chat member.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.chat : Chat = kwargs["chat"]
        self._from : User = User(**CleanObject(kwargs["from"]))
        self.date : int = kwargs["date"]
        self.old_chat_member : ChatMember = kwargs["old_chat_member"]
        self.new_chat_member : ChatMember = kwargs["new_chat_member"]

        Okwargs = OptionalKwargs(kwargs)
        self.invite_link : ChatInviteLink = Okwargs["invite_link"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.ChatMemberUpdated object @{hex(id(self))} date={self.date}>"

class ChatJoinRequest:
    '''
    Represents a join request sent to a chat.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.chat : Chat = kwargs["chat"]
        self._from : User = User(**CleanObject(kwargs["from"]))
        self.date : int = kwargs["date"]

        Okwargs = OptionalKwargs(kwargs)
        self.bio : str = Okwargs["bio"]
        self.invite_link : ChatInviteLink = Okwargs["invite_link"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.ChatJoinRequest object @{hex(id(self))} date={self.date}>"

class ChatPermissions:
    '''
    Describes actions that a non-administrator user is allowed to take in a chat.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return

        Okwargs = OptionalKwargs(kwargs)
        self.can_send_messages : bool = Okwargs["can_send_messages"]
        self.can_send_media_messages : bool = Okwargs["can_send_media_messages"]
        self.can_send_polls : bool = Okwargs["can_send_polls"]
        self.can_send_other_messages : bool = Okwargs["can_send_other_messages"]
        self.can_add_web_page_previews : bool = Okwargs["can_add_web_page_previews"]
        self.can_change_info : bool = Okwargs["can_change_info"]
        self.can_invite_users : bool = Okwargs["can_invite_users"]
        self.can_pin_messages : bool = Okwargs["can_pin_messages"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.ChatPermissions object @{hex(id(self))}>"

class ChatLocation:
    '''
    Represents a location to which a chat is connected.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.location : Location = kwargs["location"]
        self.address : str = kwargs["address"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.ChatLocation object @{hex(id(self))} address={self.address}>"

class BotCommand:
    '''
    This object represents a bot command.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.command : str = kwargs["command"]
        self.description : str = kwargs["description"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.BotCommand object @{hex(id(self))} command={self.command} description={self.description}>"

class BotCommandScopeDefault:
    '''
    Represents the default scope of bot commands. Default commands are used if no commands with a narrower scope are specified for the user.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.BotCommandScopeDefault object @{hex(id(self))} type={self.type}>"

class BotCommandScopeAllPrivateChats:
    '''
    Represents the scope of bot commands, covering all private chats.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.BotCommandScopeAllPrivateChats object @{hex(id(self))} type={self.type}>"

class BotCommandScopeAllGroupChats:
    '''
    Represents the scope of bot commands, covering all group and supergroup chats.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.BotCommandScopeAllGroupChats object @{hex(id(self))} type={self.type}>"

class BotCommandScopeAllChatAdministrators:
    '''
    Represents the scope of bot commands, covering all group and supergroup chat administrators.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.BotCommandScopeAllChatAdministrators object @{hex(id(self))} type={self.type}>"

class BotCommandScopeChat:
    '''
    Represents the scope of bot commands, covering a specific chat.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.chat_id : Integer or str = kwargs["chat_id"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.BotCommandScopeChat object @{hex(id(self))} type={self.type}>"

class BotCommandScopeChatAdministrators:
    '''
    Represents the scope of bot commands, covering all administrators of a specific group or supergroup chat.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.chat_id : Integer or str = kwargs["chat_id"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.BotCommandScopeChatAdministrators object @{hex(id(self))} type={self.type}>"

class BotCommandScopeChatMember:
    '''
    Represents the scope of bot commands, covering a specific member of a group or supergroup chat.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.chat_id : Integer or str = kwargs["chat_id"]
        self.user_id : int = kwargs["user_id"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.BotCommandScopeChatMember object @{hex(id(self))} type={self.type} user_id={self.user_id}>"

class ResponseParameters:
    '''
    Contains information about why a request was unsuccessful.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return

        Okwargs = OptionalKwargs(kwargs)
        self.migrate_to_chat_id : int = Okwargs["migrate_to_chat_id"]
        self.retry_after : int = Okwargs["retry_after"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.ResponseParameters object @{hex(id(self))}>"

class InputMediaPhoto:
    '''
    Represents a photo to be sent.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.media : str = kwargs["media"]

        Okwargs = OptionalKwargs(kwargs)
        self.caption : str = Okwargs["caption"]
        self.parse_mode : str = Okwargs["parse_mode"]
        self.caption_entities : List[MessageEntity] = Okwargs["caption_entities"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.InputMediaPhoto object @{hex(id(self))} type={self.type} media={self.media}>"

class InputMediaVideo:
    '''
    Represents a video to be sent.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.media : str = kwargs["media"]

        Okwargs = OptionalKwargs(kwargs)
        self.thumb : InputFile or str = Okwargs["thumb"]
        self.caption : str = Okwargs["caption"]
        self.parse_mode : str = Okwargs["parse_mode"]
        self.caption_entities : List[MessageEntity] = Okwargs["caption_entities"]
        self.width : int = Okwargs["width"]
        self.height : int = Okwargs["height"]
        self.duration : int = Okwargs["duration"]
        self.supports_streaming : bool = Okwargs["supports_streaming"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.InputMediaVideo object @{hex(id(self))} type={self.type} media={self.media}>"

class InputMediaAnimation:
    '''
    Represents an animation file (GIF or H.264/MPEG-4 AVC video without sound) to be sent.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.media : str = kwargs["media"]

        Okwargs = OptionalKwargs(kwargs)
        self.thumb : InputFile or str = Okwargs["thumb"]
        self.caption : str = Okwargs["caption"]
        self.parse_mode : str = Okwargs["parse_mode"]
        self.caption_entities : List[MessageEntity] = Okwargs["caption_entities"]
        self.width : int = Okwargs["width"]
        self.height : int = Okwargs["height"]
        self.duration : int = Okwargs["duration"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.InputMediaAnimation object @{hex(id(self))} type={self.type} media={self.media}>"

class InputMediaAudio:
    '''
    Represents an audio file to be treated as music to be sent.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.media : str = kwargs["media"]

        Okwargs = OptionalKwargs(kwargs)
        self.thumb : InputFile or str = Okwargs["thumb"]
        self.caption : str = Okwargs["caption"]
        self.parse_mode : str = Okwargs["parse_mode"]
        self.caption_entities : List[MessageEntity] = Okwargs["caption_entities"]
        self.duration : int = Okwargs["duration"]
        self.performer : str = Okwargs["performer"]
        self.title : str = Okwargs["title"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.InputMediaAudio object @{hex(id(self))} type={self.type} media={self.media}>"

class InputMediaDocument:
    '''
    Represents a general file to be sent.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.media : str = kwargs["media"]

        Okwargs = OptionalKwargs(kwargs)
        self.thumb : InputFile or str = Okwargs["thumb"]
        self.caption : str = Okwargs["caption"]
        self.parse_mode : str = Okwargs["parse_mode"]
        self.caption_entities : List[MessageEntity] = Okwargs["caption_entities"]
        self.disable_content_type_detection : bool = Okwargs["disable_content_type_detection"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.InputMediaDocument object @{hex(id(self))} type={self.type} media={self.media}>"

class InputFile:
    '''
    This object represents the contents of a file to be uploaded.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.file_id : str = kwargs["file_id"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.InputFile object @{hex(id(self))} file_id={self.file_id}>"

# Stickers
class Sticker:
    '''
    This object represents a sticker.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.file_id : str = kwargs["file_id"]
        self.file_unique_id : str = kwargs["file_unique_id"]
        self.width : int = kwargs["width"]
        self.height : int = kwargs["height"]
        self.is_animated : bool = kwargs["is_animated"]

        Okwargs = OptionalKwargs(kwargs)
        self.thumb : PhotoSize = PhotoSize(**CleanObject(Okwargs["thumb"]))
        self.emoji : str = Okwargs["emoji"]
        self.set_name : str = Okwargs["set_name"]
        self.mask_position : MaskPosition = MaskPosition(**CleanObject(Okwargs["mask_position"]))
        self.file_size : int = Okwargs["file_size"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.Sticker object @{hex(id(self))} file_id={self.file_id} file_unique_id={self.file_unique_id} width={self.width} height={self.height} is_animated={self.is_animated}>"

class StickerSet:
    '''
    This object represents a sticker set.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.name : str = kwargs["name"]
        self.title : str = kwargs["title"]
        self.is_animated : bool = kwargs["is_animated"]
        self.contains_masks : bool = kwargs["contains_masks"]
        self.stickers : List[Sticker] = [Sticker(**sticker) for sticker in CleanObject(Okwargs["stickers"])]

        Okwargs = OptionalKwargs(kwargs)
        self.thumb : PhotoSize = PhotoSize(**CleanObject(Okwargs["thumb"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.StickerSet object @{hex(id(self))} name={self.name} title={self.title} is_animated={self.is_animated} contains_masks={self.contains_masks}>"
class MaskPosition:
    '''
    This object describes the position on faces where a mask should be placed by default.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.point : str = kwargs["point"]
        self.x_shift : float = kwargs["x_shift"]
        self.y_shift : float = kwargs["y_shift"]
        self.scale : float = kwargs["scale"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.MaskPosition object @{hex(id(self))} point={self.point}>"

# Inline Query
class InlineQuery:
    '''
    This object represents an incoming inline query. When the user sends an empty query, your bot could return some default or trending results.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.id : str = kwargs["id"]
        self.From : User = User(**CleanObject(kwargs["from"]))
        self.query : str = kwargs["query"]
        self.offset : str = kwargs["offset"]

        Okwargs = OptionalKwargs(kwargs)
        self.chat_type : str = Okwargs["chat_type"]
        self.location : Location = Location(**CleanObject(Okwargs["location"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQuery object @{hex(id(self))} id={self.id} query={self.query} offset={self.offset}>"

class InlineQueryResultArticle:
    '''
    Represents a link to an article or web page.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.title : str = kwargs["title"]
        self.input_message_content : InputMessageContent = InputMessageContent(**CleanObject(kwargs["input_message_content"]))

        Okwargs = OptionalKwargs(kwargs)
        self.reply_markup : InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))
        self.url : str = Okwargs["url"]
        self.hide_url : bool = Okwargs["hide_url"]
        self.description : str = Okwargs["description"]
        self.thumb_url : str = Okwargs["thumb_url"]
        self.thumb_width : int = Okwargs["thumb_width"]
        self.thumb_height : int = Okwargs["thumb_height"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultArticle object @{hex(id(self))} type={self.type} id={self.id} title={self.title}>"

class InlineQueryResultPhoto:
    '''
    Represents a link to a photo. By default, this photo will be sent by the user with optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the photo.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.photo_url : str = kwargs["photo_url"]
        self.thumb_url : str = kwargs["thumb_url"]

        Okwargs = OptionalKwargs(kwargs)
        self.photo_width : int = Okwargs["photo_width"]
        self.photo_height : int = Okwargs["photo_height"]
        self.title : str = Okwargs["title"]
        self.description : str = Okwargs["description"]
        self.caption : str = Okwargs["caption"]
        self.parse_mode : str = Okwargs["parse_mode"]
        self.caption_entities : List[MessageEntity] = [MessageEntity(**caption_entity) for caption_entity in CleanObject(Okwargs["caption_entities"])]
        self.reply_markup : InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))
        self.input_message_content : InputMessageContent = InputMessageContent(**CleanObject(Okwargs["input_message_content"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultPhoto object @{hex(id(self))} type={self.type} id={self.id} photo_url={self.photo_url} thumb_url={self.thumb_url}>"

class InlineQueryResultGif:
    '''
    Represents a link to an animated GIF file. By default, this animated GIF file will be sent by the user with optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the animation.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.gif_url : str = kwargs["gif_url"]
        self.thumb_url : str = kwargs["thumb_url"]

        Okwargs = OptionalKwargs(kwargs)
        self.gif_width : int = Okwargs["gif_width"]
        self.gif_height : int = Okwargs["gif_height"]
        self.gif_duration : int = Okwargs["gif_duration"]
        self.thumb_mime_type : str = Okwargs["thumb_mime_type"]
        self.title : str = Okwargs["title"]
        self.caption : str = Okwargs["caption"]
        self.parse_mode : str = Okwargs["parse_mode"]
        self.caption_entities : List[MessageEntity] = [MessageEntity(**caption_entity) for caption_entity in CleanObject(Okwargs["caption_entities"])]
        self.reply_markup : InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))
        self.input_message_content : InputMessageContent = InputMessageContent(**CleanObject(Okwargs["input_message_content"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultGif object @{hex(id(self))} type={self.type} id={self.id} gif_url={self.gif_url} thumb_url={self.thumb_url}>"

class InlineQueryResultMpeg4Gif:
    '''
    Represents a link to a video animation (H.264/MPEG-4 AVC video without sound). By default, this animated MPEG-4 file will be sent by the user with optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the animation.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.mpeg4_url : str = kwargs["mpeg4_url"]
        self.thumb_url : str = kwargs["thumb_url"]

        Okwargs = OptionalKwargs(kwargs)
        self.mpeg4_width : int = Okwargs["mpeg4_width"]
        self.mpeg4_height : int = Okwargs["mpeg4_height"]
        self.mpeg4_duration : int = Okwargs["mpeg4_duration"]
        self.thumb_mime_type : str = Okwargs["thumb_mime_type"]
        self.title : str = Okwargs["title"]
        self.caption : str = Okwargs["caption"]
        self.parse_mode : str = Okwargs["parse_mode"]
        self.caption_entities : List[MessageEntity] = [MessageEntity(**caption_entity) for caption_entity in CleanObject(Okwargs["caption_entities"])]
        self.reply_markup : InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))
        self.input_message_content : InputMessageContent = InputMessageContent(**CleanObject(Okwargs["input_message_content"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultMpeg4Gif object @{hex(id(self))} type={self.type} id={self.id} mpeg4_url={self.mpeg4_url} thumb_url={self.thumb_url}>"

class InlineQueryResultVideo:
    '''
    Represents a link to a page containing an embedded video player or a video file. By default, this video file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the video.\nIf an InlineQueryResultVideo message contains an embedded video (e.g., YouTube), you must replace its content using input_message_content.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.video_url : str = kwargs["video_url"]
        self.mime_type : str = kwargs["mime_type"]
        self.thumb_url : str = kwargs["thumb_url"]
        self.title : str = kwargs["title"]

        Okwargs = OptionalKwargs(kwargs)
        self.caption : str = Okwargs["caption"]
        self.parse_mode : str = Okwargs["parse_mode"]
        self.caption_entities : List[MessageEntity] = Okwargs["caption_entities"]
        self.video_width : int = Okwargs["video_width"]
        self.video_height : int = Okwargs["video_height"]
        self.video_duration : int = Okwargs["video_duration"]
        self.description : str = Okwargs["description"]
        self.reply_markup : InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))
        self.input_message_content : InputMessageContent = InputMessageContent(**CleanObject(Okwargs["input_message_content"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultVideo object @{hex(id(self))} type={self.type} id={self.id} video_url={self.video_url} mime_type={self.mime_type} thumb_url={self.thumb_url} title={self.title}>"

class InlineQueryResultAudio:
    '''
    Represents a link to an MP3 audio file. By default, this audio file will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the audio.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.audio_url : str = kwargs["audio_url"]
        self.title : str = kwargs["title"]

        Okwargs = OptionalKwargs(kwargs)
        self.caption : str = Okwargs["caption"]
        self.parse_mode : str = Okwargs["parse_mode"]
        self.caption_entities : List[MessageEntity] = Okwargs["caption_entities"]
        self.performer : str = Okwargs["performer"]
        self.audio_duration : int = Okwargs["audio_duration"]
        self.reply_markup : InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))
        self.input_message_content : InputMessageContent = InputMessageContent(**CleanObject(Okwargs["input_message_content"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultAudio object @{hex(id(self))} type={self.type} id={self.id} audio_url={self.audio_url} title={self.title}>"

class InlineQueryResultVoice:
    '''
    Represents a link to a voice recording in an .OGG container encoded with OPUS. By default, this voice recording will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the the voice message.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.voice_url : str = kwargs["voice_url"]
        self.title : str = kwargs["title"]

        Okwargs = OptionalKwargs(kwargs)
        self.caption : str = Okwargs["caption"]
        self.parse_mode : str = Okwargs["parse_mode"]
        self.caption_entities : List[MessageEntity] = Okwargs["caption_entities"]
        self.voice_duration : int = Okwargs["voice_duration"]
        self.reply_markup : InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))
        self.input_message_content : InputMessageContent = InputMessageContent(**CleanObject(Okwargs["input_message_content"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultVoice object @{hex(id(self))} type={self.type} id={self.id} voice_url={self.voice_url} title={self.title}>"

class InlineQueryResultDocument:
    '''
    Represents a link to a file. By default, this file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the file. Currently, only .PDF and .ZIP files can be sent using this method.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.title : str = kwargs["title"]
        self.document_url : str = kwargs["document_url"]
        self.mime_type : str = kwargs["mime_type"]

        Okwargs = OptionalKwargs(kwargs)
        self.caption : str = Okwargs["caption"]
        self.parse_mode : str = Okwargs["parse_mode"]
        self.caption_entities : List[MessageEntity] = Okwargs["caption_entities"]
        self.description : str = Okwargs["description"]
        self.reply_markup : InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))
        self.input_message_content : InputMessageContent = InputMessageContent(**CleanObject(Okwargs["input_message_content"]))
        self.thumb_url : str = Okwargs["thumb_url"]
        self.thumb_width : int = Okwargs["thumb_width"]
        self.thumb_height : int = Okwargs["thumb_height"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultDocument object @{hex(id(self))} type={self.type} id={self.id} title={self.title} document_url={self.document_url} mime_type={self.mime_type}>"

class InlineQueryResultLocation:
    '''
    Represents a location on a map. By default, the location will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the location.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.latitude : float = kwargs["latitude"]
        self.longitude : float = kwargs["longitude"]
        self.title : str = kwargs["title"]

        Okwargs = OptionalKwargs(kwargs)
        self.horizontal_accuracy : float = Okwargs["horizontal_accuracy"]
        self.live_period : int = Okwargs["live_period"]
        self.heading : int = Okwargs["heading"]
        self.proximity_alert_radius : int = Okwargs["proximity_alert_radius"]
        self.reply_markup : InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))
        self.input_message_content : InputMessageContent = InputMessageContent(**CleanObject(Okwargs["input_message_content"]))
        self.thumb_url : str = Okwargs["thumb_url"]
        self.thumb_width : int = Okwargs["thumb_width"]
        self.thumb_height : int = Okwargs["thumb_height"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultLocation object @{hex(id(self))} type={self.type} id={self.id} title={self.title}>"

class InlineQueryResultVenue:
    '''
    Represents a venue. By default, the venue will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the venue.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.latitude : float = kwargs["latitude"]
        self.longitude : float = kwargs["longitude"]
        self.title : str = kwargs["title"]
        self.address : str = kwargs["address"]

        Okwargs = OptionalKwargs(kwargs)
        self.foursquare_id : str = Okwargs["foursquare_id"]
        self.foursquare_type : str = Okwargs["foursquare_type"]
        self.google_place_id : str = Okwargs["google_place_id"]
        self.google_place_type : str = Okwargs["google_place_type"]
        self.reply_markup : InlineKeyboardMarkup = Okwargs["reply_markup"]
        self.input_message_content : InputMessageContent = Okwargs["input_message_content"]
        self.thumb_url : str = Okwargs["thumb_url"]
        self.thumb_width : int = Okwargs["thumb_width"]
        self.thumb_height : int = Okwargs["thumb_height"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultVenue object @{hex(id(self))} type={self.type} id={self.id} latitude={self.latitude} longitude={self.longitude} title={self.title} address={self.address}>"

class InlineQueryResultContact:
    '''
    Represents a contact with a phone number. By default, this contact will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the contact.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.phone_number : str = kwargs["phone_number"]
        self.first_name : str = kwargs["first_name"]

        Okwargs = OptionalKwargs(kwargs)
        self.last_name : str = Okwargs["last_name"]
        self.vcard : str = Okwargs["vcard"]
        self.reply_markup : InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))
        self.input_message_content : InputMessageContent = InputMessageContent(**CleanObject(Okwargs["input_message_content"]))
        self.thumb_url : str = Okwargs["thumb_url"]
        self.thumb_width : int = Okwargs["thumb_width"]
        self.thumb_height : int = Okwargs["thumb_height"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultContact object @{hex(id(self))} type={self.type} id={self.id} phone_number={self.phone_number} first_name={self.first_name}>"

class InlineQueryResultGame:
    '''
    Represents a Game.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.game_short_name : str = kwargs["game_short_name"]

        Okwargs = OptionalKwargs(kwargs)
        self.reply_markup : InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultGame object @{hex(id(self))} type={self.type} id={self.id} game_short_name={self.game_short_name}>"

class InlineQueryResultCachedPhoto:
    '''
    Represents a link to a photo stored on the Telegram servers. By default, this photo will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the photo.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.photo_file_id : str = kwargs["photo_file_id"]

        Okwargs = OptionalKwargs(kwargs)
        self.title : str = Okwargs["title"]
        self.description : str = Okwargs["description"]
        self.caption : str = Okwargs["caption"]
        self.parse_mode : str = Okwargs["parse_mode"]
        self.caption_entities : List[MessageEntity] = [MessageEntity(**caption_entity) for caption_entity in CleanObject(Okwargs["caption_entities"])]
        self.reply_markup : InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))
        self.input_message_content : InputMessageContent = InputMessageContent(**CleanObject(Okwargs["input_message_content"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultCachedPhoto object @{hex(id(self))} type={self.type} id={self.id} photo_file_id={self.photo_file_id}>"

class InlineQueryResultCachedGif:
    '''
    Represents a link to an animated GIF file stored on the Telegram servers. By default, this animated GIF file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with specified content instead of the animation.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.gif_file_id : str = kwargs["gif_file_id"]

        Okwargs = OptionalKwargs(kwargs)
        self.title : str = Okwargs["title"]
        self.caption : str = Okwargs["caption"]
        self.parse_mode : str = Okwargs["parse_mode"]
        self.caption_entities : List[MessageEntity] = [MessageEntity(**caption_entity) for caption_entity in CleanObject(Okwargs["caption_entities"])]
        self.reply_markup : InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))
        self.input_message_content : InputMessageContent = InputMessageContent(**CleanObject(Okwargs["input_message_content"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultCachedGif object @{hex(id(self))} type={self.type} id={self.id} gif_file_id={self.gif_file_id}>"

class InlineQueryResultCachedMpeg4Gif:
    '''
    Represents a link to a video animation (H.264/MPEG-4 AVC video without sound) stored on the Telegram servers. By default, this animated MPEG-4 file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the animation.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.mpeg4_file_id : str = kwargs["mpeg4_file_id"]

        Okwargs = OptionalKwargs(kwargs)
        self.title : str = Okwargs["title"]
        self.caption : str = Okwargs["caption"]
        self.parse_mode : str = Okwargs["parse_mode"]
        self.caption_entities : List[MessageEntity] = [MessageEntity(**caption_entity) for caption_entity in CleanObject(Okwargs["caption_entities"])]
        self.reply_markup : InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))
        self.input_message_content : InputMessageContent = InputMessageContent(**CleanObject(Okwargs["input_message_content"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultCachedMpeg4Gif object @{hex(id(self))} type={self.type} id={self.id} mpeg4_file_id={self.mpeg4_file_id}>"

class InlineQueryResultCachedSticker:
    '''
    Represents a link to a sticker stored on the Telegram servers. By default, this sticker will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the sticker.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.sticker_file_id : str = kwargs["sticker_file_id"]

        Okwargs = OptionalKwargs(kwargs)
        self.reply_markup : InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))
        self.input_message_content : InputMessageContent = InputMessageContent(**CleanObject(Okwargs["input_message_content"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultCachedSticker object @{hex(id(self))} type={self.type} id={self.id} sticker_file_id={self.sticker_file_id}>"

class InlineQueryResultCachedDocument:
    '''
    Represents a link to a file stored on the Telegram servers. By default, this file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the file.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.title : str = kwargs["title"]
        self.document_file_id : str = kwargs["document_file_id"]

        Okwargs = OptionalKwargs(kwargs)
        self.description : str = Okwargs["description"]
        self.caption : str = Okwargs["caption"]
        self.parse_mode : str = Okwargs["parse_mode"]
        self.caption_entities : List[MessageEntity] = [MessageEntity(**caption_entity) for caption_entity in CleanObject(Okwargs["caption_entities"])]
        self.reply_markup : InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))
        self.input_message_content : InputMessageContent = InputMessageContent(**CleanObject(Okwargs["input_message_content"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultCachedDocument object @{hex(id(self))} type={self.type} id={self.id} title={self.title} document_file_id={self.document_file_id}>"

class InlineQueryResultCachedVideo:
    '''
    Represents a link to a video file stored on the Telegram servers. By default, this video file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the video.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.video_file_id : str = kwargs["video_file_id"]
        self.title : str = kwargs["title"]

        Okwargs = OptionalKwargs(kwargs)
        self.description : str = Okwargs["description"]
        self.caption : str = Okwargs["caption"]
        self.parse_mode : str = Okwargs["parse_mode"]
        self.caption_entities : List[MessageEntity] = [MessageEntity(**caption_entity) for caption_entity in CleanObject(Okwargs["caption_entities"])]
        self.reply_markup : InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))
        self.input_message_content : InputMessageContent = InputMessageContent(**CleanObject(Okwargs["input_message_content"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultCachedVideo object @{hex(id(self))} type={self.type} id={self.id} video_file_id={self.video_file_id} title={self.title}>"

class InlineQueryResultCachedVoice:
    '''
    Represents a link to a voice message stored on the Telegram servers. By default, this voice message will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the voice message.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.voice_file_id : str = kwargs["voice_file_id"]
        self.title : str = kwargs["title"]

        Okwargs = OptionalKwargs(kwargs)
        self.caption : str = Okwargs["caption"]
        self.parse_mode : str = Okwargs["parse_mode"]
        self.caption_entities : List[MessageEntity] = [MessageEntity(**caption_entity) for caption_entity in CleanObject(Okwargs["caption_entities"])]
        self.reply_markup : InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))
        self.input_message_content : InputMessageContent = InputMessageContent(**CleanObject(Okwargs["input_message_content"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultCachedVoice object @{hex(id(self))} type={self.type} id={self.id} voice_file_id={self.voice_file_id} title={self.title}>"

class InlineQueryResultCachedAudio:
    '''
    Represents a link to an MP3 audio file stored on the Telegram servers. By default, this audio file will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the audio.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.id : str = kwargs["id"]
        self.audio_file_id : str = kwargs["audio_file_id"]

        Okwargs = OptionalKwargs(kwargs)
        self.caption : str = Okwargs["caption"]
        self.parse_mode : str = Okwargs["parse_mode"]
        self.caption_entities : List[MessageEntity] = [MessageEntity(**caption_entity) for caption_entity in CleanObject(Okwargs["caption_entities"])]
        self.reply_markup : InlineKeyboardMarkup = InlineKeyboardMarkup(**CleanObject(Okwargs["reply_markup"]))
        self.input_message_content : InputMessageContent = InputMessageContent(**CleanObject(Okwargs["input_message_content"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.InlineQueryResultCachedAudio object @{hex(id(self))} type={self.type} id={self.id} audio_file_id={self.audio_file_id}>"

# Input Message Content

class InputTextMessageContent:
    '''
    Represents the content of a text message to be sent as the result of an inline query.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.message_text : str = kwargs["message_text"]

        Okwargs = OptionalKwargs(kwargs)
        self.parse_mode : str = Okwargs["parse_mode"]
        self.entities : List[MessageEntity] = [MessageEntity(**entity) for entity in CleanObject(Okwargs["entities"])]
        self.disable_web_page_preview : bool = Okwargs["disable_web_page_preview"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.InputTextMessageContent object @{hex(id(self))} message_text={self.message_text}>"

class InputLocationMessageContent:
    '''
    Represents the content of a location message to be sent as the result of an inline query.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.latitude : float = kwargs["latitude"]
        self.longitude : float = kwargs["longitude"]

        Okwargs = OptionalKwargs(kwargs)
        self.horizontal_accuracy : float = Okwargs["horizontal_accuracy"]
        self.live_period : int = Okwargs["live_period"]
        self.heading : int = Okwargs["heading"]
        self.proximity_alert_radius : int = Okwargs["proximity_alert_radius"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.InputLocationMessageContent object @{hex(id(self))} latitude={self.latitude} longitude={self.longitude}>"

class InputVenueMessageContent:
    '''
    Represents the content of a venue message to be sent as the result of an inline query.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.latitude : float = kwargs["latitude"]
        self.longitude : float = kwargs["longitude"]
        self.title : str = kwargs["title"]
        self.address : str = kwargs["address"]

        Okwargs = OptionalKwargs(kwargs)
        self.foursquare_id : str = Okwargs["foursquare_id"]
        self.foursquare_type : str = Okwargs["foursquare_type"]
        self.google_place_id : str = Okwargs["google_place_id"]
        self.google_place_type : str = Okwargs["google_place_type"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.InputVenueMessageContent object @{hex(id(self))} latitude={self.latitude} longitude={self.longitude} title={self.title} address={self.address}>"

class InputContactMessageContent:
    '''
    Represents the content of a contact message to be sent as the result of an inline query.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.phone_number : str = kwargs["phone_number"]
        self.first_name : str = kwargs["first_name"]

        Okwargs = OptionalKwargs(kwargs)
        self.last_name : str = Okwargs["last_name"]
        self.vcard : str = Okwargs["vcard"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.InputContactMessageContent object @{hex(id(self))} phone_number={self.phone_number} first_name={self.first_name}>"

class InputInvoiceMessageContent:
    '''
    Represents the content of an invoice message to be sent as the result of an inline query.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.title : str = kwargs["title"]
        self.description : str = kwargs["description"]
        self.payload : str = kwargs["payload"]
        self.provider_token : str = kwargs["provider_token"]
        self.currency : str = kwargs["currency"]
        self.prices : List[LabeledPrice] = [LabeledPrice(**kwargs["prices"]) for kwargs["prices"] in CleanObject(kwargs["prices"])]

        Okwargs = OptionalKwargs(kwargs)
        self.max_tip_amount : int = Okwargs["max_tip_amount"]
        self.suggested_tip_amounts : List[int] = Okwargs["suggested_tip_amounts"]
        self.provider_data : str = Okwargs["provider_data"]
        self.photo_url : str = Okwargs["photo_url"]
        self.photo_size : int = Okwargs["photo_size"]
        self.photo_width : int = Okwargs["photo_width"]
        self.photo_height : int = Okwargs["photo_height"]
        self.need_name : bool = Okwargs["need_name"]
        self.need_phone_number : bool = Okwargs["need_phone_number"]
        self.need_email : bool = Okwargs["need_email"]
        self.need_shipping_address : bool = Okwargs["need_shipping_address"]
        self.send_phone_number_to_provider : bool = Okwargs["send_phone_number_to_provider"]
        self.send_email_to_provider : bool = Okwargs["send_email_to_provider"]
        self.is_flexible : bool = Okwargs["is_flexible"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.InputInvoiceMessageContent object @{hex(id(self))} title={self.title} description={self.description} payload={self.payload} provider_token={self.provider_token} currency={self.currency}>"

class ChosenInlineResult:
    '''
    Represents a result of an inline query that was chosen by the user and sent to their chat partner.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.result_id : str = kwargs["result_id"]
        self.From : User = User(**CleanObject(kwargs["from"]))
        self.query : str = kwargs["query"]

        Okwargs = OptionalKwargs(kwargs)
        self.location : Location = Location(**CleanObject(Okwargs["location"]))
        self.inline_message_id : str = Okwargs["inline_message_id"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.ChosenInlineResult object @{hex(id(self))} result_id={self.result_id} query={self.query}>"

# Payment
class LabeledPrice:
    '''
    This object represents a portion of the price for goods or services.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.label : str = kwargs["label"]
        self.amount : int = kwargs["amount"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.LabeledPrice object @{hex(id(self))} label={self.label} amount={self.amount}>"

class Invoice:
    '''
    This object contains basic information about an invoice.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.title : str = kwargs["title"]
        self.description : str = kwargs["description"]
        self.start_parameter : str = kwargs["start_parameter"]
        self.currency : str = kwargs["currency"]
        self.total_amount : int = kwargs["total_amount"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.Invoice object @{hex(id(self))} title={self.title} description={self.description} start_parameter={self.start_parameter} currency={self.currency} total_amount={self.total_amount}>"

class ShippingAddress:
    '''
    This object represents a shipping address.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.country_code : str = kwargs["country_code"]
        self.state : str = kwargs["state"]
        self.city : str = kwargs["city"]
        self.street_line1 : str = kwargs["street_line1"]
        self.street_line2 : str = kwargs["street_line2"]
        self.post_code : str = kwargs["post_code"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.ShippingAddress object @{hex(id(self))} country_code={self.country_code} state={self.state} city={self.city} street_line1={self.street_line1} street_line2={self.street_line2} post_code={self.post_code}>"

class OrderInfo:
    '''
    This object represents information about an order.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return

        Okwargs = OptionalKwargs(kwargs)
        self.name : str = Okwargs["name"]
        self.phone_number : str = Okwargs["phone_number"]
        self.email : str = Okwargs["email"]
        self.shipping_address : ShippingAddress = ShippingAddress(**CleanObject(Okwargs["shipping_address"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.OrderInfo object @{hex(id(self))}>"

class ShippingOption:
    '''
    This object represents one shipping option.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.id : str = kwargs["id"]
        self.title : str = kwargs["title"]
        self.prices : List[LabeledPrice] = [LabeledPrice(**price) for price in CleanObject(Okwargs["prices"])]

    def __repr__(self):
        return f"<Telpy.extension.Objects.ShippingOption object @{hex(id(self))} id={self.id} title={self.title}>"

class SuccessfulPayment:
    '''
    This object contains basic information about a successful payment.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.currency : str = kwargs["currency"]
        self.total_amount : int = kwargs["total_amount"]
        self.invoice_payload : str = kwargs["invoice_payload"]
        self.telegram_payment_charge_id : str = kwargs["telegram_payment_charge_id"]
        self.provider_payment_charge_id : str = kwargs["provider_payment_charge_id"]

        Okwargs = OptionalKwargs(kwargs)
        self.shipping_option_id : str = Okwargs["shipping_option_id"]
        self.order_info : OrderInfo = OrderInfo(**CleanObject(Okwargs["order_info"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.SuccessfulPayment object @{hex(id(self))} currency={self.currency} total_amount={self.total_amount} invoice_payload={self.invoice_payload} telegram_payment_charge_id={self.telegram_payment_charge_id} provider_payment_charge_id={self.provider_payment_charge_id}>"

class ShippingQuery:
    '''
    This object contains information about an incoming shipping query.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.id : str = kwargs["id"]
        self.From : User = User(**CleanObject(kwargs["from"]))
        self.invoice_payload : str = kwargs["invoice_payload"]
        self.shipping_address : ShippingAddress = ShippingAddress(**CleanObject(kwargs["shipping_address"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.ShippingQuery object @{hex(id(self))} id={self.id} invoice_payload={self.invoice_payload}>"

class PreCheckoutQuery:
    '''
    This object contains information about an incoming pre-checkout query.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.id : str = kwargs["id"]
        self.From : User = User(**CleanObject(kwargs["from"]))
        self.currency : str = kwargs["currency"]
        self.total_amount : int = kwargs["total_amount"]
        self.invoice_payload : str = kwargs["invoice_payload"]

        Okwargs = OptionalKwargs(kwargs)
        self.shipping_option_id : str = Okwargs["shipping_option_id"]
        self.order_info : OrderInfo = OrderInfo(**CleanObject(Okwargs["order_info"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.PreCheckoutQuery object @{hex(id(self))} id={self.id} currency={self.currency} total_amount={self.total_amount} invoice_payload={self.invoice_payload}>"

# Telegram Passport
class PassportData:
    '''
    Contains information about Telegram Passport data shared with the bot by the user.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.data : List[EncryptedPassportElement] = [EncryptedPassportElement(**data) for data in CleanObject(Okwargs["data"])]
        self.credentials : EncryptedCredentials = EncryptedCredentials(**CleanObject(kwargs["credentials"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.PassportData object @{hex(id(self))}>"

class PassportFile:
    '''
    This object represents a file uploaded to Telegram Passport. Currently all Telegram Passport files are in JPEG format when decrypted and don't exceed 10MB.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.file_id : str = kwargs["file_id"]
        self.file_unique_id : str = kwargs["file_unique_id"]
        self.file_size : int = kwargs["file_size"]
        self.file_date : int = kwargs["file_date"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.PassportFile object @{hex(id(self))} file_id={self.file_id} file_unique_id={self.file_unique_id} file_size={self.file_size} file_date={self.file_date}>"

class EncryptedPassportElement:
    '''
    Contains information about documents or other Telegram Passport elements shared with the bot by the user.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.type : str = kwargs["type"]
        self.hash : str = kwargs["hash"]

        Okwargs = OptionalKwargs(kwargs)
        self.data : str = Okwargs["data"]
        self.phone_number : str = Okwargs["phone_number"]
        self.email : str = Okwargs["email"]
        self.files : List[PassportFile] = [PassportFile(**file) for file in CleanObject(Okwargs["files"])]
        self.front_side : PassportFile = PassportFile(**CleanObject(Okwargs["front_side"]))
        self.reverse_side : PassportFile = PassportFile(**CleanObject(Okwargs["reverse_side"]))
        self.selfie : PassportFile = PassportFile(**CleanObject(Okwargs["selfie"]))
        self.translation : List[PassportFile] = [PassportFile(**translation) for translation in CleanObject(Okwargs["translation"])]

    def __repr__(self):
        return f"<Telpy.extension.Objects.EncryptedPassportElement object @{hex(id(self))} type={self.type} hash={self.hash}>"

class EncryptedCredentials:
    '''
    Contains data required for decrypting and authenticating EncryptedPassportElement. See the Telegram Passport Documentation for a complete description of the data decryption and authentication processes.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.data : str = kwargs["data"]
        self.hash : str = kwargs["hash"]
        self.secret : str = kwargs["secret"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.EncryptedCredentials object @{hex(id(self))} data={self.data} hash={self.hash} secret={self.secret}>"

# Passport Element Error
class PassportElementErrorDataField:
    '''
    Represents an issue in one of the data fields that was provided by the user. The error is considered resolved when the field's value changes.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.source : str = kwargs["source"]
        self.type : str = kwargs["type"]
        self.field_name : str = kwargs["field_name"]
        self.data_hash : str = kwargs["data_hash"]
        self.message : str = kwargs["message"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.PassportElementErrorDataField object @{hex(id(self))} source={self.source} type={self.type} field_name={self.field_name} data_hash={self.data_hash} message={self.message}>"

class PassportElementErrorFrontSide:
    '''
    Represents an issue with the front side of a document. The error is considered resolved when the file with the front side of the document changes.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.source : str = kwargs["source"]
        self.type : str = kwargs["type"]
        self.file_hash : str = kwargs["file_hash"]
        self.message : str = kwargs["message"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.PassportElementErrorFrontSide object @{hex(id(self))} source={self.source} type={self.type} file_hash={self.file_hash} message={self.message}>"

class PassportElementErrorReverseSide:
    '''
    Represents an issue with the reverse side of a document. The error is considered resolved when the file with reverse side of the document changes.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.source : str = kwargs["source"]
        self.type : str = kwargs["type"]
        self.file_hash : str = kwargs["file_hash"]
        self.message : str = kwargs["message"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.PassportElementErrorReverseSide object @{hex(id(self))} source={self.source} type={self.type} file_hash={self.file_hash} message={self.message}>"

class PassportElementErrorSelfie:
    '''
    Represents an issue with the selfie with a document. The error is considered resolved when the file with the selfie changes.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.source : str = kwargs["source"]
        self.type : str = kwargs["type"]
        self.file_hash : str = kwargs["file_hash"]
        self.message : str = kwargs["message"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.PassportElementErrorSelfie object @{hex(id(self))} source={self.source} type={self.type} file_hash={self.file_hash} message={self.message}>"

class PassportElementErrorFile:
    '''
    Represents an issue with a document scan. The error is considered resolved when the file with the document scan changes.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.source : str = kwargs["source"]
        self.type : str = kwargs["type"]
        self.file_hash : str = kwargs["file_hash"]
        self.message : str = kwargs["message"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.PassportElementErrorFile object @{hex(id(self))} source={self.source} type={self.type} file_hash={self.file_hash} message={self.message}>"

class PassportElementErrorFiles:
    '''
    Represents an issue with a list of scans. The error is considered resolved when the list of files containing the scans changes.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.source : str = kwargs["source"]
        self.type : str = kwargs["type"]
        self.file_hashes : List[str] = kwargs["file_hashes"]
        self.message : str = kwargs["message"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.PassportElementErrorFiles object @{hex(id(self))} source={self.source} type={self.type} message={self.message}>"

class PassportElementErrorTranslationFile:
    '''
    Represents an issue with one of the files that constitute the translation of a document. The error is considered resolved when the file changes.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.source : str = kwargs["source"]
        self.type : str = kwargs["type"]
        self.file_hash : str = kwargs["file_hash"]
        self.message : str = kwargs["message"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.PassportElementErrorTranslationFile object @{hex(id(self))} source={self.source} type={self.type} file_hash={self.file_hash} message={self.message}>"

class PassportElementErrorTranslationFiles:
    '''
    Represents an issue with the translated version of a document. The error is considered resolved when a file with the document translation change.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.source : str = kwargs["source"]
        self.type : str = kwargs["type"]
        self.file_hashes : List[str] = kwargs["file_hashes"]
        self.message : str = kwargs["message"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.PassportElementErrorTranslationFiles object @{hex(id(self))} source={self.source} type={self.type} message={self.message}>"

class PassportElementErrorUnspecified:
    '''
    Represents an issue in an unspecified place. The error is considered resolved when new data is added.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.source : str = kwargs["source"]
        self.type : str = kwargs["type"]
        self.element_hash : str = kwargs["element_hash"]
        self.message : str = kwargs["message"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.PassportElementErrorUnspecified object @{hex(id(self))} source={self.source} type={self.type} element_hash={self.element_hash} message={self.message}>"

# Game
class Game:
    '''
    This object represents a game. Use BotFather to create and edit games, their short names will act as unique identifiers.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.title : str = kwargs["title"]
        self.description : str = kwargs["description"]
        self.photo : List[PhotoSize] = [PhotoSize(**photo) for photo in CleanObject(Okwargs["photo"])]

        Okwargs = OptionalKwargs(kwargs)
        self.text : str = Okwargs["text"]
        self.text_entities : List[MessageEntity] = [MessageEntity(**text_entity) for text_entity in CleanObject(Okwargs["text_entities"])]
        self.animation : Animation = Animation(**CleanObject(Okwargs["animation"]))

    def __repr__(self):
        return f"<Telpy.extension.Objects.Game object @{hex(id(self))} title={self.title} description={self.description}>"

class CallbackGame:
    '''
    A placeholder, currently holds no information. Use BotFather to set up your game.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        pass

    def __repr__(self):
        return f"<Telpy.extension.Objects.CallbackGame object @{hex(id(self))}"

class GameHighScore:
    '''
    This object represents one row of the high scores table for a game.
    '''
    def __init__(self, **kwargs):
        if kwargs == {}:
            return
        self.position : int = kwargs["position"]
        self.user : User = User(**CleanObject(kwargs["user"]))
        self.score : int = kwargs["score"]

    def __repr__(self):
        return f"<Telpy.extension.Objects.GameHighScore object @{hex(id(self))} position={self.position} score={self.score}>"
