mirror of
https://github.com/Mayuri-Chan/pyrofork.git
synced 2025-12-29 12:04:51 +00:00
Compare commits
8 commits
c09057c6f4
...
b0a8c9ce7f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b0a8c9ce7f | ||
|
|
bce191c3fd | ||
|
|
dc05f2b791 | ||
|
|
d7e13e7b18 | ||
|
|
5b9081cb08 | ||
|
|
98dab35e93 | ||
|
|
fed146f54f | ||
|
|
125f49ec7f |
25 changed files with 1191 additions and 206 deletions
|
|
@ -513,17 +513,25 @@ def pyrogram_api():
|
|||
Messages & Media
|
||||
Message
|
||||
MessageEntity
|
||||
MessageOriginChannel
|
||||
MessageOriginChat
|
||||
MessageOriginHiddenUser
|
||||
MessageOriginImport
|
||||
MessageOriginUser
|
||||
MessageOrigin
|
||||
Photo
|
||||
Thumbnail
|
||||
Audio
|
||||
AvailableEffect
|
||||
Document
|
||||
ExternalReplyInfo
|
||||
AlternativeVideo
|
||||
Animation
|
||||
Video
|
||||
Voice
|
||||
VideoNote
|
||||
Contact
|
||||
LinkPreviewOptions
|
||||
Location
|
||||
Venue
|
||||
Sticker
|
||||
|
|
@ -540,6 +548,7 @@ def pyrogram_api():
|
|||
WebPagePreview
|
||||
TranscribedAudio
|
||||
TranslatedText
|
||||
TextQuote
|
||||
Poll
|
||||
PollOption
|
||||
Dice
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ from .gift_attribute_type import GiftAttributeType
|
|||
from .listerner_types import ListenerTypes
|
||||
from .message_entity_type import MessageEntityType
|
||||
from .message_media_type import MessageMediaType
|
||||
from .message_origin_type import MessageOriginType
|
||||
from .message_service_type import MessageServiceType
|
||||
from .messages_filter import MessagesFilter
|
||||
from .next_code_type import NextCodeType
|
||||
|
|
@ -57,6 +58,7 @@ __all__ = [
|
|||
'ListenerTypes',
|
||||
'MessageEntityType',
|
||||
'MessageMediaType',
|
||||
'MessageOriginType',
|
||||
'MessageServiceType',
|
||||
'MessagesFilter',
|
||||
'NextCodeType',
|
||||
|
|
|
|||
41
pyrogram/enums/message_origin_type.py
Normal file
41
pyrogram/enums/message_origin_type.py
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram 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.
|
||||
#
|
||||
# Pyrogram 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 Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from enum import auto
|
||||
|
||||
from .auto_name import AutoName
|
||||
|
||||
|
||||
class MessageOriginType(AutoName):
|
||||
"""Message origin type enumeration used in :obj:`~pyrogram.types.MessageOrigin`."""
|
||||
|
||||
CHANNEL = auto()
|
||||
"The message was originally a post in a channel"
|
||||
|
||||
CHAT = auto()
|
||||
"The message was originally sent on behalf of a chat"
|
||||
|
||||
HIDDEN_USER = auto()
|
||||
"The message was originally sent by a user, which is hidden by their privacy settings"
|
||||
|
||||
IMPORT = auto()
|
||||
"The message was imported from a foreign chat service"
|
||||
|
||||
|
||||
USER = auto()
|
||||
"The message was originally sent by a known user"
|
||||
|
|
@ -17,14 +17,15 @@
|
|||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import raw, enums
|
||||
from pyrogram import types
|
||||
from pyrogram import utils
|
||||
from pyrogram import enums, raw, types, utils
|
||||
|
||||
from .inline_session import get_session
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class EditInlineText:
|
||||
async def edit_inline_text(
|
||||
|
|
@ -32,6 +33,7 @@ class EditInlineText:
|
|||
inline_message_id: str,
|
||||
text: str,
|
||||
parse_mode: Optional["enums.ParseMode"] = None,
|
||||
link_preview_options: "types.LinkPreviewOptions" = None,
|
||||
disable_web_page_preview: bool = None,
|
||||
reply_markup: "types.InlineKeyboardMarkup" = None,
|
||||
invert_media: bool = None
|
||||
|
|
@ -51,6 +53,9 @@ class EditInlineText:
|
|||
By default, texts are parsed using both Markdown and HTML styles.
|
||||
You can combine both syntaxes together.
|
||||
|
||||
link_preview_options (:obj:`~pyrogram.types.LinkPreviewOptions`, *optional*):
|
||||
Options used for link preview generation for the message.
|
||||
|
||||
disable_web_page_preview (``bool``, *optional*):
|
||||
Disables link previews for links in this message.
|
||||
|
||||
|
|
@ -77,6 +82,11 @@ class EditInlineText:
|
|||
inline_message_id, message.text,
|
||||
disable_web_page_preview=True)
|
||||
"""
|
||||
if disable_web_page_preview is not None:
|
||||
log.warning(
|
||||
"`disable_web_page_preview` is deprecated and will be removed in future updates. Use `link_preview_options` instead."
|
||||
)
|
||||
link_preview_options = types.LinkPreviewOptions(is_disabled=disable_web_page_preview)
|
||||
|
||||
unpacked = utils.unpack_inline_message_id(inline_message_id)
|
||||
dc_id = unpacked.dc_id
|
||||
|
|
@ -86,7 +96,7 @@ class EditInlineText:
|
|||
return await session.invoke(
|
||||
raw.functions.messages.EditInlineBotMessage(
|
||||
id=unpacked,
|
||||
no_webpage=disable_web_page_preview or None,
|
||||
no_webpage=getattr(link_preview_options, "is_disabled", None) or None,
|
||||
reply_markup=await reply_markup.write(self) if reply_markup else None,
|
||||
**await self.parser.parse(text, parse_mode),
|
||||
invert_media=invert_media
|
||||
|
|
|
|||
|
|
@ -17,12 +17,13 @@
|
|||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import logging
|
||||
from typing import Union, List, Optional
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import raw, enums
|
||||
from pyrogram import types
|
||||
from pyrogram import utils
|
||||
from pyrogram import enums, raw, types, utils
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class EditMessageText:
|
||||
|
|
@ -33,6 +34,7 @@ class EditMessageText:
|
|||
text: str,
|
||||
parse_mode: Optional["enums.ParseMode"] = None,
|
||||
entities: List["types.MessageEntity"] = None,
|
||||
link_preview_options: "types.LinkPreviewOptions" = None,
|
||||
disable_web_page_preview: bool = None,
|
||||
invert_media: bool = None,
|
||||
reply_markup: "types.InlineKeyboardMarkup" = None,
|
||||
|
|
@ -62,8 +64,8 @@ class EditMessageText:
|
|||
entities (List of :obj:`~pyrogram.types.MessageEntity`):
|
||||
List of special entities that appear in message text, which can be specified instead of *parse_mode*.
|
||||
|
||||
disable_web_page_preview (``bool``, *optional*):
|
||||
Disables link previews for links in this message.
|
||||
link_preview_options (:obj:`~pyrogram.types.LinkPreviewOptions`, *optional*):
|
||||
Options used for link preview generation for the message.
|
||||
|
||||
invert_media (``bool``, *optional*):
|
||||
Inverts the position of the media and caption.
|
||||
|
|
@ -89,11 +91,16 @@ class EditMessageText:
|
|||
chat_id, message_id, message.text,
|
||||
disable_web_page_preview=True)
|
||||
"""
|
||||
if disable_web_page_preview is not None:
|
||||
log.warning(
|
||||
"`disable_web_page_preview` is deprecated and will be removed in future updates. Use `link_preview_options` instead."
|
||||
)
|
||||
link_preview_options = types.LinkPreviewOptions(is_disabled=disable_web_page_preview)
|
||||
|
||||
rpc = raw.functions.messages.EditMessage(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
id=message_id,
|
||||
no_webpage=disable_web_page_preview or None,
|
||||
no_webpage=getattr(link_preview_options, "is_disabled", None) or None,
|
||||
invert_media=invert_media,
|
||||
reply_markup=await reply_markup.write(self) if reply_markup else None,
|
||||
**await utils.parse_text_entities(self, text, parse_mode, entities)
|
||||
|
|
|
|||
|
|
@ -17,12 +17,14 @@
|
|||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from typing import Union, List, Optional
|
||||
from typing import List, Optional, Union
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import raw, utils, enums
|
||||
from pyrogram import types
|
||||
from pyrogram import enums, raw, types, utils
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SendMessage:
|
||||
|
|
@ -32,7 +34,7 @@ class SendMessage:
|
|||
text: str,
|
||||
parse_mode: Optional["enums.ParseMode"] = None,
|
||||
entities: List["types.MessageEntity"] = None,
|
||||
disable_web_page_preview: bool = None,
|
||||
link_preview_options: "types.LinkPreviewOptions" = None,
|
||||
disable_notification: bool = None,
|
||||
message_thread_id: int = None,
|
||||
business_connection_id: str = None,
|
||||
|
|
@ -51,7 +53,8 @@ class SendMessage:
|
|||
"types.ReplyKeyboardMarkup",
|
||||
"types.ReplyKeyboardRemove",
|
||||
"types.ForceReply"
|
||||
] = None
|
||||
] = None,
|
||||
disable_web_page_preview: bool = None, # TODO: Remove later
|
||||
) -> "types.Message":
|
||||
"""Send text messages.
|
||||
|
||||
|
|
@ -74,8 +77,8 @@ class SendMessage:
|
|||
entities (List of :obj:`~pyrogram.types.MessageEntity`):
|
||||
List of special entities that appear in message text, which can be specified instead of *parse_mode*.
|
||||
|
||||
disable_web_page_preview (``bool``, *optional*):
|
||||
Disables link previews for links in this message.
|
||||
link_preview_options (:obj:`~pyrogram.types.LinkPreviewOptions`, *optional*):
|
||||
Options used for link preview generation for the message.
|
||||
|
||||
disable_notification (``bool``, *optional*):
|
||||
Sends the message silently.
|
||||
|
|
@ -166,6 +169,16 @@ class SendMessage:
|
|||
"""
|
||||
|
||||
message, entities = (await utils.parse_text_entities(self, text, parse_mode, entities)).values()
|
||||
|
||||
if disable_web_page_preview is not None or invert_media is not None:
|
||||
if disable_web_page_preview is not None:
|
||||
log.warning(
|
||||
"`disable_web_page_preview` is deprecated and will be removed in future updates. Use `link_preview_options` instead."
|
||||
)
|
||||
link_preview_options = types.LinkPreviewOptions(
|
||||
is_disabled=disable_web_page_preview,
|
||||
invert_media=invert_media
|
||||
)
|
||||
|
||||
reply_to = await utils.get_reply_to(
|
||||
client=self,
|
||||
|
|
@ -181,7 +194,7 @@ class SendMessage:
|
|||
|
||||
rpc = raw.functions.messages.SendMessage(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
no_webpage=disable_web_page_preview or None,
|
||||
no_webpage=getattr(link_preview_options, "is_disabled", None) or None,
|
||||
silent=disable_notification or None,
|
||||
reply_to=reply_to,
|
||||
random_id=self.rnd_id(),
|
||||
|
|
@ -191,7 +204,7 @@ class SendMessage:
|
|||
entities=entities,
|
||||
noforwards=protect_content,
|
||||
allow_paid_floodskip=allow_paid_broadcast,
|
||||
invert_media=invert_media,
|
||||
invert_media=getattr(link_preview_options, "invert_media", None) or None,
|
||||
effect=message_effect_id,
|
||||
)
|
||||
if business_connection_id is not None:
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class SendWebPage:
|
|||
async def send_web_page(
|
||||
self: "pyrogram.Client",
|
||||
chat_id: Union[int, str],
|
||||
url: str,
|
||||
url: str = None,
|
||||
text: str = "",
|
||||
parse_mode: Optional["enums.ParseMode"] = None,
|
||||
entities: List["types.MessageEntity"] = None,
|
||||
|
|
@ -53,7 +53,7 @@ class SendWebPage:
|
|||
"types.ForceReply"
|
||||
] = None
|
||||
) -> "types.Message":
|
||||
"""Send text Web Page Preview.
|
||||
"""Send Web Page Preview.
|
||||
|
||||
.. include:: /_includes/usable-by/users-bots.rst
|
||||
|
||||
|
|
@ -64,12 +64,13 @@ class SendWebPage:
|
|||
For a contact that exists in your Telegram address book you can use his phone number (str).
|
||||
You can also use chat public link in form of *t.me/<username>* (str).
|
||||
|
||||
url (``str``):
|
||||
Link that will be previewed.
|
||||
|
||||
text (``str``, *optional*):
|
||||
Text of the message to be sent.
|
||||
|
||||
url (``str``, *optional*):
|
||||
Link that will be previewed.
|
||||
If url not specified, the first URL found in the text will be used.
|
||||
|
||||
parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*):
|
||||
By default, texts are parsed using both Markdown and HTML styles.
|
||||
You can combine both syntaxes together.
|
||||
|
|
@ -131,7 +132,7 @@ class SendWebPage:
|
|||
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.
|
||||
:obj:`~pyrogram.types.Message`: On success, the sent message is returned.
|
||||
|
||||
Example:
|
||||
.. code-block:: python
|
||||
|
|
@ -141,6 +142,18 @@ class SendWebPage:
|
|||
"""
|
||||
|
||||
message, entities = (await utils.parse_text_entities(self, text, parse_mode, entities)).values()
|
||||
if not url:
|
||||
if entities:
|
||||
for entity in entities:
|
||||
if isinstance(entity, enums.MessageEntityType.URL):
|
||||
url = entity.url
|
||||
break
|
||||
|
||||
if not url:
|
||||
url = utils.get_first_url(message)
|
||||
|
||||
if not url:
|
||||
raise ValueError("URL not specified")
|
||||
|
||||
reply_to = await utils.get_reply_to(
|
||||
client=self,
|
||||
|
|
|
|||
|
|
@ -17,15 +17,18 @@
|
|||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Union, List, Match, Optional
|
||||
import logging
|
||||
from typing import List, Match, Optional, Union
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import raw, enums
|
||||
from pyrogram import types
|
||||
|
||||
from ... import utils
|
||||
from ..object import Object
|
||||
from ..update import Update
|
||||
from ... import utils
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class CallbackQuery(Object, Update):
|
||||
"""An incoming callback query from a callback button in an inline keyboard.
|
||||
|
|
@ -180,8 +183,9 @@ class CallbackQuery(Object, Update):
|
|||
self,
|
||||
text: str,
|
||||
parse_mode: Optional["enums.ParseMode"] = None,
|
||||
disable_web_page_preview: bool = None,
|
||||
link_preview_options: "types.LinkPreviewOptions" = None,
|
||||
reply_markup: "types.InlineKeyboardMarkup" = None,
|
||||
disable_web_page_preview: bool = None,
|
||||
business_connection_id: Optional[str] = None
|
||||
) -> Union["types.Message", bool]:
|
||||
"""Edit the text of messages attached to callback queries.
|
||||
|
|
@ -196,8 +200,8 @@ class CallbackQuery(Object, Update):
|
|||
By default, texts are parsed using both Markdown and HTML styles.
|
||||
You can combine both syntaxes together.
|
||||
|
||||
disable_web_page_preview (``bool``, *optional*):
|
||||
Disables link previews for links in this message.
|
||||
link_preview_options (:obj:`~pyrogram.types.LinkPreviewOptions`, *optional*):
|
||||
Options used for link preview generation for the message.
|
||||
|
||||
reply_markup (:obj:`~pyrogram.types.InlineKeyboardMarkup`, *optional*):
|
||||
An InlineKeyboardMarkup object.
|
||||
|
|
@ -213,6 +217,12 @@ class CallbackQuery(Object, Update):
|
|||
Raises:
|
||||
RPCError: In case of a Telegram RPC error.
|
||||
"""
|
||||
if disable_web_page_preview is not None:
|
||||
log.warning(
|
||||
"`disable_web_page_preview` is deprecated and will be removed in future updates. Use `link_preview_options` instead."
|
||||
)
|
||||
link_preview_options = types.LinkPreviewOptions(is_disabled=disable_web_page_preview)
|
||||
|
||||
if self.inline_message_id is None:
|
||||
return await self._client.edit_message_text(
|
||||
chat_id=self.message.chat.id,
|
||||
|
|
@ -220,6 +230,7 @@ class CallbackQuery(Object, Update):
|
|||
text=text,
|
||||
parse_mode=parse_mode,
|
||||
disable_web_page_preview=disable_web_page_preview,
|
||||
link_preview_options=link_preview_options,
|
||||
reply_markup=reply_markup,
|
||||
business_connection_id=getattr(self.message, "business_connection_id", None)
|
||||
)
|
||||
|
|
@ -228,7 +239,7 @@ class CallbackQuery(Object, Update):
|
|||
inline_message_id=self.inline_message_id,
|
||||
text=text,
|
||||
parse_mode=parse_mode,
|
||||
disable_web_page_preview=disable_web_page_preview,
|
||||
link_preview_options=link_preview_options,
|
||||
reply_markup=reply_markup
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -17,12 +17,15 @@
|
|||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Optional, List
|
||||
import logging
|
||||
from typing import List, Optional
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import raw, types, utils, enums
|
||||
from pyrogram import enums, raw, types, utils
|
||||
|
||||
from .input_message_content import InputMessageContent
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class InputTextMessageContent(InputMessageContent):
|
||||
"""Content of a text message to be sent as the result of an inline query.
|
||||
|
|
@ -38,8 +41,8 @@ class InputTextMessageContent(InputMessageContent):
|
|||
entities (List of :obj:`~pyrogram.types.MessageEntity`):
|
||||
List of special entities that appear in message text, which can be specified instead of *parse_mode*.
|
||||
|
||||
disable_web_page_preview (``bool``, *optional*):
|
||||
Disables link previews for links in this message.
|
||||
link_preview_options (:obj:`~pyrogram.types.LinkPreviewOptions`, *optional*):
|
||||
Options used for link preview generation for the message.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
|
|
@ -47,13 +50,21 @@ class InputTextMessageContent(InputMessageContent):
|
|||
message_text: str,
|
||||
parse_mode: Optional["enums.ParseMode"] = None,
|
||||
entities: List["types.MessageEntity"] = None,
|
||||
link_preview_options: "types.LinkPreviewOptions" = None,
|
||||
disable_web_page_preview: bool = None
|
||||
):
|
||||
super().__init__()
|
||||
|
||||
if disable_web_page_preview is not None:
|
||||
log.warning(
|
||||
"`disable_web_page_preview` is deprecated and will be removed in future updates. Use `link_preview_options` instead."
|
||||
)
|
||||
link_preview_options = types.LinkPreviewOptions(is_disabled=disable_web_page_preview)
|
||||
|
||||
self.message_text = message_text
|
||||
self.parse_mode = parse_mode
|
||||
self.entities = entities
|
||||
self.link_preview_options = link_preview_options
|
||||
self.disable_web_page_preview = disable_web_page_preview
|
||||
|
||||
async def write(self, client: "pyrogram.Client", reply_markup):
|
||||
|
|
@ -62,7 +73,7 @@ class InputTextMessageContent(InputMessageContent):
|
|||
)).values()
|
||||
|
||||
return raw.types.InputBotInlineMessageText(
|
||||
no_webpage=self.disable_web_page_preview or None,
|
||||
no_webpage=getattr(self.link_preview_options, "is_disabled", None) or None,
|
||||
reply_markup=await reply_markup.write(client) if reply_markup else None,
|
||||
message=message,
|
||||
entities=entities
|
||||
|
|
|
|||
|
|
@ -27,16 +27,24 @@ from .contact import Contact
|
|||
from .contact_registered import ContactRegistered
|
||||
from .dice import Dice
|
||||
from .document import Document
|
||||
from .external_reply_info import ExternalReplyInfo
|
||||
from .game import Game
|
||||
from .giveaway import Giveaway
|
||||
from .giveaway_launched import GiveawayLaunched
|
||||
from .giveaway_result import GiveawayResult
|
||||
from .link_preview_options import LinkPreviewOptions
|
||||
from .location import Location
|
||||
from .media_area import MediaArea
|
||||
from .media_area_channel_post import MediaAreaChannelPost
|
||||
from .media_area_coordinates import MediaAreaCoordinates
|
||||
from .message import Message
|
||||
from .message_entity import MessageEntity
|
||||
from .message_origin import MessageOrigin
|
||||
from .message_origin_channel import MessageOriginChannel
|
||||
from .message_origin_chat import MessageOriginChat
|
||||
from .message_origin_hidden_user import MessageOriginHiddenUser
|
||||
from .message_origin_import import MessageOriginImport
|
||||
from .message_origin_user import MessageOriginUser
|
||||
from .photo import Photo
|
||||
from .poll import Poll
|
||||
from .poll_option import PollOption
|
||||
|
|
@ -71,6 +79,7 @@ from .wallpaper import Wallpaper
|
|||
from .wallpaper_settings import WallpaperSettings
|
||||
from .transcribed_audio import TranscribedAudio
|
||||
from .translated_text import TranslatedText
|
||||
from .text_quote import TextQuote
|
||||
|
||||
__all__ = [
|
||||
"AlternativeVideo",
|
||||
|
|
@ -82,16 +91,24 @@ __all__ = [
|
|||
"Contact",
|
||||
"ContactRegistered",
|
||||
"Document",
|
||||
"ExternalReplyInfo",
|
||||
"Game",
|
||||
"Giveaway",
|
||||
"GiveawayLaunched",
|
||||
"GiveawayResult",
|
||||
"LinkPreviewOptions",
|
||||
"Location",
|
||||
"MediaArea",
|
||||
"MediaAreaChannelPost",
|
||||
"MediaAreaCoordinates",
|
||||
"Message",
|
||||
"MessageEntity",
|
||||
"MessageOrigin",
|
||||
"MessageOriginChannel",
|
||||
"MessageOriginChat",
|
||||
"MessageOriginHiddenUser",
|
||||
"MessageOriginImport",
|
||||
"MessageOriginUser",
|
||||
"Photo",
|
||||
"Thumbnail",
|
||||
"StrippedThumbnail",
|
||||
|
|
@ -126,5 +143,6 @@ __all__ = [
|
|||
"Wallpaper",
|
||||
"WallpaperSettings",
|
||||
"TranscribedAudio",
|
||||
"TranslatedText"
|
||||
"TranslatedText",
|
||||
"TextQuote"
|
||||
]
|
||||
|
|
|
|||
324
pyrogram/types/messages_and_media/external_reply_info.py
Normal file
324
pyrogram/types/messages_and_media/external_reply_info.py
Normal file
|
|
@ -0,0 +1,324 @@
|
|||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram 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.
|
||||
#
|
||||
# Pyrogram 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 Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Dict, Optional
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import enums, raw, types, utils
|
||||
|
||||
from ..object import Object
|
||||
|
||||
|
||||
class ExternalReplyInfo(Object):
|
||||
"""This object contains information about a message that is being replied to, which may come from another chat or forum topic.
|
||||
|
||||
Parameters:
|
||||
origin (:obj:`~pyrogram.types.MessageOrigin`, *optional*):
|
||||
Origin of the message replied to by the given message.
|
||||
|
||||
chat (:obj:`~pyrogram.types.Chat`, *optional*):
|
||||
Chat the original message belongs to.
|
||||
Available only if the chat is a supergroup or a channel.
|
||||
|
||||
message_id (``int``, *optional*):
|
||||
Unique message identifier inside the original chat.
|
||||
Available only if the original chat is a supergroup or a channel.
|
||||
|
||||
link_preview_options (:obj:`~pyrogram.types.LinkPreviewOptions`, *optional*):
|
||||
Options used for link preview generation for the original message, if it is a text message.
|
||||
|
||||
media (:obj:`~pyrogram.enums.MessageMediaType`, *optional*):
|
||||
The message is a media message.
|
||||
This field will contain the enumeration type of the media message.
|
||||
You can use ``media = getattr(message, message.media.value)`` to access the media message.
|
||||
|
||||
animation (:obj:`~pyrogram.types.Animation`, *optional*):
|
||||
Message is an animation, information about the animation.
|
||||
|
||||
audio (:obj:`~pyrogram.types.Audio`, *optional*):
|
||||
Message is an audio file, information about the file.
|
||||
|
||||
document (:obj:`~pyrogram.types.Document`, *optional*):
|
||||
Message is a general file, information about the file.
|
||||
|
||||
paid_media (:obj:`~pyrogram.types.PaidMediaInfo`, *optional*):
|
||||
Message contains paid media; information about the paid media.
|
||||
|
||||
photo (:obj:`~pyrogram.types.Photo`, *optional*):
|
||||
Message is a photo, information about the photo.
|
||||
|
||||
sticker (:obj:`~pyrogram.types.Sticker`, *optional*):
|
||||
Message is a sticker, information about the sticker.
|
||||
|
||||
story (:obj:`~pyrogram.types.Story`, *optional*):
|
||||
Message is a forwarded story.
|
||||
|
||||
video (:obj:`~pyrogram.types.Video`, *optional*):
|
||||
Message is a video, information about the video.
|
||||
|
||||
video_note (:obj:`~pyrogram.types.VideoNote`, *optional*):
|
||||
Message is a video note, information about the video message.
|
||||
|
||||
voice (:obj:`~pyrogram.types.Voice`, *optional*):
|
||||
Message is a voice message, information about the file.
|
||||
|
||||
has_media_spoiler (``bool``, *optional*):
|
||||
True, if the message media is covered by a spoiler animation.
|
||||
|
||||
contact (:obj:`~pyrogram.types.Contact`, *optional*):
|
||||
Message is a shared contact, information about the contact.
|
||||
|
||||
dice (:obj:`~pyrogram.types.Dice`, *optional*):
|
||||
A dice containing a value that is randomly generated by Telegram.
|
||||
|
||||
game (:obj:`~pyrogram.types.Game`, *optional*):
|
||||
Message is a game, information about the game.
|
||||
|
||||
giveaway (:obj:`~pyrogram.types.Giveaway`, *optional*):
|
||||
Message is a scheduled giveaway, information about the giveaway.
|
||||
|
||||
giveaway_winners (:obj:`~pyrogram.types.GiveawayWinners`, *optional*):
|
||||
A giveaway with public winners was completed
|
||||
|
||||
invoice (:obj:`~pyrogram.types.Invoice`, *optional*):
|
||||
Message is a invoice, information about the invoice.
|
||||
`More about payments » <https://core.telegram.org/bots/api#payments>`_
|
||||
|
||||
location (:obj:`~pyrogram.types.Location`, *optional*):
|
||||
Message is a shared location, information about the location.
|
||||
|
||||
poll (:obj:`~pyrogram.types.Poll`, *optional*):
|
||||
Message is a native poll, information about the poll.
|
||||
|
||||
venue (:obj:`~pyrogram.types.Venue`, *optional*):
|
||||
Message is a venue, information about the venue.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
client: "pyrogram.Client" = None,
|
||||
origin: "types.MessageOrigin" = None,
|
||||
chat: "types.Chat" = None,
|
||||
message_id: int,
|
||||
link_preview_options: Optional["types.LinkPreviewOptions"] = None,
|
||||
media: Optional["enums.MessageMediaType"] = None,
|
||||
animation: Optional["types.Animation"] = None,
|
||||
audio: Optional["types.Audio"] = None,
|
||||
document: Optional["types.Document"] = None,
|
||||
paid_media: Optional["types.PaidMediaInfo"] = None,
|
||||
photo: Optional["types.Photo"] = None,
|
||||
sticker: Optional["types.Sticker"] = None,
|
||||
story: Optional["types.Story"] = None,
|
||||
video: Optional["types.Video"] = None,
|
||||
video_note: Optional["types.VideoNote"] = None,
|
||||
voice: Optional["types.Voice"] = None,
|
||||
has_media_spoiler: Optional[bool] = None,
|
||||
contact: Optional["types.Contact"] = None,
|
||||
dice: Optional["types.Dice"] = None,
|
||||
game: Optional["types.Game"] = None,
|
||||
giveaway: Optional["types.Giveaway"] = None,
|
||||
giveaway_winners: Optional["types.GiveawayWinners"] = None,
|
||||
invoice: Optional["types.Invoice"] = None,
|
||||
location: Optional["types.Location"] = None,
|
||||
poll: Optional["types.Poll"] = None,
|
||||
venue: Optional["types.Venue"] = None,
|
||||
):
|
||||
super().__init__(client)
|
||||
|
||||
self.origin = origin
|
||||
self.chat = chat
|
||||
self.message_id = message_id
|
||||
self.link_preview_options = link_preview_options
|
||||
self.media = media
|
||||
self.animation = animation
|
||||
self.audio = audio
|
||||
self.document = document
|
||||
self.paid_media = paid_media
|
||||
self.photo = photo
|
||||
self.sticker = sticker
|
||||
self.story = story
|
||||
self.video = video
|
||||
self.video_note = video_note
|
||||
self.voice = voice
|
||||
self.has_media_spoiler = has_media_spoiler
|
||||
self.contact = contact
|
||||
self.dice = dice
|
||||
self.game = game
|
||||
self.giveaway = giveaway
|
||||
self.giveaway_winners = giveaway_winners
|
||||
self.invoice = invoice
|
||||
self.location = location
|
||||
self.poll = poll
|
||||
self.venue = venue
|
||||
|
||||
@staticmethod
|
||||
async def _parse(
|
||||
client,
|
||||
reply: "raw.types.MessageReplyHeader",
|
||||
users: Dict[int, "raw.types.User"],
|
||||
chats: Dict[int, "raw.types.Chat"],
|
||||
) -> Optional["ExternalReplyInfo"]:
|
||||
if not isinstance(reply, raw.types.MessageReplyHeader):
|
||||
return None
|
||||
|
||||
if not reply.reply_from:
|
||||
return None
|
||||
|
||||
animation = None
|
||||
audio = None
|
||||
document = None
|
||||
paid_media = None
|
||||
photo = None
|
||||
sticker = None
|
||||
story = None
|
||||
video = None
|
||||
video_note = None
|
||||
voice = None
|
||||
contact = None
|
||||
dice = None
|
||||
game = None
|
||||
giveaway = None
|
||||
giveaway_winners = None
|
||||
invoice = None
|
||||
location = None
|
||||
poll = None
|
||||
venue = None
|
||||
|
||||
media = reply.reply_media
|
||||
media_type = None
|
||||
has_media_spoiler = None
|
||||
|
||||
if media:
|
||||
if isinstance(media, raw.types.MessageMediaPhoto):
|
||||
photo = types.Photo._parse(client, media.photo, media.ttl_seconds)
|
||||
media_type = enums.MessageMediaType.PHOTO
|
||||
has_media_spoiler = media.spoiler
|
||||
elif isinstance(media, raw.types.MessageMediaGeo):
|
||||
location = types.Location._parse(client, media.geo)
|
||||
media_type = enums.MessageMediaType.LOCATION
|
||||
elif isinstance(media, raw.types.MessageMediaContact):
|
||||
contact = types.Contact._parse(client, media)
|
||||
media_type = enums.MessageMediaType.CONTACT
|
||||
elif isinstance(media, raw.types.MessageMediaVenue):
|
||||
venue = types.Venue._parse(client, media)
|
||||
media_type = enums.MessageMediaType.VENUE
|
||||
elif isinstance(media, raw.types.MessageMediaGame):
|
||||
game = types.Game._parse(client, media)
|
||||
media_type = enums.MessageMediaType.GAME
|
||||
elif isinstance(media, raw.types.MessageMediaGiveaway):
|
||||
giveaway = types.Giveaway._parse(client, media, chats)
|
||||
media_type = enums.MessageMediaType.GIVEAWAY
|
||||
elif isinstance(media, raw.types.MessageMediaGiveawayResults):
|
||||
giveaway_winners = await types.GiveawayWinners._parse(client, media, users, chats)
|
||||
media_type = enums.MessageMediaType.GIVEAWAY_WINNERS
|
||||
elif isinstance(media, raw.types.MessageMediaInvoice):
|
||||
invoice = types.Invoice._parse(client, media)
|
||||
media_type = enums.MessageMediaType.INVOICE
|
||||
elif isinstance(media, raw.types.MessageMediaStory):
|
||||
story = await types.Story._parse(client, media, media.peer, users, chats)
|
||||
media_type = enums.MessageMediaType.STORY
|
||||
elif isinstance(media, raw.types.MessageMediaDocument):
|
||||
doc = media.document
|
||||
|
||||
if isinstance(doc, raw.types.Document):
|
||||
attributes = {type(i): i for i in doc.attributes}
|
||||
|
||||
file_name = getattr(
|
||||
attributes.get(
|
||||
raw.types.DocumentAttributeFilename, None
|
||||
), "file_name", None
|
||||
)
|
||||
|
||||
if raw.types.DocumentAttributeAnimated in attributes:
|
||||
video_attributes = attributes.get(raw.types.DocumentAttributeVideo, None)
|
||||
animation = types.Animation._parse(client, doc, video_attributes, file_name)
|
||||
media_type = enums.MessageMediaType.ANIMATION
|
||||
has_media_spoiler = media.spoiler
|
||||
elif raw.types.DocumentAttributeSticker in attributes:
|
||||
sticker = await types.Sticker._parse(client, doc, attributes)
|
||||
media_type = enums.MessageMediaType.STICKER
|
||||
elif raw.types.DocumentAttributeVideo in attributes:
|
||||
video_attributes = attributes[raw.types.DocumentAttributeVideo]
|
||||
|
||||
if video_attributes.round_message:
|
||||
video_note = types.VideoNote._parse(client, doc, video_attributes, media.ttl_seconds)
|
||||
media_type = enums.MessageMediaType.VIDEO_NOTE
|
||||
else:
|
||||
video = types.Video._parse(client, doc, video_attributes, file_name, media.ttl_seconds, media.video_cover, media.video_timestamp, media.alt_documents)
|
||||
media_type = enums.MessageMediaType.VIDEO
|
||||
has_media_spoiler = media.spoiler
|
||||
elif raw.types.DocumentAttributeAudio in attributes:
|
||||
audio_attributes = attributes[raw.types.DocumentAttributeAudio]
|
||||
|
||||
if audio_attributes.voice:
|
||||
voice = types.Voice._parse(client, doc, audio_attributes, media.ttl_seconds)
|
||||
media_type = enums.MessageMediaType.VOICE
|
||||
else:
|
||||
audio = types.Audio._parse(client, doc, audio_attributes, file_name)
|
||||
media_type = enums.MessageMediaType.AUDIO
|
||||
else:
|
||||
document = types.Document._parse(client, doc, file_name)
|
||||
media_type = enums.MessageMediaType.DOCUMENT
|
||||
elif isinstance(media, raw.types.MessageMediaPoll):
|
||||
poll = types.Poll._parse(client, media)
|
||||
media_type = enums.MessageMediaType.POLL
|
||||
elif isinstance(media, raw.types.MessageMediaDice):
|
||||
dice = types.Dice._parse(client, media)
|
||||
media_type = enums.MessageMediaType.DICE
|
||||
elif isinstance(media, raw.types.MessageMediaPaidMedia):
|
||||
paid_media = types.PaidMediaInfo._parse(client, media)
|
||||
media_type = enums.MessageMediaType.PAID_MEDIA
|
||||
else:
|
||||
media = None
|
||||
|
||||
return ExternalReplyInfo(
|
||||
origin=types.MessageOrigin._parse(
|
||||
client,
|
||||
reply.reply_from,
|
||||
users,
|
||||
chats,
|
||||
),
|
||||
chat=types.Chat._parse_chat(
|
||||
client,
|
||||
chats.get(utils.get_raw_peer_id(reply.reply_to_peer_id)),
|
||||
),
|
||||
message_id=reply.reply_to_msg_id,
|
||||
link_preview_options=types.LinkPreviewOptions._parse(reply.reply_media),
|
||||
media=media_type,
|
||||
animation=animation,
|
||||
audio=audio,
|
||||
document=document,
|
||||
paid_media=paid_media,
|
||||
photo=photo,
|
||||
sticker=sticker,
|
||||
story=story,
|
||||
video=video,
|
||||
video_note=video_note,
|
||||
voice=voice,
|
||||
has_media_spoiler=has_media_spoiler,
|
||||
contact=contact,
|
||||
dice=dice,
|
||||
game=game,
|
||||
giveaway=giveaway,
|
||||
giveaway_winners=giveaway_winners,
|
||||
invoice=invoice,
|
||||
location=location,
|
||||
poll=poll,
|
||||
venue=venue
|
||||
)
|
||||
|
|
@ -69,12 +69,11 @@ class Game(Object):
|
|||
self.animation = animation
|
||||
|
||||
@staticmethod
|
||||
def _parse(client, message: "raw.types.Message") -> "Game":
|
||||
game: "raw.types.Game" = message.media.game
|
||||
def _parse(client, media: "raw.types.MessageMediaGame") -> "Game":
|
||||
animation = None
|
||||
|
||||
if game.document:
|
||||
attributes = {type(i): i for i in game.document.attributes}
|
||||
if media.game.document:
|
||||
attributes = {type(i): i for i in media.game.document.attributes}
|
||||
|
||||
file_name = getattr(
|
||||
attributes.get(
|
||||
|
|
@ -84,17 +83,17 @@ class Game(Object):
|
|||
|
||||
animation = types.Animation._parse(
|
||||
client,
|
||||
game.document,
|
||||
media.game.document,
|
||||
attributes.get(raw.types.DocumentAttributeVideo, None),
|
||||
file_name
|
||||
)
|
||||
|
||||
return Game(
|
||||
id=game.id,
|
||||
title=game.title,
|
||||
short_name=game.short_name,
|
||||
description=game.description,
|
||||
photo=types.Photo._parse(client, game.photo),
|
||||
id=media.game.id,
|
||||
title=media.game.title,
|
||||
short_name=media.game.short_name,
|
||||
description=media.game.description,
|
||||
photo=types.Photo._parse(client, media.game.photo),
|
||||
animation=animation,
|
||||
client=client
|
||||
)
|
||||
|
|
|
|||
|
|
@ -73,7 +73,6 @@ class Giveaway(Object):
|
|||
stars: int = None,
|
||||
additional_price: str = None,
|
||||
allowed_countries: List[str] = None,
|
||||
private_channel_ids: List[int] = None,
|
||||
is_winners_hidden: bool = None
|
||||
):
|
||||
super().__init__(client)
|
||||
|
|
@ -86,28 +85,12 @@ class Giveaway(Object):
|
|||
self.new_subscribers = new_subscribers
|
||||
self.additional_price = additional_price
|
||||
self.allowed_countries = allowed_countries
|
||||
self.private_channel_ids = private_channel_ids
|
||||
self.is_winners_hidden = is_winners_hidden
|
||||
|
||||
@staticmethod
|
||||
async def _parse(client, message: "raw.types.Message") -> "Giveaway":
|
||||
async def _parse(client, message: "raw.types.Message", chats: dict) -> "Giveaway":
|
||||
giveaway: "raw.types.MessageMediaGiveaway" = message.media
|
||||
chats = []
|
||||
private_ids = []
|
||||
for raw_chat_id in giveaway.channels:
|
||||
chat_id = utils.get_channel_id(raw_chat_id)
|
||||
try:
|
||||
chat = await client.invoke(
|
||||
raw.functions.channels.GetChannels(
|
||||
id=[await client.resolve_peer(chat_id)]
|
||||
)
|
||||
)
|
||||
except FloodWait as e:
|
||||
await asyncio.sleep(e.value)
|
||||
except Exception:
|
||||
private_ids.append(chat_id)
|
||||
else:
|
||||
chats.append(types.Chat._parse_chat(client, chat.chats[0]))
|
||||
chats = types.List([types.Chat._parse_channel_chat(client, chats.get(i)) for i in giveaway.channels])
|
||||
|
||||
return Giveaway(
|
||||
chats=chats,
|
||||
|
|
@ -118,7 +101,6 @@ class Giveaway(Object):
|
|||
new_subscribers=giveaway.only_new_subscribers,
|
||||
additional_price=giveaway.prize_description,
|
||||
allowed_countries=giveaway.countries_iso2 if len(giveaway.countries_iso2) > 0 else None,
|
||||
private_channel_ids=private_ids if len(private_ids) > 0 else None,
|
||||
is_winners_hidden=not giveaway.winners_are_visible,
|
||||
client=client
|
||||
)
|
||||
|
|
|
|||
87
pyrogram/types/messages_and_media/link_preview_options.py
Normal file
87
pyrogram/types/messages_and_media/link_preview_options.py
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram 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.
|
||||
#
|
||||
# Pyrogram 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 Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from pyrogram import raw
|
||||
|
||||
from ..object import Object
|
||||
|
||||
|
||||
class LinkPreviewOptions(Object):
|
||||
"""Describes the options used for link preview generation.
|
||||
|
||||
Parameters:
|
||||
is_disabled (``bool``, *optional*):
|
||||
True, if the link preview is disabled.
|
||||
|
||||
url (``str``, *optional*):
|
||||
URL to use for the link preview.
|
||||
If empty, then the first URL found in the message text will be used.
|
||||
|
||||
prefer_small_media (``bool``, *optional*):
|
||||
True, if the media in the link preview is suppposed to be shrunk.
|
||||
Ignored if the URL isn't explicitly specified or media size change isn't supported for the preview.
|
||||
|
||||
prefer_large_media (``bool``, *optional*):
|
||||
True, if the media in the link preview is suppposed to be enlarged.
|
||||
Ignored if the URL isn't explicitly specified or media size change isn't supported for the preview.
|
||||
|
||||
invert_media (``bool``, *optional*):
|
||||
True, if the link preview must be shown above the message text.
|
||||
Otherwise, the link preview will be shown below the message text.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
is_disabled: bool = None,
|
||||
url: str = None,
|
||||
prefer_small_media: bool = None,
|
||||
prefer_large_media: bool = None,
|
||||
invert_media: bool = None
|
||||
):
|
||||
super().__init__()
|
||||
|
||||
self.is_disabled = is_disabled
|
||||
self.url = url
|
||||
self.prefer_small_media = prefer_small_media
|
||||
self.prefer_large_media = prefer_large_media
|
||||
self.invert_media = invert_media
|
||||
|
||||
@staticmethod
|
||||
def _parse(
|
||||
media: "raw.types.MessageMediaWebPage",
|
||||
url: str = None,
|
||||
invert_media: bool = None
|
||||
) -> Optional["LinkPreviewOptions"]:
|
||||
if isinstance(media, raw.types.MessageMediaWebPage) and not isinstance(media.webpage, raw.types.WebPageNotModified):
|
||||
return LinkPreviewOptions(
|
||||
is_disabled=False,
|
||||
url=media.webpage.url,
|
||||
prefer_small_media=media.force_small_media,
|
||||
prefer_large_media=media.force_large_media,
|
||||
invert_media=invert_media,
|
||||
)
|
||||
|
||||
if url:
|
||||
return LinkPreviewOptions(
|
||||
is_disabled=True,
|
||||
url=url,
|
||||
invert_media=invert_media,
|
||||
)
|
||||
|
|
@ -88,23 +88,8 @@ class Message(Object, Update):
|
|||
Topic the message belongs to.
|
||||
only returned using when client.get_messages.
|
||||
|
||||
forward_from (:obj:`~pyrogram.types.User`, *optional*):
|
||||
For forwarded messages, sender of the original message.
|
||||
|
||||
forward_sender_name (``str``, *optional*):
|
||||
For messages forwarded from users who have hidden their accounts, name of the user.
|
||||
|
||||
forward_from_chat (:obj:`~pyrogram.types.Chat`, *optional*):
|
||||
For messages forwarded from channels, information about the original channel. For messages forwarded from anonymous group administrators, information about the original supergroup.
|
||||
|
||||
forward_from_message_id (``int``, *optional*):
|
||||
For messages forwarded from channels, identifier of the original message in the channel.
|
||||
|
||||
forward_signature (``str``, *optional*):
|
||||
For messages forwarded from channels, signature of the post author if present.
|
||||
|
||||
forward_date (:py:obj:`~datetime.datetime`, *optional*):
|
||||
For forwarded messages, date the original message was sent.
|
||||
forward_origin (:obj:`~pyrogram.types.MessageOrigin`, *optional*):
|
||||
Information about the original message for forwarded messages.
|
||||
|
||||
is_topic_message (``bool``, *optional*):
|
||||
True, if the message is sent to a forum topic
|
||||
|
|
@ -187,11 +172,8 @@ class Message(Object, Update):
|
|||
For messages with a caption, special entities like usernames, URLs, bot commands, etc. that appear
|
||||
in the caption.
|
||||
|
||||
quote_text (``str``, *optional*):
|
||||
Quoted reply text.
|
||||
|
||||
quote_entities (List of :obj:`~pyrogram.types.MessageEntity`, *optional*):
|
||||
For quote text, special entities like usernames, URLs, bot commands, etc. that appear in the quote text.
|
||||
quote (:obj:`~pyrogram.types.TextQuote`, *optional*):
|
||||
Chosen quote from the replied message.
|
||||
|
||||
effect_id (``str``, *optional*):
|
||||
Unique identifier of the message effect added to the message.
|
||||
|
|
@ -260,6 +242,9 @@ class Message(Object, Update):
|
|||
venue (:obj:`~pyrogram.types.Venue`, *optional*):
|
||||
Message is a venue, information about the venue.
|
||||
|
||||
link_preview_options (:obj:`~pyrogram.types.LinkPreviewOptions`, *optional*):
|
||||
Options used for link preview generation for the message.
|
||||
|
||||
poll (:obj:`~pyrogram.types.Poll`, *optional*):
|
||||
Message is a native poll, information about the poll.
|
||||
|
||||
|
|
@ -336,6 +321,9 @@ class Message(Object, Update):
|
|||
Messages sent from yourself to other chats are outgoing (*outgoing* is True).
|
||||
An exception is made for your own personal chat; messages sent there will be incoming.
|
||||
|
||||
external_reply (:obj:`~pyrogram.types.ExternalReplyInfo`, *optional*):
|
||||
Information about the message that is being replied to, which may come from another chat or forum topic.
|
||||
|
||||
matches (List of regex Matches, *optional*):
|
||||
A list containing all `Match Objects <https://docs.python.org/3/library/re.html#match-objects>`_ that match
|
||||
the text of this message. Only applicable when using :obj:`Filters.regex <pyrogram.Filters.regex>`.
|
||||
|
|
@ -451,12 +439,7 @@ class Message(Object, Update):
|
|||
date: datetime = None,
|
||||
chat: "types.Chat" = None,
|
||||
topic: "types.ForumTopic" = None,
|
||||
forward_from: "types.User" = None,
|
||||
forward_sender_name: str = None,
|
||||
forward_from_chat: "types.Chat" = None,
|
||||
forward_from_message_id: int = None,
|
||||
forward_signature: str = None,
|
||||
forward_date: datetime = None,
|
||||
forward_origin: "types.MessageOrigin" = None,
|
||||
is_topic_message: bool = None,
|
||||
reply_to_chat_id: int = None,
|
||||
reply_to_message_id: int = None,
|
||||
|
|
@ -481,8 +464,7 @@ class Message(Object, Update):
|
|||
text: Str = None,
|
||||
entities: List["types.MessageEntity"] = None,
|
||||
caption_entities: List["types.MessageEntity"] = None,
|
||||
quote_text: str = None,
|
||||
quote_entities: List["types.MessageEntity"] = None,
|
||||
quote: "types.TextQuote" = None,
|
||||
effect_id: str = None,
|
||||
invert_media: bool = None,
|
||||
audio: "types.Audio" = None,
|
||||
|
|
@ -512,6 +494,7 @@ class Message(Object, Update):
|
|||
contact: "types.Contact" = None,
|
||||
location: "types.Location" = None,
|
||||
venue: "types.Venue" = None,
|
||||
link_preview_options: "types.LinkPreviewOptions" = None,
|
||||
poll: "types.Poll" = None,
|
||||
dice: "types.Dice" = None,
|
||||
new_chat_members: List["types.User"] = None,
|
||||
|
|
@ -531,6 +514,7 @@ class Message(Object, Update):
|
|||
forwards: int = None,
|
||||
via_bot: "types.User" = None,
|
||||
outgoing: bool = None,
|
||||
external_reply: Optional["types.ExternalReplyInfo"] = None,
|
||||
matches: List[Match] = None,
|
||||
command: List[str] = None,
|
||||
bot_allowed: "types.BotAllowed" = None,
|
||||
|
|
@ -570,13 +554,8 @@ class Message(Object, Update):
|
|||
self.sender_business_bot = sender_business_bot
|
||||
self.date = date
|
||||
self.chat = chat
|
||||
self.topic = topic
|
||||
self.forward_from = forward_from
|
||||
self.forward_sender_name = forward_sender_name
|
||||
self.forward_from_chat = forward_from_chat
|
||||
self.forward_from_message_id = forward_from_message_id
|
||||
self.forward_signature = forward_signature
|
||||
self.forward_date = forward_date
|
||||
self.forward_origin = forward_origin
|
||||
self.external_reply = external_reply
|
||||
self.is_topic_message = is_topic_message
|
||||
self.reply_to_chat_id = reply_to_chat_id
|
||||
self.reply_to_message_id = reply_to_message_id
|
||||
|
|
@ -601,8 +580,7 @@ class Message(Object, Update):
|
|||
self.text = text
|
||||
self.entities = entities
|
||||
self.caption_entities = caption_entities
|
||||
self.quote_text = quote_text
|
||||
self.quote_entities = quote_entities
|
||||
self.quote = quote
|
||||
self.effect_id = effect_id
|
||||
self.invert_media = invert_media
|
||||
self.audio = audio
|
||||
|
|
@ -633,6 +611,7 @@ class Message(Object, Update):
|
|||
self.contact = contact
|
||||
self.location = location
|
||||
self.venue = venue
|
||||
self.link_preview_options = link_preview_options
|
||||
self.poll = poll
|
||||
self.dice = dice
|
||||
self.new_chat_members = new_chat_members
|
||||
|
|
@ -1008,31 +987,18 @@ class Message(Object, Update):
|
|||
entities = types.List(filter(lambda x: x is not None, entities))
|
||||
|
||||
sender_business_bot = None
|
||||
forward_from = None
|
||||
forward_sender_name = None
|
||||
forward_from_chat = None
|
||||
forward_from_message_id = None
|
||||
forward_signature = None
|
||||
forward_date = None
|
||||
is_topic_message = None
|
||||
|
||||
forward_header = message.fwd_from # type: raw.types.MessageFwdHeader
|
||||
forward_origin = None
|
||||
|
||||
if forward_header:
|
||||
forward_date = utils.timestamp_to_datetime(forward_header.date)
|
||||
|
||||
if forward_header.from_id:
|
||||
raw_peer_id = utils.get_raw_peer_id(forward_header.from_id)
|
||||
peer_id = utils.get_peer_id(forward_header.from_id)
|
||||
|
||||
if peer_id > 0:
|
||||
forward_from = types.User._parse(client, users[raw_peer_id])
|
||||
else:
|
||||
forward_from_chat = types.Chat._parse_channel_chat(client, chats[raw_peer_id])
|
||||
forward_from_message_id = forward_header.channel_post
|
||||
forward_signature = forward_header.post_author
|
||||
elif forward_header.from_name:
|
||||
forward_sender_name = forward_header.from_name
|
||||
forward_origin = types.MessageOrigin._parse(
|
||||
client,
|
||||
forward_header,
|
||||
users,
|
||||
chats,
|
||||
)
|
||||
|
||||
photo = None
|
||||
paid_media = None
|
||||
|
|
@ -1053,6 +1019,7 @@ class Message(Object, Update):
|
|||
web_page_preview = None
|
||||
sticker = None
|
||||
document = None
|
||||
link_preview_options = None
|
||||
poll = None
|
||||
dice = None
|
||||
|
||||
|
|
@ -1075,10 +1042,10 @@ class Message(Object, Update):
|
|||
venue = types.Venue._parse(client, media)
|
||||
media_type = enums.MessageMediaType.VENUE
|
||||
elif isinstance(media, raw.types.MessageMediaGame):
|
||||
game = types.Game._parse(client, message)
|
||||
game = types.Game._parse(client, media)
|
||||
media_type = enums.MessageMediaType.GAME
|
||||
elif isinstance(media, raw.types.MessageMediaGiveaway):
|
||||
giveaway = await types.Giveaway._parse(client, message)
|
||||
giveaway = await types.Giveaway._parse(client, message, chats)
|
||||
media_type = enums.MessageMediaType.GIVEAWAY
|
||||
elif isinstance(media, raw.types.MessageMediaGiveawayResults):
|
||||
giveaway_result = await types.GiveawayResult._parse(client, message.media)
|
||||
|
|
@ -1165,6 +1132,12 @@ class Message(Object, Update):
|
|||
else:
|
||||
media = None
|
||||
|
||||
link_preview_options = types.LinkPreviewOptions._parse(
|
||||
media,
|
||||
getattr(getattr(media, "webpage", None), "url", utils.get_first_url(message.message)),
|
||||
message.invert_media
|
||||
)
|
||||
|
||||
reply_markup = message.reply_markup
|
||||
|
||||
if reply_markup:
|
||||
|
|
@ -1219,12 +1192,7 @@ class Message(Object, Update):
|
|||
author_signature=message.post_author,
|
||||
has_protected_content=message.noforwards,
|
||||
has_media_spoiler=has_media_spoiler,
|
||||
forward_from=forward_from,
|
||||
forward_sender_name=forward_sender_name,
|
||||
forward_from_chat=forward_from_chat,
|
||||
forward_from_message_id=forward_from_message_id,
|
||||
forward_signature=forward_signature,
|
||||
forward_date=forward_date,
|
||||
forward_origin=forward_origin,
|
||||
is_topic_message=is_topic_message,
|
||||
mentioned=message.mentioned,
|
||||
scheduled=is_scheduled,
|
||||
|
|
@ -1253,6 +1221,7 @@ class Message(Object, Update):
|
|||
web_page_preview=web_page_preview,
|
||||
sticker=sticker,
|
||||
document=document,
|
||||
link_preview_options=link_preview_options,
|
||||
poll=poll,
|
||||
dice=dice,
|
||||
views=message.views,
|
||||
|
|
@ -1269,11 +1238,19 @@ class Message(Object, Update):
|
|||
parsed_message.sender_chat = sender_chat
|
||||
|
||||
if message.reply_to:
|
||||
parsed_message.external_reply = await types.ExternalReplyInfo._parse(
|
||||
client,
|
||||
message.reply_to,
|
||||
users,
|
||||
chats
|
||||
)
|
||||
if isinstance(message.reply_to, raw.types.MessageReplyHeader):
|
||||
parsed_message.quote_text = message.reply_to.quote_text
|
||||
if len(message.reply_to.quote_entities) > 0:
|
||||
quote_entities = [types.MessageEntity._parse(client, entity, users) for entity in message.reply_to.quote_entities]
|
||||
parsed_message.quote_entities = types.List(filter(lambda x: x is not None, quote_entities))
|
||||
if message.reply_to.quote:
|
||||
parsed_message.quote = types.TextQuote._parse(
|
||||
client,
|
||||
users,
|
||||
message.reply_to
|
||||
)
|
||||
if message.reply_to.forum_topic:
|
||||
if message.reply_to.reply_to_top_id:
|
||||
thread_id = message.reply_to.reply_to_top_id
|
||||
|
|
@ -1309,20 +1286,15 @@ class Message(Object, Update):
|
|||
|
||||
if replies:
|
||||
if parsed_message.reply_to_message_id:
|
||||
if rtci is not None and parsed_message.chat.id != reply_to_chat_id:
|
||||
key = (reply_to_chat_id, message.reply_to.reply_to_msg_id)
|
||||
reply_to_params = {"chat_id": key[0], 'message_ids': key[1]}
|
||||
else:
|
||||
key = (parsed_message.chat.id, parsed_message.reply_to_message_id)
|
||||
reply_to_params = {'chat_id': key[0], 'reply_to_message_ids': message.id}
|
||||
|
||||
try:
|
||||
key = (parsed_message.chat.id, parsed_message.reply_to_message_id)
|
||||
reply_to_message = client.message_cache[key]
|
||||
|
||||
if not reply_to_message:
|
||||
reply_to_message = await client.get_messages(
|
||||
replies=replies - 1,
|
||||
**reply_to_params
|
||||
parsed_message.chat.id,
|
||||
reply_to_message_ids=message.id,
|
||||
replies=replies - 1
|
||||
)
|
||||
if reply_to_message and not reply_to_message.forum_topic_created:
|
||||
parsed_message.reply_to_message = reply_to_message
|
||||
|
|
@ -1362,6 +1334,60 @@ class Message(Object, Update):
|
|||
@property
|
||||
def content(self) -> str:
|
||||
return self.text or self.caption or Str("").init([])
|
||||
|
||||
# region Deprecated
|
||||
# TODO: Remove later
|
||||
@property
|
||||
def forward_from(self) -> Optional["types.User"]:
|
||||
log.warning(
|
||||
"`message.forward_from` is deprecated and will be removed in future updates. Use `message.forward_origin.sender_user` instead."
|
||||
)
|
||||
return getattr(self.forward_origin, "sender_user", None)
|
||||
|
||||
@property
|
||||
def forward_sender_name(self) -> Optional[str]:
|
||||
log.warning(
|
||||
"`message.forward_sender_name` property is deprecated and will be removed in future updates. Use `message.forward_origin.sender_user_name` instead."
|
||||
)
|
||||
return getattr(self.forward_origin, "sender_user_name", None)
|
||||
|
||||
@property
|
||||
def forward_from_chat(self) -> Optional["types.Chat"]:
|
||||
log.warning(
|
||||
"`message.forward_from_chat` property is deprecated and will be removed in future updates. Use `message.forward_origin.chat.sender_chat` instead."
|
||||
)
|
||||
return getattr(
|
||||
self.forward_origin,
|
||||
"chat",
|
||||
getattr(
|
||||
self.forward_origin,
|
||||
"sender_chat",
|
||||
None
|
||||
)
|
||||
)
|
||||
|
||||
@property
|
||||
def forward_from_message_id(self) -> Optional[int]:
|
||||
log.warning(
|
||||
"`message.forward_from_message_id` property is deprecated and will be removed in future updates. Use `message.forward_origin.message_id` instead."
|
||||
)
|
||||
return getattr(self.forward_origin, "message_id", None)
|
||||
|
||||
@property
|
||||
def forward_signature(self) -> Optional[str]:
|
||||
log.warning(
|
||||
"`message.forward_signature` property is deprecated and will be removed in future updates. Use `message.forward_origin.author_signature` instead."
|
||||
)
|
||||
return getattr(self.forward_origin, "author_signature", None)
|
||||
|
||||
@property
|
||||
def forward_date(self) -> Optional[datetime]:
|
||||
log.warning(
|
||||
"`message.forward_date` property is deprecated and will be removed in future updates. Use `message.forward_origin.date` instead."
|
||||
)
|
||||
return getattr(self.forward_origin, "date", None)
|
||||
|
||||
# endregion
|
||||
|
||||
async def get_media_group(self) -> List["types.Message"]:
|
||||
"""Bound method *get_media_group* of :obj:`~pyrogram.types.Message`.
|
||||
|
|
@ -1398,7 +1424,7 @@ class Message(Object, Update):
|
|||
quote: bool = None,
|
||||
parse_mode: Optional["enums.ParseMode"] = None,
|
||||
entities: List["types.MessageEntity"] = None,
|
||||
disable_web_page_preview: bool = None,
|
||||
link_preview_options: "types.LinkPreviewOptions" = None,
|
||||
disable_notification: bool = None,
|
||||
reply_to_message_id: int = None,
|
||||
business_connection_id: str = None,
|
||||
|
|
@ -1410,7 +1436,8 @@ class Message(Object, Update):
|
|||
allow_paid_broadcast: bool = None,
|
||||
message_effect_id: int = None,
|
||||
invert_media: bool = None,
|
||||
reply_markup=None
|
||||
reply_markup=None,
|
||||
disable_web_page_preview: bool = None
|
||||
) -> "Message":
|
||||
"""Bound method *reply_text* of :obj:`~pyrogram.types.Message`.
|
||||
|
||||
|
|
@ -1450,9 +1477,8 @@ class Message(Object, Update):
|
|||
disable_web_page_preview (``bool``, *optional*):
|
||||
Disables link previews for links in this message.
|
||||
|
||||
disable_notification (``bool``, *optional*):
|
||||
Sends the message silently.
|
||||
Users will receive a notification with no sound.
|
||||
link_preview_options (:obj:`~pyrogram.types.LinkPreviewOptions`, *optional*):
|
||||
Options used for link preview generation for the message.
|
||||
|
||||
reply_to_message_id (``int``, *optional*):
|
||||
If the message is a reply, ID of the original message.
|
||||
|
|
@ -1525,6 +1551,7 @@ class Message(Object, Update):
|
|||
parse_mode=parse_mode,
|
||||
entities=entities,
|
||||
disable_web_page_preview=disable_web_page_preview,
|
||||
link_preview_options=link_preview_options,
|
||||
disable_notification=disable_notification,
|
||||
message_thread_id=message_thread_id,
|
||||
reply_to_message_id=reply_to_message_id,
|
||||
|
|
@ -4312,10 +4339,11 @@ class Message(Object, Update):
|
|||
text: str,
|
||||
parse_mode: Optional["enums.ParseMode"] = None,
|
||||
entities: List["types.MessageEntity"] = None,
|
||||
disable_web_page_preview: bool = None,
|
||||
link_preview_options: "types.LinkPreviewOptions" = None,
|
||||
invert_media: bool = None,
|
||||
reply_markup: "types.InlineKeyboardMarkup" = None,
|
||||
business_connection_id: str = None
|
||||
business_connection_id: str = None,
|
||||
disable_web_page_preview: bool = None
|
||||
) -> "Message":
|
||||
"""Bound method *edit_text* of :obj:`~pyrogram.types.Message`.
|
||||
|
||||
|
|
@ -4347,8 +4375,8 @@ class Message(Object, Update):
|
|||
entities (List of :obj:`~pyrogram.types.MessageEntity`):
|
||||
List of special entities that appear in message text, which can be specified instead of *parse_mode*.
|
||||
|
||||
disable_web_page_preview (``bool``, *optional*):
|
||||
Disables link previews for links in this message.
|
||||
link_preview_options (:obj:`~pyrogram.types.LinkPreviewOptions`, *optional*):
|
||||
Options used for link preview generation for the message.
|
||||
|
||||
invert_media (``bool``, *optional*):
|
||||
Inverts the position of the media and caption.
|
||||
|
|
@ -4373,6 +4401,7 @@ class Message(Object, Update):
|
|||
parse_mode=parse_mode,
|
||||
entities=entities,
|
||||
disable_web_page_preview=disable_web_page_preview,
|
||||
link_preview_options=link_preview_options,
|
||||
invert_media=invert_media,
|
||||
reply_markup=reply_markup,
|
||||
business_connection_id=self.business_connection_id if business_connection_id is None else business_connection_id
|
||||
|
|
@ -4747,7 +4776,7 @@ class Message(Object, Update):
|
|||
text=self.text,
|
||||
entities=self.entities,
|
||||
parse_mode=enums.ParseMode.DISABLED,
|
||||
disable_web_page_preview=not self.web_page_preview,
|
||||
link_preview_options=types.LinkPreviewOptions(is_disabled=not self.web_page),
|
||||
disable_notification=disable_notification,
|
||||
message_thread_id=message_thread_id,
|
||||
reply_to_message_id=reply_to_message_id,
|
||||
|
|
|
|||
94
pyrogram/types/messages_and_media/message_origin.py
Normal file
94
pyrogram/types/messages_and_media/message_origin.py
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present <https://github.com/TelegramPlayGround>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram 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.
|
||||
#
|
||||
# Pyrogram 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 Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
from datetime import datetime
|
||||
from typing import Dict, Optional
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import enums, raw, types, utils
|
||||
|
||||
from ..object import Object
|
||||
|
||||
|
||||
class MessageOrigin(Object):
|
||||
"""This object describes the origin of a message.
|
||||
|
||||
It can be one of:
|
||||
|
||||
- :obj:`~pyrogram.types.MessageOriginChannel`
|
||||
- :obj:`~pyrogram.types.MessageOriginChat`
|
||||
- :obj:`~pyrogram.types.MessageOriginHiddenUser`
|
||||
- :obj:`~pyrogram.types.MessageOriginImport`
|
||||
- :obj:`~pyrogram.types.MessageOriginUser`
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
type: "enums.MessageOriginType",
|
||||
date: Optional[datetime] = None
|
||||
):
|
||||
super().__init__()
|
||||
|
||||
self.type = type
|
||||
self.date = date
|
||||
|
||||
@staticmethod
|
||||
def _parse(
|
||||
client: "pyrogram.Client",
|
||||
fwd_from: "raw.types.MessageFwdHeader",
|
||||
users: Dict[int, "raw.base.User"],
|
||||
chats: Dict[int, "raw.base.Chat"]
|
||||
) -> Optional["MessageOrigin"]:
|
||||
if not fwd_from:
|
||||
return None
|
||||
|
||||
forward_date = utils.timestamp_to_datetime(fwd_from.date)
|
||||
|
||||
if fwd_from.from_id:
|
||||
raw_peer_id = utils.get_raw_peer_id(fwd_from.from_id)
|
||||
peer_id = utils.get_peer_id(fwd_from.from_id)
|
||||
peer_type = utils.get_peer_type(peer_id)
|
||||
|
||||
if peer_type == "user":
|
||||
return types.MessageOriginUser(
|
||||
date=forward_date,
|
||||
sender_user=types.User._parse(client, users.get(raw_peer_id))
|
||||
)
|
||||
else:
|
||||
if fwd_from.channel_post:
|
||||
return types.MessageOriginChannel(
|
||||
date=forward_date,
|
||||
chat=types.Chat._parse_channel_chat(client, chats.get(raw_peer_id)),
|
||||
message_id=fwd_from.channel_post,
|
||||
author_signature=fwd_from.post_author
|
||||
)
|
||||
else:
|
||||
return types.MessageOriginChat(
|
||||
date=forward_date,
|
||||
sender_chat=types.Chat._parse_channel_chat(client, chats.get(raw_peer_id)),
|
||||
author_signature=fwd_from.post_author
|
||||
)
|
||||
elif fwd_from.from_name:
|
||||
return types.MessageOriginHiddenUser(
|
||||
date=forward_date,
|
||||
sender_user_name=fwd_from.from_name
|
||||
)
|
||||
elif fwd_from.imported:
|
||||
return types.MessageOriginImport(
|
||||
date=forward_date,
|
||||
sender_user_name=fwd_from.post_author
|
||||
)
|
||||
61
pyrogram/types/messages_and_media/message_origin_channel.py
Normal file
61
pyrogram/types/messages_and_media/message_origin_channel.py
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present <https://github.com/TelegramPlayGround>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram 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.
|
||||
#
|
||||
# Pyrogram 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 Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from pyrogram import enums, types
|
||||
|
||||
from .message_origin import MessageOrigin
|
||||
|
||||
|
||||
class MessageOriginChannel(MessageOrigin):
|
||||
"""The message was originally sent to a channel chat.
|
||||
|
||||
Parameters:
|
||||
type (:obj:`~pyrogram.enums.MessageOriginType`):
|
||||
Type of the message origin.
|
||||
|
||||
date (:py:obj:`~datetime.datetime`):
|
||||
Date the message was sent originally.
|
||||
|
||||
chat (:obj:`~pyrogram.types.Chat`):
|
||||
Channel chat to which the message was originally sent.
|
||||
|
||||
message_id (``int``):
|
||||
Unique message identifier inside the chat.
|
||||
|
||||
author_signature (``str``, *optional*):
|
||||
Signature of the original post author.
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
type: "enums.MessageOriginType" = enums.MessageOriginType.CHANNEL,
|
||||
date: datetime = None,
|
||||
chat: "types.Chat" = None,
|
||||
message_id: int = None,
|
||||
author_signature: str = None
|
||||
):
|
||||
super().__init__(
|
||||
type=type,
|
||||
date=date
|
||||
)
|
||||
|
||||
self.chat = chat
|
||||
self.message_id = message_id
|
||||
self.author_signature = author_signature
|
||||
56
pyrogram/types/messages_and_media/message_origin_chat.py
Normal file
56
pyrogram/types/messages_and_media/message_origin_chat.py
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present <https://github.com/TelegramPlayGround>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram 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.
|
||||
#
|
||||
# Pyrogram 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 Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from pyrogram import enums, types
|
||||
|
||||
from .message_origin import MessageOrigin
|
||||
|
||||
|
||||
class MessageOriginChat(MessageOrigin):
|
||||
"""The message was originally sent on behalf of a chat to a group chat.
|
||||
|
||||
Parameters:
|
||||
type (:obj:`~pyrogram.enums.MessageOriginType`):
|
||||
Type of the message origin.
|
||||
|
||||
date (:py:obj:`~datetime.datetime`):
|
||||
Date the message was sent originally.
|
||||
|
||||
sender_chat (:obj:`~pyrogram.types.Chat`):
|
||||
Chat that sent the message originally.
|
||||
|
||||
author_signature (``str``, *optional*):
|
||||
For messages originally sent by an anonymous chat administrator, original message author signature.
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
type: "enums.MessageOriginType" = enums.MessageOriginType.CHAT,
|
||||
date: datetime = None,
|
||||
sender_chat: "types.Chat" = None,
|
||||
author_signature: str = None
|
||||
):
|
||||
super().__init__(
|
||||
type=type,
|
||||
date=date
|
||||
)
|
||||
|
||||
self.sender_chat = sender_chat
|
||||
self.author_signature = author_signature
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present <https://github.com/TelegramPlayGround>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram 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.
|
||||
#
|
||||
# Pyrogram 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 Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from pyrogram import enums
|
||||
|
||||
from .message_origin import MessageOrigin
|
||||
|
||||
|
||||
class MessageOriginHiddenUser(MessageOrigin):
|
||||
"""The message was originally sent by an unknown user.
|
||||
|
||||
Parameters:
|
||||
type (:obj:`~pyrogram.enums.MessageOriginType`):
|
||||
Type of the message origin.
|
||||
|
||||
date (:py:obj:`~datetime.datetime`):
|
||||
Date the message was sent originally.
|
||||
|
||||
sender_user_name (``str``):
|
||||
Name of the user that sent the message originally.
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
type: "enums.MessageOriginType" = enums.MessageOriginType.HIDDEN_USER,
|
||||
date: datetime = None,
|
||||
sender_user_name: str = None
|
||||
):
|
||||
super().__init__(
|
||||
type=type,
|
||||
date=date
|
||||
)
|
||||
|
||||
self.sender_user_name = sender_user_name
|
||||
50
pyrogram/types/messages_and_media/message_origin_import.py
Normal file
50
pyrogram/types/messages_and_media/message_origin_import.py
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present <https://github.com/TelegramPlayGround>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram 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.
|
||||
#
|
||||
# Pyrogram 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 Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from pyrogram import enums
|
||||
|
||||
from .message_origin import MessageOrigin
|
||||
|
||||
|
||||
class MessageOriginImport(MessageOrigin):
|
||||
"""Contains information about a message imported from a foreign chat service.
|
||||
|
||||
Parameters:
|
||||
type (:obj:`~pyrogram.enums.MessageOriginType`):
|
||||
Type of the message origin.
|
||||
|
||||
date (:py:obj:`~datetime.datetime`):
|
||||
Date the message was sent originally.
|
||||
|
||||
sender_user_name (``str``):
|
||||
Name of the original sender.
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
date: datetime = None,
|
||||
sender_user_name: str = None
|
||||
):
|
||||
super().__init__(
|
||||
type=enums.MessageOriginType.IMPORT,
|
||||
date=date
|
||||
)
|
||||
|
||||
self.sender_user_name = sender_user_name
|
||||
51
pyrogram/types/messages_and_media/message_origin_user.py
Normal file
51
pyrogram/types/messages_and_media/message_origin_user.py
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present <https://github.com/TelegramPlayGround>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram 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.
|
||||
#
|
||||
# Pyrogram 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 Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from pyrogram import enums, types
|
||||
|
||||
from .message_origin import MessageOrigin
|
||||
|
||||
|
||||
class MessageOriginUser(MessageOrigin):
|
||||
"""The message was originally sent by a known user.
|
||||
|
||||
Parameters:
|
||||
type (:obj:`~pyrogram.enums.MessageOriginType`):
|
||||
Type of the message origin.
|
||||
|
||||
date (:py:obj:`~datetime.datetime`):
|
||||
Date the message was sent originally.
|
||||
|
||||
sender_user (:obj:`~pyrogram.types.User`):
|
||||
User that sent the message originally.
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
type: "enums.MessageOriginType" = enums.MessageOriginType.USER,
|
||||
date: datetime = None,
|
||||
sender_user: "types.User" = None
|
||||
):
|
||||
super().__init__(
|
||||
type=type,
|
||||
date=date
|
||||
)
|
||||
|
||||
self.sender_user = sender_user
|
||||
|
|
@ -327,12 +327,13 @@ class Story(Object, Update):
|
|||
text: str,
|
||||
parse_mode: Optional["enums.ParseMode"] = None,
|
||||
entities: List["types.MessageEntity"] = None,
|
||||
disable_web_page_preview: bool = None,
|
||||
link_preview_options: "types.LinkPreviewOptions" = None,
|
||||
disable_notification: bool = None,
|
||||
reply_to_story_id: int = None,
|
||||
schedule_date: datetime = None,
|
||||
protect_content: bool = None,
|
||||
reply_markup=None
|
||||
reply_markup=None,
|
||||
disable_web_page_preview: bool = None
|
||||
) -> "types.Message":
|
||||
"""Bound method *reply_text* of :obj:`~pyrogram.types.Story`.
|
||||
|
||||
|
|
@ -364,8 +365,8 @@ class Story(Object, Update):
|
|||
entities (List of :obj:`~pyrogram.types.MessageEntity`):
|
||||
List of special entities that appear in message text, which can be specified instead of *parse_mode*.
|
||||
|
||||
disable_web_page_preview (``bool``, *optional*):
|
||||
Disables link previews for links in this message.
|
||||
link_preview_options (:obj:`~pyrogram.types.LinkPreviewOptions`, *optional*):
|
||||
Options used for link preview generation for the message.
|
||||
|
||||
disable_notification (``bool``, *optional*):
|
||||
Sends the message silently.
|
||||
|
|
@ -400,6 +401,7 @@ class Story(Object, Update):
|
|||
parse_mode=parse_mode,
|
||||
entities=entities,
|
||||
disable_web_page_preview=disable_web_page_preview,
|
||||
link_preview_options=link_preview_options,
|
||||
disable_notification=disable_notification,
|
||||
reply_to_story_id=reply_to_story_id,
|
||||
schedule_date=schedule_date,
|
||||
|
|
|
|||
83
pyrogram/types/messages_and_media/text_quote.py
Normal file
83
pyrogram/types/messages_and_media/text_quote.py
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram 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.
|
||||
#
|
||||
# Pyrogram 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 Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Dict, List, Optional
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import raw, types
|
||||
|
||||
from ..messages_and_media.message import Str
|
||||
from ..object import Object
|
||||
|
||||
|
||||
class TextQuote(Object):
|
||||
"""Describes manually or automatically chosen quote from another message.
|
||||
|
||||
Parameters:
|
||||
text (``str``):
|
||||
Text of the quoted part of a message that is replied to by the given message.
|
||||
|
||||
entities (List of :obj:`~pyrogram.types.MessageEntity`, *optional*):
|
||||
Special entities that appear in the quote.
|
||||
Currently, only bold, italic, underline, strikethrough, spoiler, and custom_emoji entities are kept in quotes.
|
||||
|
||||
position (``int``):
|
||||
Approximate quote position in the original message in UTF-16 code units as specified by the sender.
|
||||
|
||||
is_manual (``bool``, *optional*):
|
||||
True, if the quote was chosen manually by the message sender.
|
||||
Otherwise, the quote was added automatically by the server.
|
||||
|
||||
"""
|
||||
def __init__(
|
||||
self, *,
|
||||
text: Optional[str] = None,
|
||||
entities: Optional[List["types.MessageEntity"]] = None,
|
||||
position: Optional[int] = None,
|
||||
is_manual: Optional[bool] = None
|
||||
):
|
||||
super().__init__()
|
||||
|
||||
self.text = text
|
||||
self.entities = entities
|
||||
self.position = position
|
||||
self.is_manual = is_manual
|
||||
|
||||
@staticmethod
|
||||
def _parse(
|
||||
client: "pyrogram.Client",
|
||||
users: Dict[int, "raw.types.User"],
|
||||
reply_to: "raw.types.MessageReplyHeader"
|
||||
) -> "TextQuote":
|
||||
if isinstance(reply_to, raw.types.MessageReplyHeader):
|
||||
entities = types.List(
|
||||
filter(
|
||||
lambda x: x is not None,
|
||||
[
|
||||
types.MessageEntity._parse(client, entity, users)
|
||||
for entity in getattr(reply_to, "quote_entities", [])
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
return TextQuote(
|
||||
text=Str(reply_to.quote_text).init(entities) or None,
|
||||
entities=entities or None,
|
||||
position=reply_to.quote_offset or 0,
|
||||
is_manual=reply_to.quote
|
||||
)
|
||||
|
|
@ -22,6 +22,7 @@ from pyrogram import raw
|
|||
from pyrogram import types
|
||||
from ..object import Object
|
||||
|
||||
from typing import Optional
|
||||
|
||||
class WebPage(Object):
|
||||
# TODO: hash, cached_page
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import asyncio
|
|||
import base64
|
||||
import functools
|
||||
import hashlib
|
||||
import re
|
||||
import os
|
||||
import struct
|
||||
from concurrent.futures.thread import ThreadPoolExecutor
|
||||
|
|
@ -120,9 +121,14 @@ async def parse_messages(
|
|||
|
||||
if replies:
|
||||
messages_with_replies = {
|
||||
i.id: i.reply_to
|
||||
i.id: i.reply_to.reply_to_msg_id
|
||||
for i in messages.messages
|
||||
if not isinstance(i, raw.types.MessageEmpty) and i.reply_to and isinstance(i.reply_to, raw.types.MessageReplyHeader)
|
||||
if (
|
||||
not isinstance(i, raw.types.MessageEmpty)
|
||||
and i.reply_to
|
||||
and isinstance(i.reply_to, raw.types.MessageReplyHeader)
|
||||
and i.reply_to.reply_to_msg_id is not None
|
||||
)
|
||||
}
|
||||
|
||||
message_reply_to_story = {
|
||||
|
|
@ -135,61 +141,27 @@ async def parse_messages(
|
|||
# We need a chat id, but some messages might be empty (no chat attribute available)
|
||||
# Scan until we find a message with a chat available (there must be one, because we are fetching replies)
|
||||
for m in parsed_messages:
|
||||
if not isinstance(m, types.Message):
|
||||
continue
|
||||
|
||||
if m.chat:
|
||||
chat_id = m.chat.id
|
||||
break
|
||||
else:
|
||||
chat_id = 0
|
||||
|
||||
is_all_within_chat = not any(
|
||||
value.reply_to_peer_id
|
||||
for value in messages_with_replies.values()
|
||||
reply_messages = await client.get_messages(
|
||||
chat_id,
|
||||
reply_to_message_ids=messages_with_replies.keys(),
|
||||
replies=replies - 1
|
||||
)
|
||||
reply_messages: List[pyrogram.types.Message] = []
|
||||
if is_all_within_chat:
|
||||
# fast path: fetch all messages within the same chat
|
||||
reply_messages = await client.get_messages(
|
||||
chat_id,
|
||||
reply_to_message_ids=messages_with_replies.keys(),
|
||||
replies=replies - 1
|
||||
)
|
||||
else:
|
||||
# slow path: fetch all messages individually
|
||||
for target_reply_to in messages_with_replies.values():
|
||||
to_be_added_msg = None
|
||||
the_chat_id = chat_id
|
||||
if target_reply_to.reply_to_peer_id:
|
||||
the_chat_id = get_channel_id(target_reply_to.reply_to_peer_id.channel_id)
|
||||
to_be_added_msg = await client.get_messages(
|
||||
chat_id=the_chat_id,
|
||||
message_ids=target_reply_to.reply_to_msg_id,
|
||||
replies=replies - 1
|
||||
)
|
||||
if isinstance(to_be_added_msg, list):
|
||||
for current_to_be_added in to_be_added_msg:
|
||||
reply_messages.append(current_to_be_added)
|
||||
elif to_be_added_msg:
|
||||
reply_messages.append(to_be_added_msg)
|
||||
|
||||
for message in parsed_messages:
|
||||
reply_to = messages_with_replies.get(message.id, None)
|
||||
if not reply_to:
|
||||
continue
|
||||
|
||||
reply_id = reply_to.reply_to_msg_id
|
||||
reply_id = messages_with_replies.get(message.id, None)
|
||||
|
||||
for reply in reply_messages:
|
||||
if reply.id == reply_id and not reply.forum_topic_created:
|
||||
message.reply_to_message = reply
|
||||
|
||||
if reply.id == reply_id:
|
||||
if not reply.forum_topic_created:
|
||||
message.reply_to_message = reply
|
||||
if message_reply_to_story:
|
||||
for m in parsed_messages:
|
||||
if not isinstance(m, types.Message):
|
||||
continue
|
||||
|
||||
if m.chat:
|
||||
chat_id = m.chat.id
|
||||
break
|
||||
|
|
@ -197,7 +169,7 @@ async def parse_messages(
|
|||
chat_id = 0
|
||||
|
||||
reply_messages = {}
|
||||
for msg_id in message_reply_to_story:
|
||||
for msg_id in message_reply_to_story.keys():
|
||||
reply_messages[msg_id] = await client.get_stories(
|
||||
message_reply_to_story[msg_id]['user_id'],
|
||||
message_reply_to_story[msg_id]['story_id']
|
||||
|
|
@ -529,3 +501,11 @@ async def get_reply_to(
|
|||
story_id=reply_to_story_id
|
||||
)
|
||||
return reply_to
|
||||
|
||||
def get_first_url(text):
|
||||
text = re.sub(r"^\s*(<[\w<>=\s\"]*>)\s*", r"\1", text)
|
||||
text = re.sub(r"\s*(</[\w</>]*>)\s*$", r"\1", text)
|
||||
|
||||
matches = re.findall(r"(https?):\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])", text)
|
||||
|
||||
return f"{matches[0][0]}://{matches[0][1]}{matches[0][2]}" if matches else None
|
||||
|
|
|
|||
Loading…
Reference in a new issue