Exemple #1
0
    async def delete_profile_photos(self, photo_ids: Union[str,
                                                           List[str]]) -> bool:
        """Delete your own profile photos.

        Parameters:
            photo_ids (``str`` | List of ``str``):
                A single :obj:`Photo` id as string or multiple ids as list of strings for deleting
                more than one photos at once.

        Returns:
            ``bool``: True on success.

        Example:
            .. code-block:: python

                # Get the photos to be deleted
                photos = app.get_profile_photos("me")

                # Delete one photo
                app.delete_profile_photos(photos[0].file_id)

                # Delete the rest of the photos
                app.delete_profile_photos([p.file_id for p in photos[1:]])
        """
        photo_ids = photo_ids if isinstance(photo_ids, list) else [photo_ids]
        input_photos = [
            utils.get_input_media_from_file_id(i).id for i in photo_ids
        ]

        return bool(await
                    self.send(functions.photos.DeletePhotos(id=input_photos)))
    def send_video(
        self,
        chat_id: Union[int, str],
        video: str,
        file_ref: str = None,
        caption: str = "",
        parse_mode: Union[str, None] = object,
        duration: int = 0,
        width: int = 0,
        height: int = 0,
        thumb: str = None,
        supports_streaming: bool = True,
        disable_notification: bool = None,
        reply_to_message_id: int = None,
        schedule_date: int = None,
        reply_markup: Union["pyrogram.InlineKeyboardMarkup",
                            "pyrogram.ReplyKeyboardMarkup",
                            "pyrogram.ReplyKeyboardRemove",
                            "pyrogram.ForceReply"] = None,
        progress: callable = None,
        progress_args: tuple = ()
    ) -> Union["pyrogram.Message", None]:
        """Send video files.

        Parameters:
            chat_id (``int`` | ``str``):
                Unique identifier (int) or username (str) of the target chat.
                For your personal cloud (Saved Messages) you can simply use "me" or "self".
                For a contact that exists in your Telegram address book you can use his phone number (str).

            video (``str``):
                Video to send.
                Pass a file_id as string to send a video that exists on the Telegram servers,
                pass an HTTP URL as a string for Telegram to get a video from the Internet, or
                pass a file path as string to upload a new video that exists on your local machine.

            file_ref (``str``, *optional*):
                A valid file reference obtained by a recently fetched media message.
                To be used in combination with a file id in case a file reference is needed.

            caption (``str``, *optional*):
                Video caption, 0-1024 characters.

            parse_mode (``str``, *optional*):
                By default, texts are parsed using both Markdown and HTML styles.
                You can combine both syntaxes together.
                Pass "markdown" or "md" to enable Markdown-style parsing only.
                Pass "html" to enable HTML-style parsing only.
                Pass None to completely disable style parsing.

            duration (``int``, *optional*):
                Duration of sent video in seconds.

            width (``int``, *optional*):
                Video width.

            height (``int``, *optional*):
                Video height.

            thumb (``str``, *optional*):
                Thumbnail of the video sent.
                The thumbnail should be in JPEG format and less than 200 KB in size.
                A thumbnail's width and height should not exceed 320 pixels.
                Thumbnails can't be reused and can be only uploaded as a new file.

            supports_streaming (``bool``, *optional*):
                Pass True, if the uploaded video is suitable for streaming.
                Defaults to True.

            disable_notification (``bool``, *optional*):
                Sends the message silently.
                Users will receive a notification with no sound.

            reply_to_message_id (``int``, *optional*):
                If the message is a reply, ID of the original message.

            schedule_date (``int``, *optional*):
                Date when the message will be automatically sent. Unix time.

            reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
                Additional interface options. An object for an inline keyboard, custom reply keyboard,
                instructions to remove reply keyboard or to force a reply from the user.

            progress (``callable``, *optional*):
                Pass a callback function to view the file transmission progress.
                The function must take *(current, total)* as positional arguments (look at Other Parameters below for a
                detailed description) and will be called back each time a new file chunk has been successfully
                transmitted.

            progress_args (``tuple``, *optional*):
                Extra custom arguments for the progress callback function.
                You can pass anything you need to be available in the progress callback scope; for example, a Message
                object or a Client instance in order to edit the message with the updated progress status.

        Other Parameters:
            current (``int``):
                The amount of bytes transmitted so far.

            total (``int``):
                The total size of the file.

            *args (``tuple``, *optional*):
                Extra custom arguments as defined in the *progress_args* parameter.
                You can either keep *\*args* or add every single extra argument in your function signature.

        Returns:
            :obj:`Message` | ``None``: On success, the sent video message is returned, otherwise, in case the upload
            is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned.

        Example:
            .. code-block:: python

                # Send video by uploading from local file
                app.send_video("me", "video.mp4")

                # Add caption to the video
                app.send_video("me", "video.mp4", caption="recording")

                # Keep track of the progress while uploading
                def progress(current, total):
                    print("{:.1f}%".format(current * 100 / total))

                app.send_video("me", "video.mp4", progress=progress)
        """
        file = None

        try:
            if os.path.exists(video):
                thumb = None if thumb is None else self.save_file(thumb)
                file = self.save_file(video,
                                      progress=progress,
                                      progress_args=progress_args)
                media = types.InputMediaUploadedDocument(
                    mime_type=self.guess_mime_type(video) or "video/mp4",
                    file=file,
                    thumb=thumb,
                    attributes=[
                        types.DocumentAttributeVideo(
                            supports_streaming=supports_streaming or None,
                            duration=duration,
                            w=width,
                            h=height),
                        types.DocumentAttributeFilename(
                            file_name=os.path.basename(video))
                    ])
            elif video.startswith("http"):
                media = types.InputMediaDocumentExternal(url=video)
            else:
                media = utils.get_input_media_from_file_id(video, file_ref, 4)

            while True:
                try:
                    r = self.send(
                        functions.messages.SendMedia(
                            peer=self.resolve_peer(chat_id),
                            media=media,
                            silent=disable_notification or None,
                            reply_to_msg_id=reply_to_message_id,
                            random_id=self.rnd_id(),
                            schedule_date=schedule_date,
                            reply_markup=reply_markup.write()
                            if reply_markup else None,
                            **self.parser.parse(caption, parse_mode)))
                except FilePartMissing as e:
                    self.save_file(video, file_id=file.id, file_part=e.x)
                else:
                    for i in r.updates:
                        if isinstance(i, (types.UpdateNewMessage,
                                          types.UpdateNewChannelMessage,
                                          types.UpdateNewScheduledMessage)):
                            return pyrogram.Message._parse(
                                self,
                                i.message, {i.id: i
                                            for i in r.users},
                                {i.id: i
                                 for i in r.chats},
                                is_scheduled=isinstance(
                                    i, types.UpdateNewScheduledMessage))
        except BaseClient.StopTransmission:
            return None
