From 7ff693eefc68d3decc4d0ae2aeca47caa516284b Mon Sep 17 00:00:00 2001 From: wulan17 Date: Mon, 30 Oct 2023 19:32:57 +0700 Subject: [PATCH] Pyrofork: Add send_web_page method Signed-off-by: wulan17 --- compiler/docs/compiler.py | 1 + pyrogram/methods/messages/__init__.py | 2 + pyrogram/methods/messages/send_web_page.py | 184 +++++++++++++++++++++ 3 files changed, 187 insertions(+) create mode 100644 pyrogram/methods/messages/send_web_page.py diff --git a/compiler/docs/compiler.py b/compiler/docs/compiler.py index c4a25b37..ed74ba7a 100644 --- a/compiler/docs/compiler.py +++ b/compiler/docs/compiler.py @@ -161,6 +161,7 @@ def pyrogram_api(): send_animation send_voice send_video_note + send_web_page send_media_group send_location send_venue diff --git a/pyrogram/methods/messages/__init__.py b/pyrogram/methods/messages/__init__.py index 7a5d2d49..3007290c 100644 --- a/pyrogram/methods/messages/__init__.py +++ b/pyrogram/methods/messages/__init__.py @@ -61,6 +61,7 @@ from .send_venue import SendVenue from .send_video import SendVideo from .send_video_note import SendVideoNote from .send_voice import SendVoice +from .send_web_page import SendWebPage from .stop_poll import StopPoll from .stream_media import StreamMedia from .vote_poll import VotePoll @@ -89,6 +90,7 @@ class Messages( SendVideo, SendVideoNote, SendVoice, + SendWebPage, SendPoll, VotePoll, StopPoll, diff --git a/pyrogram/methods/messages/send_web_page.py b/pyrogram/methods/messages/send_web_page.py new file mode 100644 index 00000000..c9107374 --- /dev/null +++ b/pyrogram/methods/messages/send_web_page.py @@ -0,0 +1,184 @@ +# Pyrofork - Telegram MTProto API Client Library for Python +# Copyright (C) 2022-present Mayuri-Chan +# +# This file is part of Pyrofork. +# +# Pyrofork is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrofork is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrofork. If not, see . + +import re +from datetime import datetime +from typing import Union, List, Optional + +import pyrogram +from pyrogram import raw, utils, enums +from pyrogram import types + +class SendWebPage: + async def send_web_page( + self: "pyrogram.Client", + chat_id: Union[int, str], + url: str, + text: str = "", + parse_mode: Optional["enums.ParseMode"] = None, + entities: List["types.MessageEntity"] = None, + disable_web_page_preview: bool = None, + large_media: bool = None, + invert_media: bool = None, + disable_notification: bool = None, + message_thread_id: int = None, + reply_to_message_id: int = None, + reply_to_story_id: int = None, + quote_text: str = None, + schedule_date: datetime = None, + protect_content: bool = None, + reply_markup: Union[ + "types.InlineKeyboardMarkup", + "types.ReplyKeyboardMarkup", + "types.ReplyKeyboardRemove", + "types.ForceReply" + ] = None + ) -> "types.Message": + """Send text Web Page Preview. + + .. include:: /_includes/usable-by/users-bots.rst + + 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). + + url (``str``): + Link that will be previewed. + + text (``str``, *optional*): + Text of the message to be sent. + + parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*): + By default, texts are parsed using both Markdown and HTML styles. + You can combine both syntaxes together. + + entities (List of :obj:`~pyrogram.types.MessageEntity`): + List of special entities that appear in message text, which can be specified instead of *parse_mode*. + + large_media (``bool``, *optional*): + Make web page preview image larger. + + invert_media (``bool``, *optional*): + Move web page preview to above the message. + + disable_notification (``bool``, *optional*): + Sends the message silently. + Users will receive a notification with no sound. + + message_thread_id (``int``, *optional*): + Unique identifier for the target message thread (topic) of the forum. + for forum supergroups only. + + reply_to_message_id (``int``, *optional*): + If the message is a reply, ID of the original message. + + reply_to_story_id (``int``, *optional*): + Unique identifier for the target story. + + quote_text (``str``, *optional*): + Text to quote. + for reply_to_message only. + + schedule_date (:py:obj:`~datetime.datetime`, *optional*): + Date when the message will be automatically sent. + + protect_content (``bool``, *optional*): + Protects the contents of the sent message from forwarding and saving. + + reply_markup (:obj:`~pyrogram.types.InlineKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardRemove` | :obj:`~pyrogram.types.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:`~pyrogram.types.Message`: On success, the sent text message is returned. + + Example: + .. code-block:: python + + await app.send_web_page("me", "https://github.com/Mayuri-Chan/pyrofork") + + """ + + message, entities = (await utils.parse_text_entities(self, text, parse_mode, entities)).values() + + reply_to = None + if reply_to_message_id or message_thread_id: + reply_to = types.InputReplyToMessage(reply_to_message_id=reply_to_message_id, message_thread_id=message_thread_id, quote_text=quote_text) + if reply_to_story_id: + user_id = await self.resolve_peer(chat_id) + reply_to = types.InputReplyToStory(user_id=user_id, story_id=reply_to_story_id) + + media = raw.types.InputMediaWebPage( + url=url, + force_large_media=large_media, + force_small_media=not large_media + ) + r = await self.invoke( + raw.functions.messages.SendMedia( + peer=await self.resolve_peer(chat_id), + silent=disable_notification or None, + reply_to=reply_to, + random_id=self.rnd_id(), + schedule_date=utils.datetime_to_timestamp(schedule_date), + reply_markup=await reply_markup.write(self) if reply_markup else None, + message=message, + media=media, + invert_media=invert_media, + entities=entities, + noforwards=protect_content + ) + ) + + if isinstance(r, raw.types.UpdateShortSentMessage): + peer = await self.resolve_peer(chat_id) + + peer_id = ( + peer.user_id + if isinstance(peer, raw.types.InputPeerUser) + else -peer.chat_id + ) + return types.Message( + id=r.id, + chat=types.Chat( + id=peer_id, + type=enums.ChatType.PRIVATE, + client=self + ), + text=message, + date=utils.timestamp_to_datetime(r.date), + outgoing=r.out, + reply_markup=reply_markup, + entities=[ + types.MessageEntity._parse(None, entity, {}) + for entity in entities + ] if entities else None, + client=self + ) + + for i in r.updates: + if isinstance(i, (raw.types.UpdateNewMessage, + raw.types.UpdateNewChannelMessage, + raw.types.UpdateNewScheduledMessage)): + return await types.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, raw.types.UpdateNewScheduledMessage) + )