diff --git a/telethon/utils.py b/telethon/utils.py index 643fa746..607897e4 100644 --- a/telethon/utils.py +++ b/telethon/utils.py @@ -30,6 +30,8 @@ USERNAME_RE = re.compile( r'@|(?:https?://)?(?:telegram\.(?:me|dog)|t\.me)/(joinchat/)?' ) +VALID_USERNAME_RE = re.compile(r'^[a-zA-Z][\w\d]{3,30}[a-zA-Z\d]$') + def get_display_name(entity): """Gets the input peer for the given "entity" (user, chat or channel) @@ -326,6 +328,7 @@ def is_image(file): return (isinstance(file, str) and (mimetypes.guess_type(file)[0] or '').startswith('image/')) + def is_audio(file): """Returns True if the file extension looks like an audio file""" return (isinstance(file, str) and @@ -353,15 +356,21 @@ def parse_username(username): a string, username or URL. Returns a tuple consisting of both the stripped, lowercase username and whether it is a joinchat/ hash (in which case is not lowercase'd). + + Returns None if the username is not valid. """ username = username.strip() m = USERNAME_RE.match(username) if m: - result = username[m.end():] + username = username[m.end():] is_invite = bool(m.group(1)) - return result if is_invite else result.lower(), is_invite - else: + if is_invite: + return username, True + + if VALID_USERNAME_RE.match(username): return username.lower(), False + else: + return None, False def get_peer_id(peer):