Exemple #3
0
    def send_media_group(
            self,
            chat_id: Union[int, str],
            media: List[Union["pyrogram.InputMediaPhoto",
                              "pyrogram.InputMediaVideo"]],
            disable_notification: bool = None,
            reply_to_message_id: int = None) -> List["pyrogram.Message"]:
        """Send a group of photos or videos as an album.

        Parameters:
            chat_id (``int`` | ``str``):
                Unique identifier (int) or username (str) of the target chat.
                For your personal cloud (Saved Messages) you can simply use "me" or "self".
                For a contact that exists in your Telegram address book you can use his phone number (str).

            media (List of :obj:`InputMediaPhoto` and :obj:`InputMediaVideo`):
                A list describing photos and videos to be sent, must include 2–10 items.

            disable_notification (``bool``, *optional*):
                Sends the message silently.
                Users will receive a notification with no sound.

            reply_to_message_id (``int``, *optional*):
                If the message is a reply, ID of the original message.

        Returns:
            List of :obj:`Message`: On success, a list of the sent messages is returned.

        Example:
            .. code-block:: python

                from pyrogram import InputMediaPhoto, InputMediaVideo

                app.send_media_group(
                    "me",
                    [
                        InputMediaPhoto("photo1.jpg"),
                        InputMediaPhoto("photo2.jpg", caption="photo caption"),
                        InputMediaVideo("video.mp4", caption="a video")
                    ]
                )
        """
        multi_media = []

        for i in media:
            if isinstance(i, pyrogram.InputMediaPhoto):
                if os.path.exists(i.media):
                    while True:
                        try:
                            media = self.send(
                                functions.messages.UploadMedia(
                                    peer=self.resolve_peer(chat_id),
                                    media=types.InputMediaUploadedPhoto(
                                        file=self.save_file(i.media))))
                        except FloodWait as e:
                            log.warning("Sleeping for {}s".format(e.x))
                            time.sleep(e.x)
                        else:
                            break

                    media = types.InputMediaPhoto(id=types.InputPhoto(
                        id=media.photo.id,
                        access_hash=media.photo.access_hash,
                        file_reference=media.photo.file_reference))
                elif i.media.startswith("http"):
                    media = self.send(
                        functions.messages.UploadMedia(
                            peer=self.resolve_peer(chat_id),
                            media=types.InputMediaPhotoExternal(url=i.media)))

                    media = types.InputMediaPhoto(id=types.InputPhoto(
                        id=media.photo.id,
                        access_hash=media.photo.access_hash,
                        file_reference=media.photo.file_reference))
                else:
                    media = utils.get_input_media_from_file_id(
                        i.media, i.file_ref, 2)
            elif isinstance(i, pyrogram.InputMediaVideo):
                if os.path.exists(i.media):
                    while True:
                        try:
                            media = self.send(
                                functions.messages.UploadMedia(
                                    peer=self.resolve_peer(chat_id),
                                    media=types.InputMediaUploadedDocument(
                                        file=self.save_file(i.media),
                                        thumb=None if i.thumb is None else
                                        self.save_file(i.thumb),
                                        mime_type=self.guess_mime_type(i.media)
                                        or "video/mp4",
                                        attributes=[
                                            types.DocumentAttributeVideo(
                                                supports_streaming=i.
                                                supports_streaming or None,
                                                duration=i.duration,
                                                w=i.width,
                                                h=i.height),
                                            types.DocumentAttributeFilename(
                                                file_name=os.path.basename(
                                                    i.media))
                                        ])))
                        except FloodWait as e:
                            log.warning("Sleeping for {}s".format(e.x))
                            time.sleep(e.x)
                        else:
                            break

                    media = types.InputMediaDocument(id=types.InputDocument(
                        id=media.document.id,
                        access_hash=media.document.access_hash,
                        file_reference=media.document.file_reference))
                elif i.media.startswith("http"):
                    media = self.send(
                        functions.messages.UploadMedia(
                            peer=self.resolve_peer(chat_id),
                            media=types.InputMediaDocumentExternal(
                                url=i.media)))

                    media = types.InputMediaDocument(id=types.InputDocument(
                        id=media.document.id,
                        access_hash=media.document.access_hash,
                        file_reference=media.document.file_reference))
                else:
                    media = utils.get_input_media_from_file_id(
                        i.media, i.file_ref, 4)

            multi_media.append(
                types.InputSingleMedia(media=media,
                                       random_id=self.rnd_id(),
                                       **self.parser.parse(
                                           i.caption, i.parse_mode)))

        while True:
            try:
                r = self.send(
                    functions.messages.SendMultiMedia(
                        peer=self.resolve_peer(chat_id),
                        multi_media=multi_media,
                        silent=disable_notification or None,
                        reply_to_msg_id=reply_to_message_id))
            except FloodWait as e:
                log.warning("Sleeping for {}s".format(e.x))
                time.sleep(e.x)
            else:
                break

        return utils.parse_messages(
            self,
            types.messages.Messages(messages=[
                m.message for m in filter(
                    lambda u: isinstance(u, (types.UpdateNewMessage, types.
                                             UpdateNewChannelMessage)),
                    r.updates)
            ],
                                    users=r.users,
                                    chats=r.chats))
    async def send_video_note(
        self,
        chat_id: Union[int, str],
        video_note: str,
        file_ref: str = None,
        duration: int = 0,
        length: int = 1,
        thumb: str = None,
        disable_notification: bool = None,
        reply_to_message_id: int = None,
        schedule_date: int = None,
        reply_markup: Union["pyrogram.InlineKeyboardMarkup",
                            "pyrogram.ReplyKeyboardMarkup",
                            "pyrogram.ReplyKeyboardRemove",
                            "pyrogram.ForceReply"] = None,
        progress: callable = None,
        progress_args: tuple = ()
    ) -> Union["pyrogram.Message", None]:
        """Send video messages.

        Parameters:
            chat_id (``int`` | ``str``):
                Unique identifier (int) or username (str) of the target chat.
                For your personal cloud (Saved Messages) you can simply use "me" or "self".
                For a contact that exists in your Telegram address book you can use his phone number (str).

            video_note (``str``):
                Video note to send.
                Pass a file_id as string to send a video note that exists on the Telegram servers, or
                pass a file path as string to upload a new video note that exists on your local machine.
                Sending video notes by a URL is currently unsupported.

            file_ref (``str``, *optional*):
                A valid file reference obtained by a recently fetched media message.
                To be used in combination with a file id in case a file reference is needed.

            duration (``int``, *optional*):
                Duration of sent video in seconds.

            length (``int``, *optional*):
                Video width and height.

            thumb (``str``, *optional*):
                Thumbnail of the video sent.
                The thumbnail should be in JPEG format and less than 200 KB in size.
                A thumbnail's width and height should not exceed 320 pixels.
                Thumbnails can't be reused and can be only uploaded as a new file.

            disable_notification (``bool``, *optional*):
                Sends the message silently.
                Users will receive a notification with no sound.

            reply_to_message_id (``int``, *optional*):
                If the message is a reply, ID of the original message

            schedule_date (``int``, *optional*):
                Date when the message will be automatically sent. Unix time.

            reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
                Additional interface options. An object for an inline keyboard, custom reply keyboard,
                instructions to remove reply keyboard or to force a reply from the user.

            progress (``callable``, *optional*):
                Pass a callback function to view the file transmission progress.
                The function must take *(current, total)* as positional arguments (look at Other Parameters below for a
                detailed description) and will be called back each time a new file chunk has been successfully
                transmitted.

            progress_args (``tuple``, *optional*):
                Extra custom arguments for the progress callback function.
                You can pass anything you need to be available in the progress callback scope; for example, a Message
                object or a Client instance in order to edit the message with the updated progress status.

        Other Parameters:
            current (``int``):
                The amount of bytes transmitted so far.

            total (``int``):
                The total size of the file.

            *args (``tuple``, *optional*):
                Extra custom arguments as defined in the *progress_args* parameter.
                You can either keep *\*args* or add every single extra argument in your function signature.

        Returns:
            :obj:`Message` | ``None``: On success, the sent video note message is returned, otherwise, in case the
            upload is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned.

        Example:
            .. code-block:: python

                # Send video note by uploading from local file
                app.send_video_note("me", "video_note.mp4")

                # Set video note length
                app.send_video_note("me", "video_note.mp4", length=25)
        """
        file = None

        try:
            if os.path.exists(video_note):
                thumb = None if thumb is None else await self.save_file(thumb)
                file = await self.save_file(video_note,
                                            progress=progress,
                                            progress_args=progress_args)
                media = types.InputMediaUploadedDocument(
                    mime_type=self.guess_mime_type(video_note) or "video/mp4",
                    file=file,
                    thumb=thumb,
                    attributes=[
                        types.DocumentAttributeVideo(round_message=True,
                                                     duration=duration,
                                                     w=length,
                                                     h=length)
                    ])
            else:
                media = utils.get_input_media_from_file_id(
                    video_note, file_ref, 13)

            while True:
                try:
                    r = await self.send(
                        functions.messages.SendMedia(
                            peer=await self.resolve_peer(chat_id),
                            media=media,
                            silent=disable_notification or None,
                            reply_to_msg_id=reply_to_message_id,
                            random_id=self.rnd_id(),
                            schedule_date=schedule_date,
                            reply_markup=reply_markup.write()
                            if reply_markup else None,
                            message=""))
                except FilePartMissing as e:
                    await self.save_file(video_note,
                                         file_id=file.id,
                                         file_part=e.x)
                else:
                    for i in r.updates:
                        if isinstance(i, (types.UpdateNewMessage,
                                          types.UpdateNewChannelMessage,
                                          types.UpdateNewScheduledMessage)):
                            return await pyrogram.Message._parse(
                                self,
                                i.message, {i.id: i
                                            for i in r.users},
                                {i.id: i
                                 for i in r.chats},
                                is_scheduled=isinstance(
                                    i, types.UpdateNewScheduledMessage))
        except BaseClient.StopTransmission:
            return None
