Support t.me/ links when resolving usernames/joinchat links

Closes #419
This commit is contained in:
Lonami Exo 2017-11-10 13:27:51 +01:00
parent c4e07cff57
commit 81baced12b
2 changed files with 37 additions and 7 deletions

View File

@ -30,8 +30,9 @@ from .tl.functions.contacts import (
)
from .tl.functions.messages import (
GetDialogsRequest, GetHistoryRequest, ReadHistoryRequest, SendMediaRequest,
SendMessageRequest, GetChatsRequest,
GetAllDraftsRequest)
SendMessageRequest, GetChatsRequest, GetAllDraftsRequest,
CheckChatInviteRequest
)
from .tl.functions import channels
from .tl.functions import messages
@ -49,13 +50,13 @@ from .tl.types import (
Message, MessageMediaContact, MessageMediaDocument, MessageMediaPhoto,
InputUserSelf, UserProfilePhoto, ChatPhoto, UpdateMessageID,
UpdateNewChannelMessage, UpdateNewMessage, UpdateShortSentMessage,
PeerUser, InputPeerUser, InputPeerChat, InputPeerChannel, MessageEmpty
PeerUser, InputPeerUser, InputPeerChat, InputPeerChannel, MessageEmpty,
ChatInvite, ChatInviteAlready
)
from .tl.types.messages import DialogsSlice
from .extensions import markdown
class TelegramClient(TelegramBareClient):
"""Full featured TelegramClient meant to extend the basic functionality -
@ -1053,8 +1054,18 @@ class TelegramClient(TelegramBareClient):
entity = phone
self(GetContactsRequest(0))
else:
entity = string.strip('@').lower()
self(ResolveUsernameRequest(entity))
entity, is_join_chat = EntityDatabase.parse_username(string)
if is_join_chat:
invite = self(CheckChatInviteRequest(entity))
if isinstance(invite, ChatInvite):
# If it's an invite to a chat, the user must join before
# for the link to be resolved and work, otherwise raise.
if invite.channel:
return invite.channel
elif isinstance(invite, ChatInviteAlready):
return invite.chat
else:
self(ResolveUsernameRequest(entity))
# MtProtoSender will call .process_entities on the requests made
try:
return self.session.entities[entity]

View File

@ -9,6 +9,11 @@ from ..tl.types import (
from .. import utils # Keep this line the last to maybe fix #357
USERNAME_RE = re.compile(
r'@|(?:https?://)?(?:telegram\.(?:me|dog)|t\.me)/(joinchat/)?'
)
class EntityDatabase:
def __init__(self, input_list=None, enabled=True, enabled_full=True):
"""Creates a new entity database with an initial load of "Input"
@ -153,7 +158,8 @@ class EntityDatabase:
if phone:
return self._phone_id[phone]
else:
return self._username_id[key.lstrip('@').lower()]
username, _ = EntityDatabase.parse_username(key)
return self._username_id[username.lower()]
except KeyError as e:
raise ValueError() from e
@ -206,6 +212,19 @@ class EntityDatabase:
if phone.isdigit():
return phone
@staticmethod
def parse_username(username):
"""Parses the given username or channel access hash, given
a string, username or URL. Returns a tuple consisting of
both the stripped username and whether it is a joinchat/ hash.
"""
username = username.strip()
m = USERNAME_RE.match(username)
if m:
return username[m.end():], bool(m.group(1))
else:
return username, False
def get_input_entity(self, peer):
try:
i = utils.get_peer_id(peer, add_mark=True)