Implement Telegram->Matrix deletion bridging. Fixes #63
This commit is contained in:
+1
-1
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user