Exemple #5
0
    async def send_sticker(
        self,
        chat_id: Union[int, str],
        sticker: Union[str, BinaryIO],
        file_ref: str = None,
        disable_notification: bool = None,
        reply_to_message_id: int = None,
        schedule_date: int = None,
        reply_markup: Union["pyrogram.InlineKeyboardMarkup",
                            "pyrogram.ReplyKeyboardMarkup",
                            "pyrogram.ReplyKeyboardRemove",
                            "pyrogram.ForceReply"] = None,
        progress: callable = None,
        progress_args: tuple = ()
    ) -> Union["pyrogram.Message", None]:
        """Send static .webp or animated .tgs stickers.

        Parameters:
            chat_id (``int`` | ``str``):
                Unique identifier (int) or username (str) of the target chat.
                For your personal cloud (Saved Messages) you can simply use "me" or "self".
                For a contact that exists in your Telegram address book you can use his phone number (str).

            sticker (``str`` | ``BinaryIO``):
                Sticker to send.
                Pass a file_id as string to send a sticker that exists on the Telegram servers,
                pass an HTTP URL as a string for Telegram to get a .webp sticker file from the Internet,
                pass a file path as string to upload a new sticker that exists on your local machine, or
                pass a binary file-like object with its attribute ".name" set for in-memory uploads.

            file_ref (``str``, *optional*):
                A valid file reference obtained by a recently fetched media message.
                To be used in combination with a file id in case a file reference is needed.

            disable_notification (``bool``, *optional*):
                Sends the message silently.
                Users will receive a notification with no sound.

            reply_to_message_id (``int``, *optional*):
                If the message is a reply, ID of the original message.

            schedule_date (``int``, *optional*):
                Date when the message will be automatically sent. Unix time.

            reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
                Additional interface options. An object for an inline keyboard, custom reply keyboard,
                instructions to remove reply keyboard or to force a reply from the user.

            progress (``callable``, *optional*):
                Pass a callback function to view the file transmission progress.
                The function must take *(current, total)* as positional arguments (look at Other Parameters below for a
                detailed description) and will be called back each time a new file chunk has been successfully
                transmitted.

            progress_args (``tuple``, *optional*):
                Extra custom arguments for the progress callback function.
                You can pass anything you need to be available in the progress callback scope; for example, a Message
                object or a Client instance in order to edit the message with the updated progress status.

        Other Parameters:
            current (``int``):
                The amount of bytes transmitted so far.

            total (``int``):
                The total size of the file.

            *args (``tuple``, *optional*):
                Extra custom arguments as defined in the *progress_args* parameter.
                You can either keep *\*args* or add every single extra argument in your function signature.

        Returns:
            :obj:`Message` | ``None``: On success, the sent sticker message is returned, otherwise, in case the upload
            is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned.

        Example:
            .. code-block:: python

                # Send sticker by uploading from local file
                app.send_sticker("me", "sticker.webp")

                # Send sticker using file_id
                app.send_sticker("me", "CAADBAADzg4AAvLQYAEz_x2EOgdRwBYE")
        """
        file = None

        try:
            if isinstance(sticker, str):
                if os.path.isfile(sticker):
                    file = await self.save_file(sticker,
                                                progress=progress,
                                                progress_args=progress_args)
                    media = types.InputMediaUploadedDocument(
                        mime_type=self.guess_mime_type(sticker)
                        or "image/webp",
                        file=file,
                        attributes=[
                            types.DocumentAttributeFilename(
                                file_name=os.path.basename(sticker))
                        ])
                elif re.match("^https?://", sticker):
                    media = types.InputMediaDocumentExternal(url=sticker)
                else:
                    media = utils.get_input_media_from_file_id(
                        sticker, file_ref, 8)
            else:
                file = await self.save_file(sticker,
                                            progress=progress,
                                            progress_args=progress_args)
                media = types.InputMediaUploadedDocument(
                    mime_type=self.guess_mime_type(sticker.name)
                    or "image/webp",
                    file=file,
                    attributes=[
                        types.DocumentAttributeFilename(file_name=sticker.name)
                    ])

            while True:
                try:
                    r = await self.send(
                        functions.messages.SendMedia(
                            peer=await self.resolve_peer(chat_id),
                            media=media,
                            silent=disable_notification or None,
                            reply_to_msg_id=reply_to_message_id,
                            random_id=self.rnd_id(),
                            schedule_date=schedule_date,
                            reply_markup=reply_markup.write()
                            if reply_markup else None,
                            message=""))
                except FilePartMissing as e:
                    await self.save_file(sticker,
                                         file_id=file.id,
                                         file_part=e.x)
                else:
                    for i in r.updates:
                        if isinstance(i, (types.UpdateNewMessage,
                                          types.UpdateNewChannelMessage,
                                          types.UpdateNewScheduledMessage)):
                            return await pyrogram.Message._parse(
                                self,
                                i.message, {i.id: i
                                            for i in r.users},
                                {i.id: i
                                 for i in r.chats},
                                is_scheduled=isinstance(
                                    i, types.UpdateNewScheduledMessage))
        except BaseClient.StopTransmission:
            return None
    async def send_document(
        self,
        chat_id: Union[int, str],
        document: str,
        thumb: str = None,
        caption: str = "",
        parse_mode: Union[str, None] = "",
        disable_notification: bool = None,
        reply_to_message_id: int = None,
        reply_markup: Union["pyrogram.InlineKeyboardMarkup",
                            "pyrogram.ReplyKeyboardMarkup",
                            "pyrogram.ReplyKeyboardRemove",
                            "pyrogram.ForceReply"] = None,
        progress: callable = None,
        progress_args: tuple = ()
    ) -> Union["pyrogram.Message", None]:
        """Send generic files.

        Parameters:
            chat_id (``int`` | ``str``):
                Unique identifier (int) or username (str) of the target chat.
                For your personal cloud (Saved Messages) you can simply use "me" or "self".
                For a contact that exists in your Telegram address book you can use his phone number (str).

            document (``str``):
                File to send.
                Pass a file_id as string to send a file that exists on the Telegram servers,
                pass an HTTP URL as a string for Telegram to get a file from the Internet, or
                pass a file path as string to upload a new file that exists on your local machine.

            thumb (``str``, *optional*):
                Thumbnail of the file sent.
                The thumbnail should be in JPEG format and less than 200 KB in size.
                A thumbnail's width and height should not exceed 320 pixels.
                Thumbnails can't be reused and can be only uploaded as a new file.

            caption (``str``, *optional*):
                Document caption, 0-1024 characters.

            parse_mode (``str``, *optional*):
                By default, texts are parsed using both Markdown and HTML styles.
                You can combine both syntaxes together.
                Pass "markdown" to enable Markdown-style parsing only.
                Pass "html" to enable HTML-style parsing only.
                Pass None to completely disable style parsing.

            disable_notification (``bool``, *optional*):
                Sends the message silently.
                Users will receive a notification with no sound.

            reply_to_message_id (``int``, *optional*):
                If the message is a reply, ID of the original message.

            reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
                Additional interface options. An object for an inline keyboard, custom reply keyboard,
                instructions to remove reply keyboard or to force a reply from the user.

            progress (``callable``, *optional*):
                Pass a callback function to view the upload progress.
                The function must take *(client, current, total, \*args)* as positional arguments (look at the section
                below for a detailed description).

            progress_args (``tuple``, *optional*):
                Extra custom arguments for the progress callback function. Useful, for example, if you want to pass
                a chat_id and a message_id in order to edit a message with the updated progress.

        Other Parameters:
            client (:obj:`Client`):
                The Client itself, useful when you want to call other API methods inside the callback function.

            current (``int``):
                The amount of bytes uploaded so far.

            total (``int``):
                The size of the file.

            *args (``tuple``, *optional*):
                Extra custom arguments as defined in the *progress_args* parameter.
                You can either keep *\*args* or add every single extra argument in your function signature.

        Returns:
            :obj:`Message` | ``None``: On success, the sent document message is returned, otherwise, in case the upload
            is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned.

        Raises:
            RPCError: In case of a Telegram RPC error.
        """
        file = None

        try:
            if os.path.exists(document):
                thumb = None if thumb is None else await self.save_file(thumb)
                file = await self.save_file(document,
                                            progress=progress,
                                            progress_args=progress_args)
                media = types.InputMediaUploadedDocument(
                    mime_type=self.guess_mime_type(document)
                    or "application/zip",
                    file=file,
                    thumb=thumb,
                    attributes=[
                        types.DocumentAttributeFilename(
                            file_name=os.path.basename(document))
                    ])
            elif document.startswith("http"):
                media = types.InputMediaDocumentExternal(url=document)
            else:
                media = utils.get_input_media_from_file_id(document, 5)

            while True:
                try:
                    r = await self.send(
                        functions.messages.SendMedia(
                            peer=await self.resolve_peer(chat_id),
                            media=media,
                            silent=disable_notification or None,
                            reply_to_msg_id=reply_to_message_id,
                            random_id=self.rnd_id(),
                            reply_markup=reply_markup.write()
                            if reply_markup else None,
                            **await self.parser.parse(caption, parse_mode)))
                except FilePartMissing as e:
                    await self.save_file(document,
                                         file_id=file.id,
                                         file_part=e.x)
                else:
                    for i in r.updates:
                        if isinstance(i, (types.UpdateNewMessage,
                                          types.UpdateNewChannelMessage)):
                            return await pyrogram.Message._parse(
                                self, i.message, {i.id: i
                                                  for i in r.users},
                                {i.id: i
                                 for i in r.chats})
        except BaseClient.StopTransmission:
            return None
