mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-11-23 01:46:35 +03:00
Allow specifying a phone number or username for common methods
This commit is contained in:
parent
fb5c43b539
commit
81ccd21cdb
|
@ -15,7 +15,7 @@ from .errors import (RPCError, UnauthorizedError, InvalidParameterError,
|
||||||
PhoneCodeInvalidError, InvalidChecksumError)
|
PhoneCodeInvalidError, InvalidChecksumError)
|
||||||
|
|
||||||
# For sending and receiving requests
|
# For sending and receiving requests
|
||||||
from .tl import Session, JsonSession
|
from .tl import Session, JsonSession, TLObject
|
||||||
|
|
||||||
# Required to get the password salt
|
# Required to get the password salt
|
||||||
from .tl.functions.account import GetPasswordRequest
|
from .tl.functions.account import GetPasswordRequest
|
||||||
|
@ -30,6 +30,8 @@ from .tl.functions.messages import (
|
||||||
GetDialogsRequest, GetHistoryRequest, ReadHistoryRequest, SendMediaRequest,
|
GetDialogsRequest, GetHistoryRequest, ReadHistoryRequest, SendMediaRequest,
|
||||||
SendMessageRequest)
|
SendMessageRequest)
|
||||||
|
|
||||||
|
from .tl.functions.contacts import GetContactsRequest, ResolveUsernameRequest
|
||||||
|
|
||||||
# For .get_me() and ensuring we're authorized
|
# For .get_me() and ensuring we're authorized
|
||||||
from .tl.functions.users import GetUsersRequest
|
from .tl.functions.users import GetUsersRequest
|
||||||
|
|
||||||
|
@ -44,7 +46,7 @@ from .tl.types import (
|
||||||
MessageMediaContact, MessageMediaDocument, MessageMediaPhoto,
|
MessageMediaContact, MessageMediaDocument, MessageMediaPhoto,
|
||||||
UserProfilePhotoEmpty, InputUserSelf)
|
UserProfilePhotoEmpty, InputUserSelf)
|
||||||
|
|
||||||
from .utils import find_user_or_chat, get_input_peer, get_extension
|
from .utils import find_user_or_chat, get_extension
|
||||||
|
|
||||||
|
|
||||||
class TelegramClient(TelegramBareClient):
|
class TelegramClient(TelegramBareClient):
|
||||||
|
@ -377,9 +379,13 @@ class TelegramClient(TelegramBareClient):
|
||||||
message,
|
message,
|
||||||
link_preview=True):
|
link_preview=True):
|
||||||
"""Sends a message to the given entity (or input peer)
|
"""Sends a message to the given entity (or input peer)
|
||||||
and returns the sent message ID"""
|
and returns the sent message ID.
|
||||||
|
|
||||||
|
The entity may be a phone or an username at the expense of
|
||||||
|
some performance loss.
|
||||||
|
"""
|
||||||
request = SendMessageRequest(
|
request = SendMessageRequest(
|
||||||
peer=get_input_peer(entity),
|
peer=self._get_entity(entity),
|
||||||
message=message,
|
message=message,
|
||||||
entities=[],
|
entities=[],
|
||||||
no_webpage=not link_preview
|
no_webpage=not link_preview
|
||||||
|
@ -400,7 +406,7 @@ class TelegramClient(TelegramBareClient):
|
||||||
"""
|
"""
|
||||||
Gets the message history for the specified entity
|
Gets the message history for the specified entity
|
||||||
|
|
||||||
:param entity: The entity (or input peer) from whom to retrieve the message history
|
:param entity: The entity from whom to retrieve the message history
|
||||||
:param limit: Number of messages to be retrieved
|
:param limit: Number of messages to be retrieved
|
||||||
:param offset_date: Offset date (messages *previous* to this date will be retrieved)
|
:param offset_date: Offset date (messages *previous* to this date will be retrieved)
|
||||||
:param offset_id: Offset message ID (only messages *previous* to the given ID will be retrieved)
|
:param offset_id: Offset message ID (only messages *previous* to the given ID will be retrieved)
|
||||||
|
@ -410,9 +416,12 @@ class TelegramClient(TelegramBareClient):
|
||||||
|
|
||||||
:return: A tuple containing total message count and two more lists ([messages], [senders]).
|
:return: A tuple containing total message count and two more lists ([messages], [senders]).
|
||||||
Note that the sender can be null if it was not found!
|
Note that the sender can be null if it was not found!
|
||||||
|
|
||||||
|
The entity may be a phone or an username at the expense of
|
||||||
|
some performance loss.
|
||||||
"""
|
"""
|
||||||
result = self(GetHistoryRequest(
|
result = self(GetHistoryRequest(
|
||||||
get_input_peer(entity),
|
peer=self._get_entity(entity),
|
||||||
limit=limit,
|
limit=limit,
|
||||||
offset_date=offset_date,
|
offset_date=offset_date,
|
||||||
offset_id=offset_id,
|
offset_id=offset_id,
|
||||||
|
@ -442,7 +451,11 @@ class TelegramClient(TelegramBareClient):
|
||||||
Either a list of messages (or a single message) can be given,
|
Either a list of messages (or a single message) can be given,
|
||||||
or the maximum message ID (until which message we want to send the read acknowledge).
|
or the maximum message ID (until which message we want to send the read acknowledge).
|
||||||
|
|
||||||
Returns an AffectedMessages TLObject"""
|
Returns an AffectedMessages TLObject
|
||||||
|
|
||||||
|
The entity may be a phone or an username at the expense of
|
||||||
|
some performance loss.
|
||||||
|
"""
|
||||||
if max_id is None:
|
if max_id is None:
|
||||||
if not messages:
|
if not messages:
|
||||||
raise InvalidParameterError(
|
raise InvalidParameterError(
|
||||||
|
@ -454,7 +467,7 @@ class TelegramClient(TelegramBareClient):
|
||||||
max_id = messages.id
|
max_id = messages.id
|
||||||
|
|
||||||
return self(ReadHistoryRequest(
|
return self(ReadHistoryRequest(
|
||||||
peer=get_input_peer(entity),
|
peer=self._get_entity(entity),
|
||||||
max_id=max_id
|
max_id=max_id
|
||||||
))
|
))
|
||||||
|
|
||||||
|
@ -470,7 +483,11 @@ class TelegramClient(TelegramBareClient):
|
||||||
|
|
||||||
def send_document_file(self, input_file, entity, caption=''):
|
def send_document_file(self, input_file, entity, caption=''):
|
||||||
"""Sends a previously uploaded input_file
|
"""Sends a previously uploaded input_file
|
||||||
(which should be a document) to the given entity (or input peer)"""
|
(which should be a document) to the given entity.
|
||||||
|
|
||||||
|
The entity may be a phone or an username at the expense of
|
||||||
|
some performance loss.
|
||||||
|
"""
|
||||||
|
|
||||||
# Determine mime-type and attributes
|
# Determine mime-type and attributes
|
||||||
# Take the first element by using [0] since it returns a tuple
|
# Take the first element by using [0] since it returns a tuple
|
||||||
|
@ -494,9 +511,14 @@ class TelegramClient(TelegramBareClient):
|
||||||
entity)
|
entity)
|
||||||
|
|
||||||
def send_media_file(self, input_media, entity):
|
def send_media_file(self, input_media, entity):
|
||||||
"""Sends any input_media (contact, document, photo...) to the given entity"""
|
"""Sends any input_media (contact, document, photo...)
|
||||||
|
to the given entity.
|
||||||
|
|
||||||
|
The entity may be a phone or an username at the expense of
|
||||||
|
some performance loss.
|
||||||
|
"""
|
||||||
self(SendMediaRequest(
|
self(SendMediaRequest(
|
||||||
peer=get_input_peer(entity),
|
peer=self._get_entity(entity),
|
||||||
media=input_media
|
media=input_media
|
||||||
))
|
))
|
||||||
|
|
||||||
|
@ -511,6 +533,7 @@ class TelegramClient(TelegramBareClient):
|
||||||
download_big=True):
|
download_big=True):
|
||||||
"""Downloads the profile photo for an user or a chat (including channels).
|
"""Downloads the profile photo for an user or a chat (including channels).
|
||||||
Returns False if no photo was provided, or if it was Empty"""
|
Returns False if no photo was provided, or if it was Empty"""
|
||||||
|
# TODO Support specifying an entity
|
||||||
|
|
||||||
if (not profile_photo or
|
if (not profile_photo or
|
||||||
isinstance(profile_photo, UserProfilePhotoEmpty) or
|
isinstance(profile_photo, UserProfilePhotoEmpty) or
|
||||||
|
@ -549,6 +572,7 @@ class TelegramClient(TelegramBareClient):
|
||||||
two parameters, uploaded size and total file size (both in bytes).
|
two parameters, uploaded size and total file size (both in bytes).
|
||||||
This will be called every time a part is downloaded
|
This will be called every time a part is downloaded
|
||||||
"""
|
"""
|
||||||
|
# TODO Support specifying a message
|
||||||
if type(message_media) == MessageMediaPhoto:
|
if type(message_media) == MessageMediaPhoto:
|
||||||
return self.download_photo(message_media, file, add_extension,
|
return self.download_photo(message_media, file, add_extension,
|
||||||
progress_callback)
|
progress_callback)
|
||||||
|
@ -561,6 +585,7 @@ class TelegramClient(TelegramBareClient):
|
||||||
return self.download_contact(message_media, file,
|
return self.download_contact(message_media, file,
|
||||||
add_extension)
|
add_extension)
|
||||||
|
|
||||||
|
# TODO Make these private and only expose download_msg_media?
|
||||||
def download_photo(self,
|
def download_photo(self,
|
||||||
message_media_photo,
|
message_media_photo,
|
||||||
file,
|
file,
|
||||||
|
@ -683,6 +708,61 @@ class TelegramClient(TelegramBareClient):
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
|
# region Small utilities to make users' life easier
|
||||||
|
|
||||||
|
def _get_entity(self, entity):
|
||||||
|
"""Turns an entity into a valid Telegram user or chat.
|
||||||
|
If "entity" is a string, and starts with '+', or if
|
||||||
|
it is an integer value, it will be resolved as if it
|
||||||
|
were a phone number.
|
||||||
|
|
||||||
|
If "entity" is a string and doesn't start with '+', or
|
||||||
|
it starts with '@', it will be resolved from the username.
|
||||||
|
If no exact match is returned, an error will be raised.
|
||||||
|
|
||||||
|
If the entity is neither, and it's not a TLObject, an
|
||||||
|
error will be raised.
|
||||||
|
"""
|
||||||
|
if isinstance(entity, TLObject):
|
||||||
|
return entity
|
||||||
|
|
||||||
|
if isinstance(entity, int):
|
||||||
|
entity = '+{}'.format(entity) # Turn it into a phone-like str
|
||||||
|
|
||||||
|
if isinstance(entity, str):
|
||||||
|
if entity.startswith('+'):
|
||||||
|
contacts = self(GetContactsRequest(''))
|
||||||
|
try:
|
||||||
|
stripped_phone = entity.strip('+')
|
||||||
|
return next(
|
||||||
|
u for u in contacts.users
|
||||||
|
if u.phone and u.phone.endswith(stripped_phone)
|
||||||
|
)
|
||||||
|
except StopIteration:
|
||||||
|
raise ValueError(
|
||||||
|
'Could not find user with phone {}, '
|
||||||
|
'add them to your contacts first'.format(entity)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
username = entity.strip('@').lower()
|
||||||
|
resolved = self(ResolveUsernameRequest(username))
|
||||||
|
for c in resolved.chats:
|
||||||
|
if getattr(c, 'username', '').lower() == username:
|
||||||
|
return c
|
||||||
|
for u in resolved.users:
|
||||||
|
if getattr(u, 'username', '').lower() == username:
|
||||||
|
return u
|
||||||
|
|
||||||
|
raise ValueError(
|
||||||
|
'Could not find user with username {}'.format(entity)
|
||||||
|
)
|
||||||
|
|
||||||
|
raise ValueError(
|
||||||
|
'Cannot turn "{}" into any entity (user or chat)'.format(entity)
|
||||||
|
)
|
||||||
|
|
||||||
|
# endregion
|
||||||
|
|
||||||
# region Updates handling
|
# region Updates handling
|
||||||
|
|
||||||
def add_update_handler(self, handler):
|
def add_update_handler(self, handler):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user