From 18c5a5cd7b4c796361e4f1f644e7cc12c9338416 Mon Sep 17 00:00:00 2001 From: Max Sandholm Date: Sat, 22 Apr 2017 12:33:33 +0300 Subject: [PATCH 1/2] Update bridged displaynames and profile pictures (#27) * Telegram profile pictures and display names are updated The bridge updates the displayname and/or the avatar of the bridged Matrix user when the Telegram user changes them. This is done by checking the name and profile pic of the sender when a message is received from Telegram, and comparing to the database to see if they have changed. If they have, it will update the database and send the updates to the Matrix homeserver. * Handle users without profile pictures correctly * Fix aliases-related breakage --- telematrix/__init__.py | 47 +++++++++++++++++++++++++++++++++++++++++- telematrix/database.py | 4 ++-- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/telematrix/__init__.py b/telematrix/__init__.py index 39524f2..bea6220 100644 --- a/telematrix/__init__.py +++ b/telematrix/__init__.py @@ -171,7 +171,7 @@ async def matrix_transaction(request): except KeyError: pass - if event['type'] == 'm.room.aliases': + if event['type'] == 'm.room.aliases' and event['state_key'] == MATRIX_HOST_BARE: aliases = event['content']['aliases'] links = db.session.query(db.ChatLink)\ @@ -200,6 +200,8 @@ async def matrix_transaction(request): group = TG_BOT.group(link.tg_room) try: + response = None + if event['type'] == 'm.room.message': user_id = event['user_id'] if matrix_is_telegram(user_id): @@ -448,6 +450,45 @@ async def register_join_matrix(chat, room_id, user_id): user_id, {'displayname': name}) await matrix_post('client', 'join/{}'.format(room_id), user_id, {}) +async def update_matrix_displayname_avatar(tg_user): + name = tg_user['first_name'] + if 'last_name' in tg_user: + name += ' ' + tg_user['last_name'] + name += ' (Telegram)' + user_id = USER_ID_FORMAT.format(tg_user['id']) + + db_user = db.session.query(db.TgUser).filter_by(tg_id=tg_user['id']).first() + + profile_photos = await TG_BOT.get_user_profile_photos(tg_user['id']) + pp_file_id = None + try: + pp_file_id = profile_photos['result']['photos'][0][-1]['file_id'] + except: + pp_file_id = None + + if db_user: + if db_user.name != name: + await matrix_put('client', 'profile/{}/displayname'.format(user_id), user_id, {'displayname': name}) + db_user.name = name + if db_user.profile_pic_id != pp_file_id: + if pp_file_id: + pp_uri, _ = await upload_tgfile_to_matrix(pp_file_id, user_id) + await matrix_put('client', 'profile/{}/avatar_url'.format(user_id), user_id, {'avatar_url':pp_uri}) + else: + await matrix_put('client', 'profile/{}/avatar_url'.format(user_id), user_id, {'avatar_url':None}) + db_user.profile_pic_id = pp_file_id + else: + db_user = db.TgUser(tg_user['id'], name, pp_file_id) + await matrix_put('client', 'profile/{}/displayname'.format(user_id), user_id, {'displayname': name}) + if pp_file_id: + pp_uri, _ = await upload_tgfile_to_matrix(pp_file_id, user_id) + await matrix_put('client', 'profile/{}/avatar_url'.format(user_id), user_id, {'avatar_url':pp_uri}) + else: + await matrix_put('client', 'profile/{}/avatar_url'.format(user_id), user_id, {'avatar_url':None}) + db.session.add(db_user) + db.session.commit() + + @TG_BOT.handle('sticker') async def aiotg_sticker(chat, sticker): link = db.session.query(db.ChatLink).filter_by(tg_room=chat.id).first() @@ -455,6 +496,8 @@ async def aiotg_sticker(chat, sticker): print('Unknown telegram chat {}: {}'.format(chat, chat.id)) return + await update_matrix_displayname_avatar(chat.sender); + room_id = link.matrix_room user_id = USER_ID_FORMAT.format(chat.sender['id']) txn_id = quote('{}{}'.format(chat.message['message_id'], chat.id)) @@ -501,6 +544,7 @@ async def aiotg_photo(chat, photo): print('Unknown telegram chat {}: {}'.format(chat, chat.id)) return + await update_matrix_displayname_avatar(chat.sender); room_id = link.matrix_room user_id = USER_ID_FORMAT.format(chat.sender['id']) txn_id = quote('{}{}'.format(chat.message['message_id'], chat.id)) @@ -555,6 +599,7 @@ async def aiotg_message(chat, match): print('Unknown telegram chat {}: {}'.format(chat, chat.id)) return + await update_matrix_displayname_avatar(chat.sender); user_id = USER_ID_FORMAT.format(chat.sender['id']) txn_id = quote('{}:{}'.format(chat.message['message_id'], chat.id)) diff --git a/telematrix/database.py b/telematrix/database.py index 9d65099..b4bab21 100644 --- a/telematrix/database.py +++ b/telematrix/database.py @@ -32,9 +32,9 @@ class TgUser(Base): id = sa.Column(sa.Integer, primary_key=True) tg_id = sa.Column(sa.BigInteger) name = sa.Column(sa.String) - profile_pic_id = sa.Column(sa.String) + profile_pic_id = sa.Column(sa.String, nullable=True) - def __init__(self, tg_id, name, profile_pic_id): + def __init__(self, tg_id, name, profile_pic_id=None): self.tg_id = tg_id self.name = name self.profile_pic_id = profile_pic_id From 5a4b21db77d6efc6ff07b9e1700768063bc1cb36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Christian=20Gr=C3=BCnhage?= Date: Tue, 5 Sep 2017 14:20:48 +0200 Subject: [PATCH 2/2] Add some documentation for bridging rooms (#30) There was no information on how to do this, and while it is common knowledge around those who actively use the bridge, it would be better if it was properly documented. Open for suggestions on how to improve on this. --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 1864e4b..d5e055d 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,16 @@ A bridge between Telegram and [Matrix](http://matrix.org/). Currently under development — this project isn't considered to be in a usable state right now. +## Usage +After the [installation](#installation), follow these steps to bridge a matrix room to a telegram group chat or channel: + - Invite the bot to the telegram chat. + - Send `/alias` in the telegram chat. + - The bot will answer with an alias, something like `#telegram_-XXXXXXXXX:yourserver.example`. Add that as an alias to the matrix room you want to bridge. + +In case it doesn't work make sure that all these are true: + - You are on the same server as the brigde. If that is not the case, you can't set the alias, because you can only set aliases on the server you are on. + - The matrix room is not set to invite only. The bridge currently doesn't support invite only rooms, so the rooms must be set to be open for all. Guests access is not required though. + ## Installation ### Dependencies