Exemple #7
0
    def edit_inline_media(
            self,
            inline_message_id: str,
            media: InputMedia,
            reply_markup: "pyrogram.InlineKeyboardMarkup" = None) -> bool:
        """Edit inline animation, audio, document, photo or video messages.

        When the inline message is edited, a new file can't be uploaded. Use a previously uploaded file via its file_id
        or specify a URL.

        Parameters:
            inline_message_id (``str``):
                Required if *chat_id* and *message_id* are not specified.
                Identifier of the inline message.

            media (:obj:`InputMedia`):
                One of the InputMedia objects describing an animation, audio, document, photo or video.

            reply_markup (:obj:`InlineKeyboardMarkup`, *optional*):
                An InlineKeyboardMarkup object.

        Returns:
            ``bool``: On success, True is returned.

        Example:
            .. code-block:: python

                from pyrogram import InputMediaPhoto, InputMediaVideo, InputMediaAudio

                # Bots only

                # Replace the current media with a local photo
                app.edit_inline_media(inline_message_id, InputMediaPhoto("new_photo.jpg"))

                # Replace the current media with a local video
                app.edit_inline_media(inline_message_id, InputMediaVideo("new_video.mp4"))

                # Replace the current media with a local audio
                app.edit_inline_media(inline_message_id, InputMediaAudio("new_audio.mp3"))
        """
        caption = media.caption
        parse_mode = media.parse_mode

        if isinstance(media, InputMediaPhoto):
            if media.media.startswith("http"):
                media = types.InputMediaPhotoExternal(url=media.media)
            else:
                media = utils.get_input_media_from_file_id(
                    media.media, media.file_ref, 2)
        elif isinstance(media, InputMediaVideo):
            if media.media.startswith("http"):
                media = types.InputMediaDocumentExternal(url=media.media)
            else:
                media = utils.get_input_media_from_file_id(
                    media.media, media.file_ref, 4)
        elif isinstance(media, InputMediaAudio):
            if media.media.startswith("http"):
                media = types.InputMediaDocumentExternal(url=media.media)
            else:
                media = utils.get_input_media_from_file_id(
                    media.media, media.file_ref, 9)
        elif isinstance(media, InputMediaAnimation):
            if media.media.startswith("http"):
                media = types.InputMediaDocumentExternal(url=media.media)
            else:
                media = utils.get_input_media_from_file_id(
                    media.media, media.file_ref, 10)
        elif isinstance(media, InputMediaDocument):
            if media.media.startswith("http"):
                media = types.InputMediaDocumentExternal(url=media.media)
            else:
                media = utils.get_input_media_from_file_id(
                    media.media, media.file_ref, 5)

        return self.send(
            functions.messages.EditInlineBotMessage(
                id=utils.unpack_inline_message_id(inline_message_id),
                media=media,
                reply_markup=reply_markup.write() if reply_markup else None,
                **self.parser.parse(caption, parse_mode)))
Exemple #8
0
    async def send_cached_media(
        self,
        chat_id: Union[int, str],
        file_id: str,
        file_ref: str = None,
        caption: str = "",
        parse_mode: Union[str, None] = object,
        disable_notification: bool = None,
        reply_to_message_id: int = None,
        schedule_date: int = None,
        reply_markup: Union[
            "pyrogram.InlineKeyboardMarkup",
            "pyrogram.ReplyKeyboardMarkup",
            "pyrogram.ReplyKeyboardRemove",
            "pyrogram.ForceReply"
        ] = None
    ) -> Union["pyrogram.Message", None]:
        """Send any media stored on the Telegram servers using a file_id.

        This convenience method works with any valid file_id only.
        It does the same as calling the relevant method for sending media using a file_id, thus saving you from the
        hassle of using the correct method for the media the file_id is pointing to.

        Parameters:
            chat_id (``int`` | ``str``):
                Unique identifier (int) or username (str) of the target chat.
                For your personal cloud (Saved Messages) you can simply use "me" or "self".
                For a contact that exists in your Telegram address book you can use his phone number (str).

            file_id (``str``):
                Media to send.
                Pass a file_id as string to send a media that exists on the Telegram servers.

            file_ref (``str``, *optional*):
                A valid file reference obtained by a recently fetched media message.
                To be used in combination with a file id in case a file reference is needed.

            caption (``str``, *optional*):
                Media caption, 0-1024 characters.

            parse_mode (``str``, *optional*):
                By default, texts are parsed using both Markdown and HTML styles.
                You can combine both syntaxes together.
                Pass "markdown" or "md" to enable Markdown-style parsing only.
                Pass "html" to enable HTML-style parsing only.
                Pass None to completely disable style parsing.

            disable_notification (``bool``, *optional*):
                Sends the message silently.
                Users will receive a notification with no sound.

            reply_to_message_id (``int``, *optional*):
                If the message is a reply, ID of the original message.

            schedule_date (``int``, *optional*):
                Date when the message will be automatically sent. Unix time.

            reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
                Additional interface options. An object for an inline keyboard, custom reply keyboard,
                instructions to remove reply keyboard or to force a reply from the user.

        Returns:
            :obj:`Message`: On success, the sent media message is returned.

        Example:
            .. code-block:: python

                app.send_cached_media("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI")
        """

        r = await self.send(
            functions.messages.SendMedia(
                peer=await self.resolve_peer(chat_id),
                media=utils.get_input_media_from_file_id(file_id, file_ref),
                silent=disable_notification or None,
                reply_to_msg_id=reply_to_message_id,
                random_id=self.rnd_id(),
                schedule_date=schedule_date,
                reply_markup=reply_markup.write() if reply_markup else None,
                **await self.parser.parse(caption, parse_mode)
            )
        )

        for i in r.updates:
            if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage, types.UpdateNewScheduledMessage)):
                return await pyrogram.Message._parse(
                    self, i.message,
                    {i.id: i for i in r.users},
                    {i.id: i for i in r.chats},
                    is_scheduled=isinstance(i, types.UpdateNewScheduledMessage)
                )
