mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-02-03 05:04:33 +03:00
Make custom.Message functional
This commit is contained in:
parent
499fc9f603
commit
334a847de7
|
@ -119,6 +119,32 @@ The following modules have been moved inside ``_misc``:
|
|||
// TODO review telethon/__init__.py isn't exposing more than it should
|
||||
|
||||
|
||||
The custom.Message class and the way it is used has changed
|
||||
-----------------------------------------------------------
|
||||
|
||||
It no longer inherits ``TLObject``, and rather than trying to mimick Telegram's ``Message``
|
||||
constructor, it now takes two parameters: a ``TelegramClient`` instance and a ``_tl.Message``.
|
||||
As a benefit, you can now more easily reconstruct instances of this type from a previously-stored
|
||||
``_tl.Message`` instance.
|
||||
|
||||
There are no public attributes. Instead, they are now properties which forward the values into and
|
||||
from the private ``_message`` field. As a benefit, the documentation will now be easier to follow.
|
||||
However, you can no longer use ``del`` on these.
|
||||
|
||||
The ``_tl.Message.media`` attribute will no longer be ``None`` when using raw API if the media was
|
||||
``messageMediaEmpty``. As a benefit, you can now actually distinguish between no media and empty
|
||||
media. The ``Message.media`` property as returned by friendly methods will still be ``None`` on
|
||||
empty media.
|
||||
|
||||
The ``telethon.tl.patched`` hack has been removed.
|
||||
|
||||
In order to avoid breaking more code than strictly necessary, ``.raw_text`` will remain a synonym
|
||||
of ``.message``, and ``.text`` will still be the text formatted through the ``client.parse_mode``.
|
||||
However, you're encouraged to change uses of ``.raw_text`` with ``.message``, and ``.text`` with
|
||||
either ``.md_text`` or ``.html_text`` as needed. This is because both ``.text`` and ``.raw_text``
|
||||
may disappear in future versions, and their behaviour is not immediately obvious.
|
||||
|
||||
|
||||
The Conversation API has been removed
|
||||
-------------------------------------
|
||||
|
||||
|
|
|
@ -291,16 +291,16 @@ class _AdminLogIter(requestiter.RequestIter):
|
|||
for ev in r.events:
|
||||
if isinstance(ev.action,
|
||||
_tl.ChannelAdminLogEventActionEditMessage):
|
||||
ev.action.prev_message._finish_init(
|
||||
self.client, entities, self.entity)
|
||||
ev.action.prev_message = _custom.Message._new(
|
||||
self.client, ev.action.prev_message, entities, self.entity)
|
||||
|
||||
ev.action.new_message._finish_init(
|
||||
self.client, entities, self.entity)
|
||||
ev.action.new_message = _custom.Message._new(
|
||||
self.client, ev.action.new_message, entities, self.entity)
|
||||
|
||||
elif isinstance(ev.action,
|
||||
_tl.ChannelAdminLogEventActionDeleteMessage):
|
||||
ev.action.message._finish_init(
|
||||
self.client, entities, self.entity)
|
||||
ev.action.message = _custom.Message._new(
|
||||
self.client, ev.action.message, entities, self.entity)
|
||||
|
||||
self.buffer.append(_custom.AdminLogEvent(ev, entities))
|
||||
|
||||
|
|
|
@ -58,10 +58,10 @@ class _DialogsIter(requestiter.RequestIter):
|
|||
for x in itertools.chain(r.users, r.chats)
|
||||
if not isinstance(x, (_tl.UserEmpty, _tl.ChatEmpty))}
|
||||
|
||||
messages = {}
|
||||
for m in r.messages:
|
||||
m._finish_init(self.client, entities, None)
|
||||
messages[_dialog_message_key(m.peer_id, m.id)] = m
|
||||
messages = {
|
||||
_dialog_message_key(m.peer_id, m.id): _custom.Message._new(self.client, m, entities, None)
|
||||
for m in r.messages
|
||||
}
|
||||
|
||||
for d in r.dialogs:
|
||||
# We check the offset date here because Telegram may ignore it
|
||||
|
|
|
@ -3,6 +3,7 @@ import re
|
|||
import typing
|
||||
|
||||
from .. import helpers, utils, _tl
|
||||
from ..types import _custom
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from .telegramclient import TelegramClient
|
||||
|
@ -94,7 +95,7 @@ def _get_response_message(self: 'TelegramClient', request, result, input_chat):
|
|||
|
||||
elif isinstance(update, (
|
||||
_tl.UpdateNewChannelMessage, _tl.UpdateNewMessage)):
|
||||
update.message._finish_init(self, entities, input_chat)
|
||||
update.message = _custom.Message._new(self, update.message, entities, input_chat)
|
||||
|
||||
# Pinning a message with `updatePinnedMessage` seems to
|
||||
# always produce a service message we can't map so return
|
||||
|
@ -110,7 +111,7 @@ def _get_response_message(self: 'TelegramClient', request, result, input_chat):
|
|||
|
||||
elif (isinstance(update, _tl.UpdateEditMessage)
|
||||
and helpers._entity_type(request.peer) != helpers._EntityType.CHANNEL):
|
||||
update.message._finish_init(self, entities, input_chat)
|
||||
update.message = _custom.Message._new(self, update.message, entities, input_chat)
|
||||
|
||||
# Live locations use `sendMedia` but Telegram responds with
|
||||
# `updateEditMessage`, which means we won't have `id` field.
|
||||
|
@ -123,28 +124,24 @@ def _get_response_message(self: 'TelegramClient', request, result, input_chat):
|
|||
and utils.get_peer_id(request.peer) ==
|
||||
utils.get_peer_id(update.message.peer_id)):
|
||||
if request.id == update.message.id:
|
||||
update.message._finish_init(self, entities, input_chat)
|
||||
return update.message
|
||||
return _custom.Message._new(self, update.message, entities, input_chat)
|
||||
|
||||
elif isinstance(update, _tl.UpdateNewScheduledMessage):
|
||||
update.message._finish_init(self, entities, input_chat)
|
||||
# Scheduled IDs may collide with normal IDs. However, for a
|
||||
# single request there *shouldn't* be a mix between "some
|
||||
# scheduled and some not".
|
||||
id_to_message[update.message.id] = update.message
|
||||
id_to_message[update.message.id] = _custom.Message._new(self, update.message, entities, input_chat)
|
||||
|
||||
elif isinstance(update, _tl.UpdateMessagePoll):
|
||||
if request.media.poll.id == update.poll_id:
|
||||
m = _tl.Message(
|
||||
return _custom.Message._new(self, _tl.Message(
|
||||
id=request.id,
|
||||
peer_id=utils.get_peer(request.peer),
|
||||
media=_tl.MessageMediaPoll(
|
||||
poll=update.poll,
|
||||
results=update.results
|
||||
)
|
||||
)
|
||||
m._finish_init(self, entities, input_chat)
|
||||
return m
|
||||
), entities, input_chat)
|
||||
|
||||
if request is None:
|
||||
return id_to_message
|
||||
|
|
|
@ -5,6 +5,7 @@ import warnings
|
|||
|
||||
from .. import errors, hints, _tl
|
||||
from .._misc import helpers, utils, requestiter
|
||||
from ..types import _custom
|
||||
|
||||
_MAX_CHUNK_SIZE = 100
|
||||
|
||||
|
@ -200,8 +201,7 @@ class _MessagesIter(requestiter.RequestIter):
|
|||
# is an attempt to avoid these duplicates, since the message
|
||||
# IDs are returned in descending order (or asc if reverse).
|
||||
self.last_id = message.id
|
||||
message._finish_init(self.client, entities, self.entity)
|
||||
self.buffer.append(message)
|
||||
self.buffer.append(_custom.Message._new(self.client, message, entities, self.entity))
|
||||
|
||||
if len(r.messages) < self.request.limit:
|
||||
return True
|
||||
|
@ -315,8 +315,7 @@ class _IDsIter(requestiter.RequestIter):
|
|||
from_id and message.peer_id != from_id):
|
||||
self.buffer.append(None)
|
||||
else:
|
||||
message._finish_init(self.client, entities, self._entity)
|
||||
self.buffer.append(message)
|
||||
self.buffer.append(_custom.Message._new(self.client, message, entities, self._entity))
|
||||
|
||||
|
||||
def iter_messages(
|
||||
|
@ -498,7 +497,7 @@ async def send_message(
|
|||
|
||||
result = await self(request)
|
||||
if isinstance(result, _tl.UpdateShortSentMessage):
|
||||
message = _tl.Message(
|
||||
return _custom.Message._new(self, _tl.Message(
|
||||
id=result.id,
|
||||
peer_id=await self._get_peer(entity),
|
||||
message=message,
|
||||
|
@ -508,9 +507,7 @@ async def send_message(
|
|||
entities=result.entities,
|
||||
reply_markup=request.reply_markup,
|
||||
ttl_period=result.ttl_period
|
||||
)
|
||||
message._finish_init(self, {}, entity)
|
||||
return message
|
||||
), {}, entity)
|
||||
|
||||
return self._get_response_message(request, result, entity)
|
||||
|
||||
|
|
|
@ -3783,6 +3783,9 @@ class TelegramClient:
|
|||
async def _handle_auto_reconnect(self: 'TelegramClient'):
|
||||
return await updates._handle_auto_reconnect(**locals())
|
||||
|
||||
def _self_id(self: 'TelegramClient') -> typing.Optional[int]:
|
||||
return users._self_id(**locals())
|
||||
|
||||
# endregion Private
|
||||
|
||||
# TODO re-patch everything to remove the intermediate calls
|
||||
|
|
|
@ -168,8 +168,10 @@ class Album(EventBuilder):
|
|||
self._sender, self._input_sender = utils._get_entity_pair(
|
||||
self.sender_id, self._entities, client._entity_cache)
|
||||
|
||||
for msg in self.messages:
|
||||
msg._finish_init(client, self._entities, None)
|
||||
self.messages = [
|
||||
_custom.Message._new(client, m, self._entities, None)
|
||||
for m in self.messages
|
||||
]
|
||||
|
||||
if len(self.messages) == 1:
|
||||
# This will require hacks to be a proper album event
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from .common import EventBuilder, EventCommon, name_inner_event
|
||||
from .._misc import utils
|
||||
from .. import _tl
|
||||
from ..types import _custom
|
||||
|
||||
|
||||
@name_inner_event
|
||||
|
|
|
@ -3,6 +3,7 @@ import re
|
|||
from .common import EventBuilder, EventCommon, name_inner_event, _into_id_set
|
||||
from .._misc import utils
|
||||
from .. import _tl
|
||||
from ..types import _custom
|
||||
|
||||
|
||||
@name_inner_event
|
||||
|
|
|
@ -9,9 +9,22 @@ from ..._misc import utils, tlobject
|
|||
from ... import errors, _tl
|
||||
|
||||
|
||||
def _fwd(field, doc):
|
||||
def fget(self):
|
||||
try:
|
||||
return self._message.__dict__[field]
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
def fset(self, value):
|
||||
self._message.__dict__[field] = value
|
||||
|
||||
return property(fget, fset, None, doc)
|
||||
|
||||
|
||||
# TODO Figure out a way to have the code generator error on missing fields
|
||||
# Maybe parsing the init function alone if that's possible.
|
||||
class Message(ChatGetter, SenderGetter, tlobject.TLObject):
|
||||
class Message(ChatGetter, SenderGetter):
|
||||
"""
|
||||
This custom class aggregates both :tl:`Message` and
|
||||
:tl:`MessageService` to ease accessing their members.
|
||||
|
@ -20,219 +33,192 @@ class Message(ChatGetter, SenderGetter, tlobject.TLObject):
|
|||
<telethon.tl.custom.chatgetter.ChatGetter>` and `SenderGetter
|
||||
<telethon.tl.custom.sendergetter.SenderGetter>` which means you
|
||||
have access to all their sender and chat properties and methods.
|
||||
|
||||
Members:
|
||||
out (`bool`):
|
||||
Whether the message is outgoing (i.e. you sent it from
|
||||
another session) or incoming (i.e. someone else sent it).
|
||||
|
||||
Note that messages in your own chat are always incoming,
|
||||
but this member will be `True` if you send a message
|
||||
to your own chat. Messages you forward to your chat are
|
||||
*not* considered outgoing, just like official clients
|
||||
display them.
|
||||
|
||||
mentioned (`bool`):
|
||||
Whether you were mentioned in this message or not.
|
||||
Note that replies to your own messages also count
|
||||
as mentions.
|
||||
|
||||
media_unread (`bool`):
|
||||
Whether you have read the media in this message
|
||||
or not, e.g. listened to the voice note media.
|
||||
|
||||
silent (`bool`):
|
||||
Whether the message should notify people with sound or not.
|
||||
Previously used in channels, but since 9 August 2019, it can
|
||||
also be `used in private chats
|
||||
<https://telegram.org/blog/silent-messages-slow-mode>`_.
|
||||
|
||||
post (`bool`):
|
||||
Whether this message is a post in a broadcast
|
||||
channel or not.
|
||||
|
||||
from_scheduled (`bool`):
|
||||
Whether this message was originated from a previously-scheduled
|
||||
message or not.
|
||||
|
||||
legacy (`bool`):
|
||||
Whether this is a legacy message or not.
|
||||
|
||||
edit_hide (`bool`):
|
||||
Whether the edited mark of this message is edited
|
||||
should be hidden (e.g. in GUI clients) or shown.
|
||||
|
||||
pinned (`bool`):
|
||||
Whether this message is currently pinned or not.
|
||||
|
||||
id (`int`):
|
||||
The ID of this message. This field is *always* present.
|
||||
Any other member is optional and may be `None`.
|
||||
|
||||
from_id (:tl:`Peer`):
|
||||
The peer who sent this message, which is either
|
||||
:tl:`PeerUser`, :tl:`PeerChat` or :tl:`PeerChannel`.
|
||||
This value will be `None` for anonymous messages.
|
||||
|
||||
peer_id (:tl:`Peer`):
|
||||
The peer to which this message was sent, which is either
|
||||
:tl:`PeerUser`, :tl:`PeerChat` or :tl:`PeerChannel`. This
|
||||
will always be present except for empty messages.
|
||||
|
||||
fwd_from (:tl:`MessageFwdHeader`):
|
||||
The original forward header if this message is a forward.
|
||||
You should probably use the `forward` property instead.
|
||||
|
||||
via_bot_id (`int`):
|
||||
The ID of the bot used to send this message
|
||||
through its inline mode (e.g. "via @like").
|
||||
|
||||
reply_to (:tl:`MessageReplyHeader`):
|
||||
The original reply header if this message is replying to another.
|
||||
|
||||
date (`datetime`):
|
||||
The UTC+0 `datetime` object indicating when this message
|
||||
was sent. This will always be present except for empty
|
||||
messages.
|
||||
|
||||
message (`str`):
|
||||
The string text of the message for `Message
|
||||
<telethon.tl.custom.message.Message>` instances,
|
||||
which will be `None` for other types of messages.
|
||||
|
||||
media (:tl:`MessageMedia`):
|
||||
The media sent with this message if any (such as
|
||||
photos, videos, documents, gifs, stickers, etc.).
|
||||
|
||||
You may want to access the `photo`, `document`
|
||||
etc. properties instead.
|
||||
|
||||
If the media was not present or it was :tl:`MessageMediaEmpty`,
|
||||
this member will instead be `None` for convenience.
|
||||
|
||||
reply_markup (:tl:`ReplyMarkup`):
|
||||
The reply markup for this message (which was sent
|
||||
either via a bot or by a bot). You probably want
|
||||
to access `buttons` instead.
|
||||
|
||||
entities (List[:tl:`MessageEntity`]):
|
||||
The list of markup entities in this message,
|
||||
such as bold, italics, code, hyperlinks, etc.
|
||||
|
||||
views (`int`):
|
||||
The number of views this message from a broadcast
|
||||
channel has. This is also present in forwards.
|
||||
|
||||
forwards (`int`):
|
||||
The number of times this message has been forwarded.
|
||||
|
||||
replies (`int`):
|
||||
The number of times another message has replied to this message.
|
||||
|
||||
edit_date (`datetime`):
|
||||
The date when this message was last edited.
|
||||
|
||||
post_author (`str`):
|
||||
The display name of the message sender to
|
||||
show in messages sent to broadcast channels.
|
||||
|
||||
grouped_id (`int`):
|
||||
If this message belongs to a group of messages
|
||||
(photo albums or video albums), all of them will
|
||||
have the same value here.
|
||||
|
||||
restriction_reason (List[:tl:`RestrictionReason`])
|
||||
An optional list of reasons why this message was restricted.
|
||||
If the list is `None`, this message has not been restricted.
|
||||
|
||||
ttl_period (`int`):
|
||||
The Time To Live period configured for this message.
|
||||
The message should be erased from wherever it's stored (memory, a
|
||||
local database, etc.) when
|
||||
``datetime.now() > message.date + timedelta(seconds=message.ttl_period)``.
|
||||
|
||||
action (:tl:`MessageAction`):
|
||||
The message action object of the message for :tl:`MessageService`
|
||||
instances, which will be `None` for other types of messages.
|
||||
"""
|
||||
|
||||
# region Forwarded properties
|
||||
|
||||
out = _fwd('out', """
|
||||
Whether the message is outgoing (i.e. you sent it from
|
||||
another session) or incoming (i.e. someone else sent it).
|
||||
|
||||
Note that messages in your own chat are always incoming,
|
||||
but this member will be `True` if you send a message
|
||||
to your own chat. Messages you forward to your chat are
|
||||
*not* considered outgoing, just like official clients
|
||||
display them.
|
||||
""")
|
||||
|
||||
mentioned = _fwd('mentioned', """
|
||||
Whether you were mentioned in this message or not.
|
||||
Note that replies to your own messages also count
|
||||
as mentions.
|
||||
""")
|
||||
|
||||
media_unread = _fwd('media_unread', """
|
||||
Whether you have read the media in this message
|
||||
or not, e.g. listened to the voice note media.
|
||||
""")
|
||||
|
||||
silent = _fwd('silent', """
|
||||
Whether the message should notify people with sound or not.
|
||||
Previously used in channels, but since 9 August 2019, it can
|
||||
also be `used in private chats
|
||||
<https://telegram.org/blog/silent-messages-slow-mode>`_.
|
||||
""")
|
||||
|
||||
post = _fwd('post', """
|
||||
Whether this message is a post in a broadcast
|
||||
channel or not.
|
||||
""")
|
||||
|
||||
from_scheduled = _fwd('from_scheduled', """
|
||||
Whether this message was originated from a previously-scheduled
|
||||
message or not.
|
||||
""")
|
||||
|
||||
legacy = _fwd('legacy', """
|
||||
Whether this is a legacy message or not.
|
||||
""")
|
||||
|
||||
edit_hide = _fwd('edit_hide', """
|
||||
Whether the edited mark of this message is edited
|
||||
should be hidden (e.g. in GUI clients) or shown.
|
||||
""")
|
||||
|
||||
pinned = _fwd('pinned', """
|
||||
Whether this message is currently pinned or not.
|
||||
""")
|
||||
|
||||
id = _fwd('id', """
|
||||
The ID of this message. This field is *always* present.
|
||||
Any other member is optional and may be `None`.
|
||||
""")
|
||||
|
||||
from_id = _fwd('from_id', """
|
||||
The peer who sent this message, which is either
|
||||
:tl:`PeerUser`, :tl:`PeerChat` or :tl:`PeerChannel`.
|
||||
This value will be `None` for anonymous messages.
|
||||
""")
|
||||
|
||||
peer_id = _fwd('peer_id', """
|
||||
The peer to which this message was sent, which is either
|
||||
:tl:`PeerUser`, :tl:`PeerChat` or :tl:`PeerChannel`. This
|
||||
will always be present except for empty messages.
|
||||
""")
|
||||
|
||||
fwd_from = _fwd('fwd_from', """
|
||||
The original forward header if this message is a forward.
|
||||
You should probably use the `forward` property instead.
|
||||
""")
|
||||
|
||||
via_bot_id = _fwd('via_bot_id', """
|
||||
The ID of the bot used to send this message
|
||||
through its inline mode (e.g. "via @like").
|
||||
""")
|
||||
|
||||
reply_to = _fwd('reply_to', """
|
||||
The original reply header if this message is replying to another.
|
||||
""")
|
||||
|
||||
date = _fwd('date', """
|
||||
The UTC+0 `datetime` object indicating when this message
|
||||
was sent. This will always be present except for empty
|
||||
messages.
|
||||
""")
|
||||
|
||||
message = _fwd('message', """
|
||||
The string text of the message for `Message
|
||||
<telethon.tl.custom.message.Message>` instances,
|
||||
which will be `None` for other types of messages.
|
||||
""")
|
||||
|
||||
@property
|
||||
def media(self):
|
||||
"""
|
||||
The media sent with this message if any (such as
|
||||
photos, videos, documents, gifs, stickers, etc.).
|
||||
|
||||
You may want to access the `photo`, `document`
|
||||
etc. properties instead.
|
||||
|
||||
If the media was not present or it was :tl:`MessageMediaEmpty`,
|
||||
this member will instead be `None` for convenience.
|
||||
"""
|
||||
try:
|
||||
media = self._message.media
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
return None if media.CONSTRUCTOR_ID == 0x3ded6320 else media
|
||||
|
||||
@media.setter
|
||||
def media(self, value):
|
||||
self._message.media = value
|
||||
|
||||
reply_markup = _fwd('reply_markup', """
|
||||
The reply markup for this message (which was sent
|
||||
either via a bot or by a bot). You probably want
|
||||
to access `buttons` instead.
|
||||
""")
|
||||
|
||||
entities = _fwd('entities', """
|
||||
The list of markup entities in this message,
|
||||
such as bold, italics, code, hyperlinks, etc.
|
||||
""")
|
||||
|
||||
views = _fwd('views', """
|
||||
The number of views this message from a broadcast
|
||||
channel has. This is also present in forwards.
|
||||
""")
|
||||
|
||||
forwards = _fwd('forwards', """
|
||||
The number of times this message has been forwarded.
|
||||
""")
|
||||
|
||||
replies = _fwd('replies', """
|
||||
The number of times another message has replied to this message.
|
||||
""")
|
||||
|
||||
edit_date = _fwd('edit_date', """
|
||||
The date when this message was last edited.
|
||||
""")
|
||||
|
||||
post_author = _fwd('post_author', """
|
||||
The display name of the message sender to
|
||||
show in messages sent to broadcast channels.
|
||||
""")
|
||||
|
||||
grouped_id = _fwd('grouped_id', """
|
||||
If this message belongs to a group of messages
|
||||
(photo albums or video albums), all of them will
|
||||
have the same value here.
|
||||
|
||||
restriction_reason (List[:tl:`RestrictionReason`])
|
||||
An optional list of reasons why this message was restricted.
|
||||
If the list is `None`, this message has not been restricted.
|
||||
""")
|
||||
|
||||
ttl_period = _fwd('ttl_period', """
|
||||
The Time To Live period configured for this message.
|
||||
The message should be erased from wherever it's stored (memory, a
|
||||
local database, etc.) when
|
||||
``datetime.now() > message.date + timedelta(seconds=message.ttl_period)``.
|
||||
""")
|
||||
|
||||
action = _fwd('action', """
|
||||
The message action object of the message for :tl:`MessageService`
|
||||
instances, which will be `None` for other types of messages.
|
||||
""")
|
||||
|
||||
# endregion
|
||||
|
||||
# region Initialization
|
||||
|
||||
def __init__(
|
||||
# Common to all
|
||||
self, id: int,
|
||||
|
||||
# Common to Message and MessageService (mandatory)
|
||||
peer_id: _tl.TypePeer = None,
|
||||
date: Optional[datetime] = None,
|
||||
|
||||
# Common to Message and MessageService (flags)
|
||||
out: Optional[bool] = None,
|
||||
mentioned: Optional[bool] = None,
|
||||
media_unread: Optional[bool] = None,
|
||||
silent: Optional[bool] = None,
|
||||
post: Optional[bool] = None,
|
||||
from_id: Optional[_tl.TypePeer] = None,
|
||||
reply_to: Optional[_tl.TypeMessageReplyHeader] = None,
|
||||
ttl_period: Optional[int] = None,
|
||||
|
||||
# For Message (mandatory)
|
||||
message: Optional[str] = None,
|
||||
|
||||
# For Message (flags)
|
||||
fwd_from: Optional[_tl.TypeMessageFwdHeader] = None,
|
||||
via_bot_id: Optional[int] = None,
|
||||
media: Optional[_tl.TypeMessageMedia] = None,
|
||||
reply_markup: Optional[_tl.TypeReplyMarkup] = None,
|
||||
entities: Optional[List[_tl.TypeMessageEntity]] = None,
|
||||
views: Optional[int] = None,
|
||||
edit_date: Optional[datetime] = None,
|
||||
post_author: Optional[str] = None,
|
||||
grouped_id: Optional[int] = None,
|
||||
from_scheduled: Optional[bool] = None,
|
||||
legacy: Optional[bool] = None,
|
||||
edit_hide: Optional[bool] = None,
|
||||
pinned: Optional[bool] = None,
|
||||
restriction_reason: Optional[_tl.TypeRestrictionReason] = None,
|
||||
forwards: Optional[int] = None,
|
||||
replies: Optional[_tl.TypeMessageReplies] = None,
|
||||
|
||||
# For MessageAction (mandatory)
|
||||
action: Optional[_tl.TypeMessageAction] = None
|
||||
):
|
||||
# Common properties to messages, then to service (in the order they're defined in the `.tl`)
|
||||
self.out = bool(out)
|
||||
self.mentioned = mentioned
|
||||
self.media_unread = media_unread
|
||||
self.silent = silent
|
||||
self.post = post
|
||||
self.from_scheduled = from_scheduled
|
||||
self.legacy = legacy
|
||||
self.edit_hide = edit_hide
|
||||
self.id = id
|
||||
self.from_id = from_id
|
||||
self.peer_id = peer_id
|
||||
self.fwd_from = fwd_from
|
||||
self.via_bot_id = via_bot_id
|
||||
self.reply_to = reply_to
|
||||
self.date = date
|
||||
self.message = message
|
||||
self.media = None if isinstance(media, _tl.MessageMediaEmpty) else media
|
||||
self.reply_markup = reply_markup
|
||||
self.entities = entities
|
||||
self.views = views
|
||||
self.forwards = forwards
|
||||
self.replies = replies
|
||||
self.edit_date = edit_date
|
||||
self.pinned = pinned
|
||||
self.post_author = post_author
|
||||
self.grouped_id = grouped_id
|
||||
self.restriction_reason = restriction_reason
|
||||
self.ttl_period = ttl_period
|
||||
self.action = action
|
||||
def __init__(self, client, message):
|
||||
self._client = client
|
||||
self._message = message
|
||||
|
||||
# Convenient storage for custom functions
|
||||
# TODO This is becoming a bit of bloat
|
||||
self._client = None
|
||||
self._text = None
|
||||
self._file = None
|
||||
|
@ -246,28 +232,25 @@ class Message(ChatGetter, SenderGetter, tlobject.TLObject):
|
|||
self._linked_chat = None
|
||||
|
||||
sender_id = None
|
||||
if from_id is not None:
|
||||
sender_id = utils.get_peer_id(from_id)
|
||||
elif peer_id:
|
||||
if self.from_id is not None:
|
||||
sender_id = utils.get_peer_id(self.from_id)
|
||||
elif self.peer_id:
|
||||
# If the message comes from a Channel, let the sender be it
|
||||
# ...or...
|
||||
# incoming messages in private conversations no longer have from_id
|
||||
# (layer 119+), but the sender can only be the chat we're in.
|
||||
if post or (not out and isinstance(peer_id, _tl.PeerUser)):
|
||||
sender_id = utils.get_peer_id(peer_id)
|
||||
if self.post or (not self.out and isinstance(self.peer_id, _tl.PeerUser)):
|
||||
sender_id = utils.get_peer_id(self.peer_id)
|
||||
|
||||
# Note that these calls would reset the client
|
||||
ChatGetter.__init__(self, peer_id, broadcast=post)
|
||||
ChatGetter.__init__(self, self.peer_id, broadcast=self.post)
|
||||
SenderGetter.__init__(self, sender_id)
|
||||
|
||||
self._forward = None
|
||||
|
||||
def _finish_init(self, client, entities, input_chat):
|
||||
"""
|
||||
Finishes the initialization of this message by setting
|
||||
the client that sent the message and making use of the
|
||||
known entities.
|
||||
"""
|
||||
@classmethod
|
||||
def _new(cls, client, message, entities, input_chat):
|
||||
self = cls(client, message)
|
||||
self._client = client
|
||||
|
||||
# Make messages sent to ourselves outgoing unless they're forwarded.
|
||||
|
@ -314,6 +297,7 @@ class Message(ChatGetter, SenderGetter, tlobject.TLObject):
|
|||
self._linked_chat = entities.get(utils.get_peer_id(
|
||||
_tl.PeerChannel(self.replies.channel_id)))
|
||||
|
||||
return self
|
||||
|
||||
# endregion Initialization
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user