Implement Telegram->Matrix deletion bridging. Fixes #63

This commit is contained in:
Tulir Asokan
2018-02-20 20:43:05 +02:00
parent 05853115c6
commit 12d4025752
4 changed files with 64 additions and 2 deletions
+1 -1
View File
@@ -46,7 +46,7 @@
* [x] Audio messages
* [x] Video messages
* [x] Documents
* [ ] Message deletions (no way to tell difference between user-specific deletion and global deletion)
* [x] Message deletions
* [ ] Message edits (not supported in Matrix)
* [x] Avatars
* [x] Presence
+3
View File
@@ -69,6 +69,9 @@ bridge:
edits_as_replies: False
# Whether or not Matrix bot messages (type m.notice) should be bridged.
bridge_notices: False
# The maximum number of simultaneous Telegram deletions to handle.
# A large number of simultaneous redactions could put strain on your homeserver.
max_telegram_delete: 10
# The prefix for commands. Only required in non-management rooms.
command_prefix: "!tg"
+10
View File
@@ -425,6 +425,16 @@ class IntentAPI:
return self.send_state_event(room_id, "m.room.member", body, state_key=user_id)
def redact(self, room_id, event_id, reason=None, txn_id=None):
txn_id = txn_id or str(self.client.txn_id) + str(int(time() * 1000))
self.client.txn_id += 1
content = {}
if reason:
content["reason"] = reason
return self.client.request("PUT",
f"/rooms/{quote(room_id)}/redact/{quote(event_id)}/{txn_id}",
content)
@staticmethod
def _get_event_url(room_id, event_type, txn_id):
if not room_id:
+50 -1
View File
@@ -18,12 +18,15 @@ import platform
import os
from telethon.tl.types import *
from mautrix_appservice import MatrixRequestError
from .tgclient import MautrixTelegramClient
from .db import Message as DBMessage
from . import portal as po, puppet as pu, __version__
config = None
# Value updated from config in init()
MAX_DELETIONS = 10
class AbstractUser:
@@ -106,6 +109,10 @@ class AbstractUser:
(UpdateShortChatMessage, UpdateShortMessage, UpdateNewChannelMessage,
UpdateNewMessage, UpdateEditMessage, UpdateEditChannelMessage)):
await self.update_message(update)
elif isinstance(update, UpdateDeleteMessages):
await self.delete_message(update)
elif isinstance(update, UpdateDeleteChannelMessages):
await self.delete_channel_message(update)
elif isinstance(update, (UpdateChatUserTyping, UpdateUserTyping)):
await self.update_typing(update)
elif isinstance(update, UpdateUserStatus):
@@ -206,6 +213,47 @@ class AbstractUser:
return update, None, None
return update, sender, portal
@staticmethod
async def _try_redact(portal, message):
if not portal:
return
try:
await portal.main_intent.redact(message.mx_room, message.mxid)
except MatrixRequestError:
pass
async def delete_message(self, update):
if len(update.messages) > MAX_DELETIONS:
return
for message in update.messages:
message = DBMessage.query.get((message, self.tgid))
if not message:
continue
self.db.delete(message)
number_left = DBMessage.query.filter(DBMessage.mxid == message.mxid,
DBMessage.mx_room == message.mx_room).count()
if number_left == 0:
portal = po.Portal.get_by_mxid(message.mx_room)
await self._try_redact(portal, message)
self.db.commit()
async def delete_channel_message(self, update):
if len(update.messages) > MAX_DELETIONS:
return
portal = po.Portal.get_by_tgid(update.channel_id)
if not portal:
return
for message in update.messages:
message = DBMessage.query.get((message, portal.tgid))
if not message:
continue
self.db.delete(message)
await self._try_redact(portal, message)
self.db.commit()
def update_message(self, original_update):
update, sender, portal = self.get_message_details(original_update)
@@ -231,5 +279,6 @@ class AbstractUser:
def init(context):
global config
global config, MAX_DELETIONS
AbstractUser.az, AbstractUser.db, config, AbstractUser.loop, _ = context
MAX_DELETIONS = config.get("bridge.max_telegram_delete", 10)