Exemple #9
0
    def edit_message_media(
        self,
        chat_id: Union[int, str],
        message_id: int,
        media: InputMedia,
        reply_markup: "pyrogram.InlineKeyboardMarkup" = None
    ) -> "pyrogram.Message":
        """Edit audio, document, photo, or video messages.

        If a message is a part of a message album, then it can be edited only to a photo or a video. Otherwise,
        message type can be changed arbitrarily. When inline message is edited, new file can't be uploaded.
        Use previously uploaded file via its file_id or specify a URL. On success, if the edited message was sent
        by the bot, the edited Message is returned, otherwise True is returned.

        Parameters:
            chat_id (``int`` | ``str``):
                Unique identifier (int) or username (str) of the target chat.
                For your personal cloud (Saved Messages) you can simply use "me" or "self".
                For a contact that exists in your Telegram address book you can use his phone number (str).

            message_id (``int``):
                Message identifier in the chat specified in chat_id.

            media (:obj:`InputMedia`)
                One of the InputMedia objects describing an animation, audio, document, photo or video.

            reply_markup (:obj:`InlineKeyboardMarkup`, *optional*):
                An InlineKeyboardMarkup object.

        Returns:
            :obj:`Message`: On success, the edited message is returned.

        Raises:
            RPCError: In case of a Telegram RPC error.
        """
        style = self.html if media.parse_mode.lower(
        ) == "html" else self.markdown
        caption = media.caption

        if isinstance(media, InputMediaPhoto):
            if os.path.exists(media.media):
                media = self.send(
                    functions.messages.UploadMedia(
                        peer=self.resolve_peer(chat_id),
                        media=types.InputMediaUploadedPhoto(
                            file=self.save_file(media.media))))

                media = types.InputMediaPhoto(
                    id=types.InputPhoto(id=media.photo.id,
                                        access_hash=media.photo.access_hash,
                                        file_reference=b""))
            elif media.media.startswith("http"):
                media = types.InputMediaPhotoExternal(url=media.media)
            else:
                media = utils.get_input_media_from_file_id(media.media, 2)

        if isinstance(media, InputMediaVideo):
            if os.path.exists(media.media):
                media = self.send(
                    functions.messages.UploadMedia(
                        peer=self.resolve_peer(chat_id),
                        media=types.InputMediaUploadedDocument(
                            mime_type=self.guess_mime_type(media.media)
                            or "video/mp4",
                            thumb=None if media.thumb is None else
                            self.save_file(media.thumb),
                            file=self.save_file(media.media),
                            attributes=[
                                types.DocumentAttributeVideo(
                                    supports_streaming=media.supports_streaming
                                    or None,
                                    duration=media.duration,
                                    w=media.width,
                                    h=media.height),
                                types.DocumentAttributeFilename(
                                    file_name=os.path.basename(media.media))
                            ])))

                media = types.InputMediaDocument(id=types.InputDocument(
                    id=media.document.id,
                    access_hash=media.document.access_hash,
                    file_reference=b""))
            elif media.media.startswith("http"):
                media = types.InputMediaDocumentExternal(url=media.media)
            else:
                media = utils.get_input_media_from_file_id(media.media, 4)

        if isinstance(media, InputMediaAudio):
            if os.path.exists(media.media):
                media = self.send(
                    functions.messages.UploadMedia(
                        peer=self.resolve_peer(chat_id),
                        media=types.InputMediaUploadedDocument(
                            mime_type=self.guess_mime_type(media.media)
                            or "audio/mpeg",
                            thumb=None if media.thumb is None else
                            self.save_file(media.thumb),
                            file=self.save_file(media.media),
                            attributes=[
                                types.DocumentAttributeAudio(
                                    duration=media.duration,
                                    performer=media.performer,
                                    title=media.title),
                                types.DocumentAttributeFilename(
                                    file_name=os.path.basename(media.media))
                            ])))

                media = types.InputMediaDocument(id=types.InputDocument(
                    id=media.document.id,
                    access_hash=media.document.access_hash,
                    file_reference=b""))
            elif media.media.startswith("http"):
                media = types.InputMediaDocumentExternal(url=media.media)
            else:
                media = utils.get_input_media_from_file_id(media.media, 9)

        if isinstance(media, InputMediaAnimation):
            if os.path.exists(media.media):
                media = self.send(
                    functions.messages.UploadMedia(
                        peer=self.resolve_peer(chat_id),
                        media=types.InputMediaUploadedDocument(
                            mime_type=self.guess_mime_type(media.media)
                            or "video/mp4",
                            thumb=None if media.thumb is None else
                            self.save_file(media.thumb),
                            file=self.save_file(media.media),
                            attributes=[
                                types.DocumentAttributeVideo(
                                    supports_streaming=True,
                                    duration=media.duration,
                                    w=media.width,
                                    h=media.height),
                                types.DocumentAttributeFilename(
                                    file_name=os.path.basename(media.media)),
                                types.DocumentAttributeAnimated()
                            ])))

                media = types.InputMediaDocument(id=types.InputDocument(
                    id=media.document.id,
                    access_hash=media.document.access_hash,
                    file_reference=b""))
            elif media.media.startswith("http"):
                media = types.InputMediaDocumentExternal(url=media.media)
            else:
                media = utils.get_input_media_from_file_id(media.media, 10)

        if isinstance(media, InputMediaDocument):
            if os.path.exists(media.media):
                media = self.send(
                    functions.messages.UploadMedia(
                        peer=self.resolve_peer(chat_id),
                        media=types.InputMediaUploadedDocument(
                            mime_type=self.guess_mime_type(media.media)
                            or "application/zip",
                            thumb=None if media.thumb is None else
                            self.save_file(media.thumb),
                            file=self.save_file(media.media),
                            attributes=[
                                types.DocumentAttributeFilename(
                                    file_name=os.path.basename(media.media))
                            ])))

                media = types.InputMediaDocument(id=types.InputDocument(
                    id=media.document.id,
                    access_hash=media.document.access_hash,
                    file_reference=b""))
            elif media.media.startswith("http"):
                media = types.InputMediaDocumentExternal(url=media.media)
            else:
                media = utils.get_input_media_from_file_id(media.media, 5)

        r = self.send(
            functions.messages.EditMessage(
                peer=self.resolve_peer(chat_id),
                id=message_id,
                reply_markup=reply_markup.write() if reply_markup else None,
                media=media,
                **style.parse(caption)))

        for i in r.updates:
            if isinstance(
                    i,
                (types.UpdateEditMessage, types.UpdateEditChannelMessage)):
                return pyrogram.Message._parse(self, i.message,
                                               {i.id: i
                                                for i in r.users},
                                               {i.id: i
                                                for i in r.chats})
Exemple #10
0
    async def edit_message_media(
        self,
        chat_id: Union[int, str],
        message_id: int,
        media: InputMedia,
        reply_markup: "pyrogram.InlineKeyboardMarkup" = None
    ) -> "pyrogram.Message":
        """Edit animation, audio, document, photo or video messages.

        If a message is a part of a message album, then it can be edited only to a photo or a video. Otherwise, the
        message type can be changed arbitrarily.

        Parameters:
            chat_id (``int`` | ``str``):
                Unique identifier (int) or username (str) of the target chat.
                For your personal cloud (Saved Messages) you can simply use "me" or "self".
                For a contact that exists in your Telegram address book you can use his phone number (str).

            message_id (``int``):
                Message identifier in the chat specified in chat_id.

            media (:obj:`InputMedia`):
                One of the InputMedia objects describing an animation, audio, document, photo or video.

            reply_markup (:obj:`InlineKeyboardMarkup`, *optional*):
                An InlineKeyboardMarkup object.

        Returns:
            :obj:`Message`: On success, the edited message is returned.

        Example:
            .. code-block:: python

                from pyrogram import InputMediaPhoto, InputMediaVideo, InputMediaAudio

                # Replace the current media with a local photo
                app.edit_message_media(chat_id, message_id, InputMediaPhoto("new_photo.jpg"))

                # Replace the current media with a local video
                app.edit_message_media(chat_id, message_id, InputMediaVideo("new_video.mp4"))

                # Replace the current media with a local audio
                app.edit_message_media(chat_id, message_id, InputMediaAudio("new_audio.mp3"))
        """
        caption = media.caption
        parse_mode = media.parse_mode

        if isinstance(media, InputMediaPhoto):
            if os.path.exists(media.media):
                media = await self.send(
                    functions.messages.UploadMedia(
                        peer=await self.resolve_peer(chat_id),
                        media=types.InputMediaUploadedPhoto(
                            file=await self.save_file(media.media)
                        )
                    )
                )

                media = types.InputMediaPhoto(
                    id=types.InputPhoto(
                        id=media.photo.id,
                        access_hash=media.photo.access_hash,
                        file_reference=media.photo.file_reference
                    )
                )
            elif media.media.startswith("http"):
                media = types.InputMediaPhotoExternal(
                    url=media.media
                )
            else:
                media = utils.get_input_media_from_file_id(media.media, media.file_ref, 2)
        elif isinstance(media, InputMediaVideo):
            if os.path.exists(media.media):
                media = await self.send(
                    functions.messages.UploadMedia(
                        peer=await self.resolve_peer(chat_id),
                        media=types.InputMediaUploadedDocument(
                            mime_type=self.guess_mime_type(media.media) or "video/mp4",
                            thumb=None if media.thumb is None else await self.save_file(media.thumb),
                            file=await self.save_file(media.media),
                            attributes=[
                                types.DocumentAttributeVideo(
                                    supports_streaming=media.supports_streaming or None,
                                    duration=media.duration,
                                    w=media.width,
                                    h=media.height
                                ),
                                types.DocumentAttributeFilename(
                                    file_name=os.path.basename(media.media)
                                )
                            ]
                        )
                    )
                )

                media = types.InputMediaDocument(
                    id=types.InputDocument(
                        id=media.document.id,
                        access_hash=media.document.access_hash,
                        file_reference=media.document.file_reference
                    )
                )
            elif media.media.startswith("http"):
                media = types.InputMediaDocumentExternal(
                    url=media.media
                )
            else:
                media = utils.get_input_media_from_file_id(media.media, media.file_ref, 4)
        elif isinstance(media, InputMediaAudio):
            if os.path.exists(media.media):
                media = await self.send(
                    functions.messages.UploadMedia(
                        peer=await self.resolve_peer(chat_id),
                        media=types.InputMediaUploadedDocument(
                            mime_type=self.guess_mime_type(media.media) or "audio/mpeg",
                            thumb=None if media.thumb is None else await self.save_file(media.thumb),
                            file=await self.save_file(media.media),
                            attributes=[
                                types.DocumentAttributeAudio(
                                    duration=media.duration,
                                    performer=media.performer,
                                    title=media.title
                                ),
                                types.DocumentAttributeFilename(
                                    file_name=os.path.basename(media.media)
                                )
                            ]
                        )
                    )
                )

                media = types.InputMediaDocument(
                    id=types.InputDocument(
                        id=media.document.id,
                        access_hash=media.document.access_hash,
                        file_reference=media.document.file_reference
                    )
                )
            elif media.media.startswith("http"):
                media = types.InputMediaDocumentExternal(
                    url=media.media
                )
            else:
                media = utils.get_input_media_from_file_id(media.media, media.file_ref, 9)
        elif isinstance(media, InputMediaAnimation):
            if os.path.exists(media.media):
                media = await self.send(
                    functions.messages.UploadMedia(
                        peer=await self.resolve_peer(chat_id),
                        media=types.InputMediaUploadedDocument(
                            mime_type=self.guess_mime_type(media.media) or "video/mp4",
                            thumb=None if media.thumb is None else self.save_file(media.thumb),
                            file=await self.save_file(media.media),
                            attributes=[
                                types.DocumentAttributeVideo(
                                    supports_streaming=True,
                                    duration=media.duration,
                                    w=media.width,
                                    h=media.height
                                ),
                                types.DocumentAttributeFilename(
                                    file_name=os.path.basename(media.media)
                                ),
                                types.DocumentAttributeAnimated()
                            ]
                        )
                    )
                )

                media = types.InputMediaDocument(
                    id=types.InputDocument(
                        id=media.document.id,
                        access_hash=media.document.access_hash,
                        file_reference=media.document.file_reference
                    )
                )
            elif media.media.startswith("http"):
                media = types.InputMediaDocumentExternal(
                    url=media.media
                )
            else:
                media = utils.get_input_media_from_file_id(media.media, media.file_ref, 10)
        elif isinstance(media, InputMediaDocument):
            if os.path.exists(media.media):
                media = await self.send(
                    functions.messages.UploadMedia(
                        peer=await self.resolve_peer(chat_id),
                        media=types.InputMediaUploadedDocument(
                            mime_type=self.guess_mime_type(media.media) or "application/zip",
                            thumb=None if media.thumb is None else await self.save_file(media.thumb),
                            file=await self.save_file(media.media),
                            attributes=[
                                types.DocumentAttributeFilename(
                                    file_name=os.path.basename(media.media)
                                )
                            ]
                        )
                    )
                )

                media = types.InputMediaDocument(
                    id=types.InputDocument(
                        id=media.document.id,
                        access_hash=media.document.access_hash,
                        file_reference=media.document.file_reference
                    )
                )
            elif media.media.startswith("http"):
                media = types.InputMediaDocumentExternal(
                    url=media.media
                )
            else:
                media = utils.get_input_media_from_file_id(media.media, media.file_ref, 5)

        r = await self.send(
            functions.messages.EditMessage(
                peer=await self.resolve_peer(chat_id),
                id=message_id,
                media=media,
                reply_markup=reply_markup.write() if reply_markup else None,
                **await self.parser.parse(caption, parse_mode)
            )
        )

        for i in r.updates:
            if isinstance(i, (types.UpdateEditMessage, types.UpdateEditChannelMessage)):
                return await pyrogram.Message._parse(
                    self, i.message,
                    {i.id: i for i in r.users},
                    {i.id: i for i in r.chats}
                )
