Add command to set username and fix some bugs

This commit is contained in:
Tulir Asokan
2018-12-19 22:36:51 +02:00
parent d3d02f173a
commit 65e0ebdb37
3 changed files with 37 additions and 6 deletions
+1
View File
@@ -271,6 +271,7 @@ class AbstractUser(ABC):
# TODO duplication not checked
puppet = pu.Puppet.get(TelegramID(update.user_id))
if isinstance(update, UpdateUserName):
puppet.username = update.username
if await puppet.update_displayname(self, update):
puppet.save()
elif isinstance(update, UpdateUserPhoto):
+29 -2
View File
@@ -21,7 +21,9 @@ from telethon.errors import (
AccessTokenExpiredError, AccessTokenInvalidError, FirstNameInvalidError, FloodWaitError,
PasswordHashInvalidError, PhoneCodeExpiredError, PhoneCodeInvalidError,
PhoneNumberAppSignupForbiddenError, PhoneNumberBannedError, PhoneNumberFloodError,
PhoneNumberOccupiedError, PhoneNumberUnoccupiedError, SessionPasswordNeededError)
PhoneNumberOccupiedError, PhoneNumberUnoccupiedError, SessionPasswordNeededError,
UsernameInvalidError, UsernameNotModifiedError, UsernameOccupiedError)
from telethon.tl.functions.account import UpdateUsernameRequest
from . import command_handler, CommandEvent, SECTION_AUTH
from .. import puppet as pu, user as u
@@ -82,7 +84,8 @@ async def login_matrix(evt: CommandEvent) -> Optional[Dict]:
}
if evt.config["appservice.public.enabled"]:
prefix = evt.config["appservice.public.external"]
url = f"{prefix}/matrix-login?token={evt.public_website.make_token(evt.sender.mxid, '/matrix-login')}"
token = evt.public_website.make_token(evt.sender.mxid, "/matrix-login")
url = f"{prefix}/matrix-login?token={token}"
if allow_matrix_login:
return await evt.reply(
"This bridge instance allows you to log in inside or outside Matrix.\n\n"
@@ -330,3 +333,27 @@ async def logout(evt: CommandEvent) -> Optional[Dict]:
if await evt.sender.log_out():
return await evt.reply("Logged out successfully.")
return await evt.reply("Failed to log out.")
@command_handler(needs_auth=True,
help_section=SECTION_AUTH,
help_text="Change your Telegram username")
async def username(evt: CommandEvent) -> Optional[Dict]:
if len(evt.args) == 0:
return await evt.reply("**Usage:** `$cmdprefix+sp username <new username>`")
if evt.sender.is_bot:
return await evt.reply("Bots can't set their own username.")
try:
await evt.sender.client(UpdateUsernameRequest(username=evt.args[0]))
except UsernameInvalidError:
return await evt.reply("Invalid username. Usernames must be between 5 and 30 alphanumeric "
"characters.")
except UsernameNotModifiedError:
return await evt.reply("That is your current username.")
except UsernameOccupiedError:
return await evt.reply("That username is already in use.")
await evt.sender.update_info()
if len(evt.sender.username) == 0:
await evt.reply("Username removed")
else:
await evt.reply(f"Username changed to {evt.sender.username}")
+7 -4
View File
@@ -14,7 +14,7 @@
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from typing import Awaitable, Coroutine, Dict, List, Optional, Pattern, TYPE_CHECKING
from typing import Awaitable, Coroutine, Dict, List, Optional, Pattern, Union, TYPE_CHECKING
from difflib import SequenceMatcher
from enum import Enum
from aiohttp import ServerDisconnectedError
@@ -24,7 +24,7 @@ import re
from sqlalchemy import orm
from telethon.tl.types import UserProfilePhoto, User, FileLocation
from telethon.tl.types import UserProfilePhoto, User, FileLocation, UpdateUserName, PeerUser
from mautrix_appservice import AppService, IntentAPI, IntentError, MatrixRequestError
from .types import MatrixUserID, TelegramID
@@ -320,7 +320,7 @@ class Puppet:
if name:
break
if info.deleted:
if isinstance(info, User) and info.deleted:
name = f"Deleted account {info.id}"
elif not name:
name = info.id
@@ -345,12 +345,15 @@ class Puppet:
if changed:
self.save()
async def update_displayname(self, source: 'AbstractUser', info: User) -> bool:
async def update_displayname(self, source: 'AbstractUser', info: Union[User, UpdateUserName]
) -> bool:
ignore_source = (not source.is_relaybot
and self.displayname_source is not None
and self.displayname_source != source.tgid)
if ignore_source:
return False
if isinstance(info, UpdateUserName):
info = await source.client.get_entity(PeerUser(self.tgid))
displayname = self.get_displayname(info)
if displayname != self.displayname: