Add new features from new layer (#3676)

Updated some documentation regarding raw API.
get_permissions has been adjusted.
Expose more parameters when sending messages.
Update chat action.
Support sending spoilers.
Update buttons.
This commit is contained in:
Devesh Pal 2022-01-24 17:45:02 +05:30 committed by GitHub
parent a25f019964
commit 539e3cb808
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 88 additions and 23 deletions

View File

@ -25,7 +25,7 @@ you should use :tl:`GetFullUser`:
# or even
full = await client(GetFullUserRequest('username'))
bio = full.about
bio = full.full_user.about
See :tl:`UserFull` to know what other fields you can access.

View File

@ -634,13 +634,8 @@ async def get_permissions(
entity = await self.get_entity(entity)
if not user:
if isinstance(entity, _tl.Channel):
FullChat = await self(_tl.fn.channels.GetFullChannel(entity))
elif isinstance(entity, _tl.Chat):
FullChat = await self(_tl.fn.messages.GetFullChat(entity))
else:
return
return FullChat.chats[0].default_banned_rights
if helpers._entity_type(entity) != helpers._EntityType.USER:
return entity.default_banned_rights
entity = await self.get_input_entity(entity)
user = await self.get_input_entity(user)

View File

@ -426,8 +426,10 @@ async def send_message(
ttl: int = None,
# - Send options
reply_to: 'typing.Union[int, _tl.Message]' = None,
send_as: 'hints.EntityLike' = None,
clear_draft: bool = False,
background: bool = None,
noforwards: bool = None,
schedule: 'hints.DateLike' = None,
comment_to: 'typing.Union[int, _tl.Message]' = None,
) -> '_tl.Message':
@ -483,7 +485,7 @@ async def send_message(
entity, message._file._media, reply_to_msg_id=reply_to, message=message._text,
entities=message._fmt_entities, reply_markup=message._reply_markup, silent=message._silent,
schedule_date=schedule, clear_draft=clear_draft,
background=background
background=background, noforwards=noforwards, send_as=send_as
)
else:
request = _tl.fn.messages.SendMessage(
@ -496,7 +498,9 @@ async def send_message(
silent=silent,
background=background,
reply_markup=_custom.button.build_reply_markup(buttons),
schedule_date=schedule
schedule_date=schedule,
noforwards=noforwards,
send_as=send_as
)
result = await self(request)
@ -525,7 +529,9 @@ async def forward_messages(
with_my_score: bool = None,
silent: bool = None,
as_album: bool = None,
schedule: 'hints.DateLike' = None
schedule: 'hints.DateLike' = None,
noforwards: bool = None,
send_as: 'hints.EntityLike' = None
) -> 'typing.Sequence[_tl.Message]':
if as_album is not None:
warnings.warn('the as_album argument is deprecated and no longer has any effect')
@ -565,7 +571,9 @@ async def forward_messages(
silent=silent,
background=background,
with_my_score=with_my_score,
schedule_date=schedule
schedule_date=schedule,
noforwards=noforwards,
send_as=send_as
)
result = await self(req)
sent.extend(self._get_response_message(req, result, entity))

View File

@ -113,6 +113,8 @@ async def send_file(
reply_to: 'typing.Union[int, _tl.Message]' = None,
clear_draft: bool = False,
background: bool = None,
noforwards: bool = None,
send_as: 'hints.EntityLike' = None,
schedule: 'hints.DateLike' = None,
comment_to: 'typing.Union[int, _tl.Message]' = None,
) -> '_tl.Message':
@ -146,13 +148,16 @@ async def send_file(
background=background,
schedule=schedule,
comment_to=comment_to,
noforwards=noforwards,
send_as=send_as
)
async def _send_album(self: 'TelegramClient', entity, files, caption='',
progress_callback=None, reply_to=None,
parse_mode=(), silent=None, schedule=None,
supports_streaming=None, clear_draft=None,
force_document=False, background=None, ttl=None):
force_document=False, background=None, ttl=None,
send_as=None, noforwards=None):
"""Specialized version of .send_file for albums"""
# We don't care if the user wants to avoid cache, we will use it
# anyway. Why? The cached version will be exactly the same thing
@ -212,7 +217,7 @@ async def _send_album(self: 'TelegramClient', entity, files, caption='',
request = _tl.fn.messages.SendMultiMedia(
entity, reply_to_msg_id=reply_to, multi_media=media,
silent=silent, schedule_date=schedule, clear_draft=clear_draft,
background=background
background=background, noforwards=noforwards, send_as=send_as
)
result = await self(request)

View File

@ -76,6 +76,11 @@ class ChatAction(EventBuilder):
return cls.Event(msg,
added_by=added_by,
users=action.users)
elif isinstance(action, _tl.MessageActionChatJoinedByRequest):
# user joined from join request (after getting admin approval)
return cls.Event(msg,
from_approval=True,
users=msg.from_id)
elif isinstance(action, _tl.MessageActionChatDeleteUser):
return cls.Event(msg,
kicked_by=utils.get_peer_id(msg.from_id) if msg.from_id else True,
@ -138,6 +143,10 @@ class ChatAction(EventBuilder):
user_kicked (`bool`):
`True` if the user was kicked by some other.
user_approved (`bool`):
`True` if the user's join request was approved.
along with `user_joined` will be also True.
created (`bool`, optional):
`True` if this chat was just created.
@ -152,7 +161,7 @@ class ChatAction(EventBuilder):
"""
def __init__(self, where, new_photo=None,
added_by=None, kicked_by=None, created=None,
added_by=None, kicked_by=None, created=None, from_approval=None,
users=None, new_title=None, pin_ids=None, pin=None, new_score=None):
if isinstance(where, _tl.MessageService):
self.action_message = where
@ -177,11 +186,12 @@ class ChatAction(EventBuilder):
self.user_added = self.user_joined = self.user_left = \
self.user_kicked = self.unpin = False
if added_by is True:
if added_by is True or from_approval is True:
self.user_joined = True
elif added_by:
self.user_added = True
self._added_by = added_by
self.user_approved = from_approval
# If `from_id` was not present (it's `True`) or the affected
# user was "kicked by itself", then it left. Else it was kicked.

View File

@ -47,6 +47,8 @@ class HTMLToTelegramParser(HTMLParser):
EntityType = _tl.MessageEntityUnderline
elif tag == 'del' or tag == 's':
EntityType = _tl.MessageEntityStrike
elif tag == 'tg-spoiler':
EntityType = _tl.MessageEntitySpoiler
elif tag == 'blockquote':
EntityType = _tl.MessageEntityBlockquote
elif tag == 'code':

View File

@ -19,6 +19,7 @@ DELIMITERS = {
_tl.MessageEntityCode: ('`', '`'),
_tl.MessageEntityItalic: ('_', '_'),
_tl.MessageEntityStrike: ('~~', '~~'),
_tl.MessageEntitySpoiler: ('||', '||'),
_tl.MessageEntityUnderline: ('# ', ''),
}

View File

@ -1,6 +1,8 @@
import typing
from .messagebutton import MessageButton
from ... import _tl
from ..._misc import utils
from ..._misc import utils, hints
class Button:
@ -54,6 +56,7 @@ class Button:
_tl.KeyboardButtonCallback,
_tl.KeyboardButtonGame,
_tl.KeyboardButtonSwitchInline,
_tl.KeyboardButtonUserProfile,
_tl.KeyboardButtonUrl,
_tl.InputKeyboardButtonUrlAuth
))
@ -166,6 +169,29 @@ class Button:
fwd_text=fwd_text
)
@staticmethod
def mention(text, input_entity):
"""
Creates a new inline button linked to the profile of user.
Args:
input_entity:
Input entity of :tl:User to use for profile button.
By default, this is the logged in user (itself), although
you may pass a different input peer.
.. note::
For now, you cannot use ID or username for this argument.
If you want to use different user, you must manually use
`client.get_input_entity() <telethon.client.users.UserMethods.get_input_entity>`.
"""
return _tl.InputKeyboardButtonUserProfile(
text,
utils.get_input_user(input_entity or _tl.InputUserSelf())
)
@classmethod
def text(cls, text, *, resize=None, single_use=None, selective=None):
"""
@ -387,4 +413,4 @@ def build_reply_markup(
return _tl.ReplyInlineMarkup(rows)
# elif is_normal:
return _tl.ReplyKeyboardMarkup(
rows, resize=resize, single_use=single_use, selective=selective)
rows, resize=resize, single_use=single_use, selective=selective)

View File

@ -104,7 +104,7 @@ class InlineResult:
async def click(self, entity=None, reply_to=None, comment_to=None,
silent=False, clear_draft=False, hide_via=False,
background=None):
background=None, send_as=None):
"""
Clicks this result and sends the associated `message`.
@ -137,6 +137,9 @@ class InlineResult:
background (`bool`, optional):
Whether the message should be send in background.
send_as (`entity`, optional):
The channel entity on behalf of which, message should be send.
"""
if entity:
entity = await self._client.get_input_entity(entity)
@ -158,7 +161,8 @@ class InlineResult:
background=background,
clear_draft=clear_draft,
hide_via=hide_via,
reply_to_msg_id=reply_id
reply_to_msg_id=reply_id,
send_as=send_as
)
return self._client._get_response_message(
req, await self._client(req), entity)

View File

@ -189,6 +189,10 @@ class Message(ChatGetter, SenderGetter):
The number of times this message has been forwarded.
""")
noforwards = _fwd('noforwards', """
does the message was sent with noforwards restriction.
""")
replies = _fwd('replies', """
The number of times another message has replied to this message.
""")
@ -205,13 +209,17 @@ class Message(ChatGetter, SenderGetter):
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.
have the same value here.""")
restriction_reason (List[:tl:`RestrictionReason`])
restriction_reason = _fwd('restriction_reason', """
An optional list of reasons why this message was restricted.
If the list is `None`, this message has not been restricted.
""")
reactions = _fwd('reactions', """
emoji reactions attached to the message.
""")
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

View File

@ -71,6 +71,10 @@ class MessageButton:
If it's an inline :tl:`KeyboardButtonCallback` with text and data,
it will be "clicked" and the :tl:`BotCallbackAnswer` returned.
If it's an inline :tl:`KeyboardButtonUserProfile` button, the
`client.get_entity` will be called and the resulting :tl:User will be
returned.
If it's an inline :tl:`KeyboardButtonSwitchInline` button, the
:tl:`StartBot` will be invoked and the resulting updates
returned.
@ -107,6 +111,8 @@ class MessageButton:
return await self._client(req)
except BotResponseTimeoutError:
return None
elif isinstance(self.button, _tl.KeyboardButtonUserProfile):
return await self._client.get_entity(self.button.user_id)
elif isinstance(self.button, _tl.KeyboardButtonSwitchInline):
return await self._client(_tl.fn.messages.StartBot(
bot=self._bot, peer=self._chat, start_param=self.button.query
@ -143,4 +149,4 @@ class MessageButton:
long, lat = share_geo
share_geo = _tl.InputMediaGeoPoint(_tl.InputGeoPoint(lat=lat, long=long))
return await self._client.send_file(self._chat, share_geo)
return await self._client.send_file(self._chat, share_geo)