Exemple #11
0
    def send_voice(
        self,
        chat_id: Union[int, str],
        voice: str,
        caption: str = "",
        parse_mode: str = "",
        duration: int = 0,
        disable_notification: bool = None,
        reply_to_message_id: int = None,
        reply_markup: Union[
            "pyrogram.InlineKeyboardMarkup",
            "pyrogram.ReplyKeyboardMarkup",
            "pyrogram.ReplyKeyboardRemove",
            "pyrogram.ForceReply"
        ] = None,
        progress: callable = None,
        progress_args: tuple = ()
    ) -> Union["pyrogram.Message", None]:
        """Send audio files.

        Parameters:
            chat_id (``int`` | ``str``):
                Unique identifier (int) or username (str) of the target chat.
                For your personal cloud (Saved Messages) you can simply use "me" or "self".
                For a contact that exists in your Telegram address book you can use his phone number (str).

            voice (``str``):
                Audio file to send.
                Pass a file_id as string to send an audio that exists on the Telegram servers,
                pass an HTTP URL as a string for Telegram to get an audio from the Internet, or
                pass a file path as string to upload a new audio that exists on your local machine.

            caption (``str``, *optional*):
                Voice message caption, 0-1024 characters.

            parse_mode (``str``, *optional*):
                Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline
                URLs in your caption. Defaults to "markdown".

            duration (``int``, *optional*):
                Duration of the voice message in seconds.

            disable_notification (``bool``, *optional*):
                Sends the message silently.
                Users will receive a notification with no sound.

            reply_to_message_id (``int``, *optional*):
                If the message is a reply, ID of the original message

            reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
                Additional interface options. An object for an inline keyboard, custom reply keyboard,
                instructions to remove reply keyboard or to force a reply from the user.

            progress (``callable``, *optional*):
                Pass a callback function to view the upload progress.
                The function must take *(client, current, total, \*args)* as positional arguments (look at the section
                below for a detailed description).

            progress_args (``tuple``, *optional*):
                Extra custom arguments for the progress callback function. Useful, for example, if you want to pass
                a chat_id and a message_id in order to edit a message with the updated progress.

        Other Parameters:
            client (:obj:`Client`):
                The Client itself, useful when you want to call other API methods inside the callback function.

            current (``int``):
                The amount of bytes uploaded so far.

            total (``int``):
                The size of the file.

            *args (``tuple``, *optional*):
                Extra custom arguments as defined in the *progress_args* parameter.
                You can either keep *\*args* or add every single extra argument in your function signature.

        Returns:
            :obj:`Message` | ``None``: On success, the sent voice message is returned, otherwise, in case the upload
            is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned.

        Raises:
            RPCError: In case of a Telegram RPC error.
        """
        file = None
        style = self.html if parse_mode.lower() == "html" else self.markdown

        try:
            if os.path.exists(voice):
                file = self.save_file(voice, progress=progress, progress_args=progress_args)
                media = types.InputMediaUploadedDocument(
                    mime_type=self.guess_mime_type(voice) or "audio/mpeg",
                    file=file,
                    attributes=[
                        types.DocumentAttributeAudio(
                            voice=True,
                            duration=duration
                        )
                    ]
                )
            elif voice.startswith("http"):
                media = types.InputMediaDocumentExternal(
                    url=voice
                )
            else:
                media = utils.get_input_media_from_file_id(voice, 3)

            while True:
                try:
                    r = self.send(
                        functions.messages.SendMedia(
                            peer=self.resolve_peer(chat_id),
                            media=media,
                            silent=disable_notification or None,
                            reply_to_msg_id=reply_to_message_id,
                            random_id=self.rnd_id(),
                            reply_markup=reply_markup.write() if reply_markup else None,
                            **style.parse(caption)
                        )
                    )
                except FilePartMissing as e:
                    self.save_file(voice, file_id=file.id, file_part=e.x)
                else:
                    for i in r.updates:
                        if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)):
                            return pyrogram.Message._parse(
                                self, i.message,
                                {i.id: i for i in r.users},
                                {i.id: i for i in r.chats}
                            )
        except BaseClient.StopTransmission:
            return None
Exemple #12
0
    async def send_photo(
        self,
        chat_id: Union[int, str],
        photo: Union[str, BinaryIO],
        file_ref: str = None,
        caption: str = "",
        parse_mode: Union[str, None] = object,
        ttl_seconds: int = None,
        disable_notification: bool = None,
        reply_to_message_id: int = None,
        schedule_date: int = None,
        reply_markup: Union[
            "pyrogram.InlineKeyboardMarkup",
            "pyrogram.ReplyKeyboardMarkup",
            "pyrogram.ReplyKeyboardRemove",
            "pyrogram.ForceReply"
        ] = None,
        progress: callable = None,
        progress_args: tuple = ()
    ) -> Union["pyrogram.Message", None]:
        """Send photos.

        Parameters:
            chat_id (``int`` | ``str``):
                Unique identifier (int) or username (str) of the target chat.
                For your personal cloud (Saved Messages) you can simply use "me" or "self".
                For a contact that exists in your Telegram address book you can use his phone number (str).

            photo (``str`` | ``BinaryIO``):
                Photo to send.
                Pass a file_id as string to send a photo that exists on the Telegram servers,
                pass an HTTP URL as a string for Telegram to get a photo from the Internet,
                pass a file path as string to upload a new photo that exists on your local machine, or
                pass a binary file-like object with its attribute ".name" set for in-memory uploads.

            file_ref (``str``, *optional*):
                A valid file reference obtained by a recently fetched media message.
                To be used in combination with a file id in case a file reference is needed.

            caption (``str``, *optional*):
                Photo caption, 0-1024 characters.

            parse_mode (``str``, *optional*):
                By default, texts are parsed using both Markdown and HTML styles.
                You can combine both syntaxes together.
                Pass "markdown" or "md" to enable Markdown-style parsing only.
                Pass "html" to enable HTML-style parsing only.
                Pass None to completely disable style parsing.

            ttl_seconds (``int``, *optional*):
                Self-Destruct Timer.
                If you set a timer, the photo will self-destruct in *ttl_seconds*
                seconds after it was viewed.

            disable_notification (``bool``, *optional*):
                Sends the message silently.
                Users will receive a notification with no sound.

            reply_to_message_id (``int``, *optional*):
                If the message is a reply, ID of the original message.

            schedule_date (``int``, *optional*):
                Date when the message will be automatically sent. Unix time.

            reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
                Additional interface options. An object for an inline keyboard, custom reply keyboard,
                instructions to remove reply keyboard or to force a reply from the user.

            progress (``callable``, *optional*):
                Pass a callback function to view the file transmission progress.
                The function must take *(current, total)* as positional arguments (look at Other Parameters below for a
                detailed description) and will be called back each time a new file chunk has been successfully
                transmitted.

            progress_args (``tuple``, *optional*):
                Extra custom arguments for the progress callback function.
                You can pass anything you need to be available in the progress callback scope; for example, a Message
                object or a Client instance in order to edit the message with the updated progress status.

        Other Parameters:
            current (``int``):
                The amount of bytes transmitted so far.

            total (``int``):
                The total size of the file.

            *args (``tuple``, *optional*):
                Extra custom arguments as defined in the *progress_args* parameter.
                You can either keep *\*args* or add every single extra argument in your function signature.

        Returns:
            :obj:`Message` | ``None``: On success, the sent photo message is returned, otherwise, in case the upload
            is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned.

        Example:
            .. code-block:: python

                # Send photo by uploading from local file
                app.send_photo("me", "photo.jpg")

                # Send photo by uploading from URL
                app.send_photo("me", "https://i.imgur.com/BQBTP7d.png")

                # Add caption to a photo
                app.send_photo("me", "photo.jpg", caption="Holidays!")

                # Send self-destructing photo
                app.send_photo("me", "photo.jpg", ttl_seconds=10)
        """
        file = None

        try:
            if isinstance(photo, str):
                if os.path.isfile(photo):
                    file = await self.save_file(photo, progress=progress, progress_args=progress_args)
                    media = types.InputMediaUploadedPhoto(
                        file=file,
                        ttl_seconds=ttl_seconds
                    )
                elif re.match("^https?://", photo):
                    media = types.InputMediaPhotoExternal(
                        url=photo,
                        ttl_seconds=ttl_seconds
                    )
                else:
                    media = utils.get_input_media_from_file_id(photo, file_ref, 2)
            else:
                file = await self.save_file(photo, progress=progress, progress_args=progress_args)
                media = types.InputMediaUploadedPhoto(
                    file=file,
                    ttl_seconds=ttl_seconds
                )

            while True:
                try:
                    r = await self.send(
                        functions.messages.SendMedia(
                            peer=await self.resolve_peer(chat_id),
                            media=media,
                            silent=disable_notification or None,
                            reply_to_msg_id=reply_to_message_id,
                            random_id=self.rnd_id(),
                            schedule_date=schedule_date,
                            reply_markup=reply_markup.write() if reply_markup else None,
                            **await self.parser.parse(caption, parse_mode)
                        )
                    )
                except FilePartMissing as e:
                    await self.save_file(photo, file_id=file.id, file_part=e.x)
                else:
                    for i in r.updates:
                        if isinstance(
                            i,
                            (types.UpdateNewMessage, types.UpdateNewChannelMessage, types.UpdateNewScheduledMessage)
                        ):
                            return await pyrogram.Message._parse(
                                self, i.message,
                                {i.id: i for i in r.users},
                                {i.id: i for i in r.chats},
                                is_scheduled=isinstance(i, types.UpdateNewScheduledMessage)
                            )
        except BaseClient.StopTransmission:
            return None
Exemple #13
0
    def edit_inline_media(
            self,
            inline_message_id: str,
            media: InputMedia,
            reply_markup: "pyrogram.InlineKeyboardMarkup" = None) -> bool:
        """Edit **inline** animation, audio, document, photo or video messages.

        When the inline message is edited, a new file can't be uploaded. Use a previously uploaded file via its file_id
        or specify a URL.

        Parameters:
            inline_message_id (``str``):
                Required if *chat_id* and *message_id* are not specified.
                Identifier of the inline message.

            media (:obj:`InputMedia`):
                One of the InputMedia objects describing an animation, audio, document, photo or video.

            reply_markup (:obj:`InlineKeyboardMarkup`, *optional*):
                An InlineKeyboardMarkup object.

        Returns:
            ``bool``: On success, True is returned.

        Raises:
            RPCError: In case of a Telegram RPC error.
        """
        caption = media.caption
        parse_mode = media.parse_mode

        if isinstance(media, InputMediaPhoto):
            if media.media.startswith("http"):
                media = types.InputMediaPhotoExternal(url=media.media)
            else:
                media = utils.get_input_media_from_file_id(media.media, 2)
        elif isinstance(media, InputMediaVideo):
            if media.media.startswith("http"):
                media = types.InputMediaDocumentExternal(url=media.media)
            else:
                media = utils.get_input_media_from_file_id(media.media, 4)
        elif isinstance(media, InputMediaAudio):
            if media.media.startswith("http"):
                media = types.InputMediaDocumentExternal(url=media.media)
            else:
                media = utils.get_input_media_from_file_id(media.media, 9)
        elif isinstance(media, InputMediaAnimation):
            if media.media.startswith("http"):
                media = types.InputMediaDocumentExternal(url=media.media)
            else:
                media = utils.get_input_media_from_file_id(media.media, 10)
        elif isinstance(media, InputMediaDocument):
            if media.media.startswith("http"):
                media = types.InputMediaDocumentExternal(url=media.media)
            else:
                media = utils.get_input_media_from_file_id(media.media, 5)

        return self.send(
            functions.messages.EditInlineBotMessage(
                id=utils.unpack_inline_message_id(inline_message_id),
                media=media,
                reply_markup=reply_markup.write() if reply_markup else None,
                **self.parser.parse(caption, parse_mode)))
async def send_sticker(
    chat_id: Union[int, str],
    sticker: str,
    file_ref: str = None,
    disable_notification: bool = None,
    reply_to_message_id: int = None,
    schedule_date: int = None,
    reply_markup: Union["pyrogram.InlineKeyboardMarkup",
                        "pyrogram.ReplyKeyboardMarkup",
                        "pyrogram.ReplyKeyboardRemove",
                        "pyrogram.ForceReply"] = None,
    progress: callable = None,
    progress_args: tuple = ()
) -> Union["pyrogram.Message", None]:
    if True:
        file = None

        try:
            if os.path.exists(sticker):
                file = await app.save_file(sticker,
                                           progress=progress,
                                           progress_args=progress_args)
                media = types.InputMediaUploadedDocument(
                    mime_type="image/webp",
                    file=file,
                    attributes=[
                        types.DocumentAttributeFilename(
                            file_name=os.path.basename(sticker))
                    ])
            elif sticker.startswith("http"):
                media = types.InputMediaDocumentExternal(url=sticker)
            else:
                media = utils.get_input_media_from_file_id(
                    sticker, file_ref, 8)

            while True:
                try:
                    r = await app.send(
                        functions.messages.SendMedia(
                            peer=await app.resolve_peer(chat_id),
                            media=media,
                            silent=disable_notification or None,
                            reply_to_msg_id=reply_to_message_id,
                            random_id=app.rnd_id(),
                            schedule_date=schedule_date,
                            reply_markup=reply_markup.write()
                            if reply_markup else None,
                            message=""))
                except FilePartMissing as e:
                    await app.save_file(sticker,
                                        file_id=file.id,
                                        file_part=e.x)
                else:
                    for i in r.updates:
                        if isinstance(i, (types.UpdateNewMessage,
                                          types.UpdateNewChannelMessage,
                                          types.UpdateNewScheduledMessage)):
                            return await pyrogram.Message._parse(
                                app,
                                i.message, {i.id: i
                                            for i in r.users},
                                {i.id: i
                                 for i in r.chats},
                                is_scheduled=isinstance(
                                    i, types.UpdateNewScheduledMessage))
        except BaseClient.StopTransmission:
            return None
    app.send(
        functions.channels.DeleteUserHistory(app.resolve_peer(chat.id),
                                             app.resolve_peer(user_id)))
Exemple #15
0
    def send_animation(
        self,
        chat_id: Union[int, str],
        animation: str,
        caption: str = "",
        unsave: bool = False,
        parse_mode: str = "",
        duration: int = 0,
        width: int = 0,
        height: int = 0,
        thumb: str = None,
        disable_notification: bool = None,
        reply_to_message_id: int = None,
        reply_markup: Union["pyrogram.InlineKeyboardMarkup",
                            "pyrogram.ReplyKeyboardMarkup",
                            "pyrogram.ReplyKeyboardRemove",
                            "pyrogram.ForceReply"] = None,
        progress: callable = None,
        progress_args: tuple = ()
    ) -> Union["pyrogram.Message", None]:
        """Send animation files (animation or H.264/MPEG-4 AVC video without sound).

        Parameters:
            chat_id (``int`` | ``str``):
                Unique identifier (int) or username (str) of the target chat.
                For your personal cloud (Saved Messages) you can simply use "me" or "self".
                For a contact that exists in your Telegram address book you can use his phone number (str).

            animation (``str``):
                Animation to send.
                Pass a file_id as string to send an animation that exists on the Telegram servers,
                pass an HTTP URL as a string for Telegram to get an animation from the Internet, or
                pass a file path as string to upload a new animation that exists on your local machine.

            caption (``str``, *optional*):
                Animation caption, 0-1024 characters.

            unsave (``bool``, *optional*):
                By default, the server will save into your own collection any new animation GIF you send.
                Pass True to automatically unsave the sent animation. Defaults to False.

            parse_mode (``str``, *optional*):
                Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline
                URLs in your caption. Defaults to "markdown".

            duration (``int``, *optional*):
                Duration of sent animation in seconds.

            width (``int``, *optional*):
                Animation width.

            height (``int``, *optional*):
                Animation height.

            thumb (``str``, *optional*):
                Thumbnail of the animation file sent.
                The thumbnail should be in JPEG format and less than 200 KB in size.
                A thumbnail's width and height should not exceed 320 pixels.
                Thumbnails can't be reused and can be only uploaded as a new file.

            disable_notification (``bool``, *optional*):
                Sends the message silently.
                Users will receive a notification with no sound.

            reply_to_message_id (``int``, *optional*):
                If the message is a reply, ID of the original message.

            reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
                Additional interface options. An object for an inline keyboard, custom reply keyboard,
                instructions to remove reply keyboard or to force a reply from the user.

            progress (``callable``, *optional*):
                Pass a callback function to view the upload progress.
                The function must take *(client, current, total, \*args)* as positional arguments (look at the section
                below for a detailed description).

            progress_args (``tuple``, *optional*):
                Extra custom arguments for the progress callback function. Useful, for example, if you want to pass
                a chat_id and a message_id in order to edit a message with the updated progress.

        Other Parameters:
            client (:obj:`Client`):
                The Client itself, useful when you want to call other API methods inside the callback function.

            current (``int``):
                The amount of bytes uploaded so far.

            total (``int``):
                The size of the file.

            *args (``tuple``, *optional*):
                Extra custom arguments as defined in the *progress_args* parameter.
                You can either keep *\*args* or add every single extra argument in your function signature.

        Returns:
            :obj:`Message` | ``None``: On success, the sent animation message is returned, otherwise, in case the upload
            is deliberately stopped with :meth:`~Client.stop_transmission`, None is returned.

        Raises:
            RPCError: In case of a Telegram RPC error.
        """
        file = None
        style = self.html if parse_mode.lower() == "html" else self.markdown

        try:
            if os.path.exists(animation):
                thumb = None if thumb is None else self.save_file(thumb)
                file = self.save_file(animation,
                                      progress=progress,
                                      progress_args=progress_args)
                media = types.InputMediaUploadedDocument(
                    mime_type=self.guess_mime_type(animation) or "video/mp4",
                    file=file,
                    thumb=thumb,
                    attributes=[
                        types.DocumentAttributeVideo(supports_streaming=True,
                                                     duration=duration,
                                                     w=width,
                                                     h=height),
                        types.DocumentAttributeFilename(
                            file_name=os.path.basename(animation)),
                        types.DocumentAttributeAnimated()
                    ])
            elif animation.startswith("http"):
                media = types.InputMediaDocumentExternal(url=animation)
            else:
                media = utils.get_input_media_from_file_id(animation, 10)

            while True:
                try:
                    r = self.send(
                        functions.messages.SendMedia(
                            peer=self.resolve_peer(chat_id),
                            media=media,
                            silent=disable_notification or None,
                            reply_to_msg_id=reply_to_message_id,
                            random_id=self.rnd_id(),
                            reply_markup=reply_markup.write()
                            if reply_markup else None,
                            **style.parse(caption)))
                except FilePartMissing as e:
                    self.save_file(animation, file_id=file.id, file_part=e.x)
                else:
                    for i in r.updates:
                        if isinstance(i, (types.UpdateNewMessage,
                                          types.UpdateNewChannelMessage)):
                            message = pyrogram.Message._parse(
                                self, i.message, {i.id: i
                                                  for i in r.users},
                                {i.id: i
                                 for i in r.chats})

                            if unsave:
                                document = message.animation or message.document
                                document_id = utils.get_input_media_from_file_id(
                                    document.file_id).id

                                self.send(
                                    functions.messages.SaveGif(id=document_id,
                                                               unsave=True))

                            return message

        except BaseClient.StopTransmission:
            return None
    def send_cached_media(
        self,
        chat_id: Union[int, str],
        file_id: str,
        caption: str = "",
        parse_mode: str = "",
        disable_notification: bool = None,
        reply_to_message_id: int = None,
        reply_markup: Union["pyrogram.InlineKeyboardMarkup",
                            "pyrogram.ReplyKeyboardMarkup",
                            "pyrogram.ReplyKeyboardRemove",
                            "pyrogram.ForceReply"] = None
    ) -> Union["pyrogram.Message", None]:
        """Send any media stored on the Telegram servers using a file_id.

        This convenience method works with any valid file_id only.
        It does the same as calling the relevant method for sending media using a file_id, thus saving you from the
        hassle of using the correct method for the media the file_id is pointing to.

        Parameters:
            chat_id (``int`` | ``str``):
                Unique identifier (int) or username (str) of the target chat.
                For your personal cloud (Saved Messages) you can simply use "me" or "self".
                For a contact that exists in your Telegram address book you can use his phone number (str).

            file_id (``str``):
                Media to send.
                Pass a file_id as string to send a media that exists on the Telegram servers.

            caption (``bool``, *optional*):
                Media caption, 0-1024 characters.

            parse_mode (``str``, *optional*):
                Pass "markdown" or "html" if you want Telegram apps to show bold, italic, fixed-width text or inline
                URLs in your caption. Defaults to "markdown".

            disable_notification (``bool``, *optional*):
                Sends the message silently.
                Users will receive a notification with no sound.

            reply_to_message_id (``int``, *optional*):
                If the message is a reply, ID of the original message.

            reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
                Additional interface options. An object for an inline keyboard, custom reply keyboard,
                instructions to remove reply keyboard or to force a reply from the user.

        Returns:
            :obj:`Message`: On success, the sent media message is returned.

        Raises:
            RPCError: In case of a Telegram RPC error.
        """
        style = self.html if parse_mode.lower() == "html" else self.markdown

        r = self.send(
            functions.messages.SendMedia(
                peer=self.resolve_peer(chat_id),
                media=utils.get_input_media_from_file_id(file_id),
                silent=disable_notification or None,
                reply_to_msg_id=reply_to_message_id,
                random_id=self.rnd_id(),
                reply_markup=reply_markup.write() if reply_markup else None,
                **style.parse(caption)))

        for i in r.updates:
            if isinstance(
                    i,
                (types.UpdateNewMessage, types.UpdateNewChannelMessage)):
                return pyrogram.Message._parse(self, i.message,
                                               {i.id: i
                                                for i in r.users},
                                               {i.id: i
                                                for i in r.chats})