diff --git a/matrix_appservice_kakaotalk/kt/client/client.py b/matrix_appservice_kakaotalk/kt/client/client.py index febd26f..2d54292 100644 --- a/matrix_appservice_kakaotalk/kt/client/client.py +++ b/matrix_appservice_kakaotalk/kt/client/client.py @@ -379,7 +379,16 @@ class Client: await self.user.on_message( Chatlog.deserialize(data["chatlog"]), Long.deserialize(data["channelId"]), - data["channelType"], + str(data["channelType"]), + ) + + async def _on_message_deleted(self, data: dict[str, JSON]) -> None: + await self.user.on_message_deleted( + Long.deserialize(data["chatId"]), + Long.deserialize(data["senderId"]), + int(data["timestamp"]), + Long.deserialize(data["channelId"]), + str(data["channelType"]), ) """ TODO @@ -406,6 +415,7 @@ class Client: def _start_listen(self) -> None: self._add_event_handler("chat", self._on_message) + self._add_event_handler("chat_deleted", self._on_message_deleted) # TODO many more listeners self._add_event_handler("disconnected", self._on_listen_disconnect) self._add_event_handler("switch_server", self._on_switch_server) diff --git a/matrix_appservice_kakaotalk/portal.py b/matrix_appservice_kakaotalk/portal.py index 3b4c5cc..248f25b 100644 --- a/matrix_appservice_kakaotalk/portal.py +++ b/matrix_appservice_kakaotalk/portal.py @@ -1224,6 +1224,23 @@ class Portal(DBPortal, BasePortal): ) return await self._send_message(intent, content, timestamp=timestamp) + async def handle_remote_message_delete( + self, + sender: p.Puppet, + message_id: Long, + timestamp: int, + ) -> None: + if not self.mxid: + return + for message in await DBMessage.get_all_by_ktid(message_id, self.kt_receiver): + try: + await sender.intent_for(self).redact( + message.mx_room, message.mxid, timestamp=timestamp + ) + except MForbidden: + await self.main_intent.redact(message.mx_room, message.mxid, timestamp=timestamp) + await message.delete() + # TODO Many more remote handlers # endregion diff --git a/matrix_appservice_kakaotalk/user.py b/matrix_appservice_kakaotalk/user.py index 0078c72..d70e1fc 100644 --- a/matrix_appservice_kakaotalk/user.py +++ b/matrix_appservice_kakaotalk/user.py @@ -49,6 +49,7 @@ from .kt.types.packet.chat.kickout import KnownKickoutType, KickoutRes METRIC_CONNECT_AND_SYNC = Summary("bridge_connect_and_sync", "calls to connect_and_sync") METRIC_MESSAGE = Summary("bridge_on_message", "calls to on_message") +METRIC_MESSAGE_DELETED = Summary("bridge_on_message_deleted", "calls to on_message_deleted") METRIC_LOGGED_IN = Gauge("bridge_logged_in", "Users logged into the bridge") METRIC_CONNECTED = Gauge("bridge_connected", "Bridge users connected to KakaoTalk") @@ -671,6 +672,26 @@ class User(DBUser, BaseUser): portal.schedule_resync(self, puppet) await portal.handle_remote_message(self, puppet, evt) + @async_time(METRIC_MESSAGE_DELETED) + async def on_message_deleted( + self, + message_id: Long, + sender_id: Long, + timestamp: int, + channel_id: Long, + channel_type: ChannelType, + ) -> None: + portal = await po.Portal.get_by_ktid( + channel_id, + kt_receiver=self.ktid, + kt_type=channel_type, + create=False + ) + if portal and portal.mxid: + await portal.backfill_lock.wait(f"redaction of {message_id}") + puppet = await pu.Puppet.get_by_ktid(sender_id) + await portal.handle_remote_message_delete(puppet, message_id, timestamp) + # TODO Many more handlers # endregion diff --git a/node/src/client.js b/node/src/client.js index 92ff962..3efe337 100644 --- a/node/src/client.js +++ b/node/src/client.js @@ -92,6 +92,28 @@ class UserClient { }) }) + this.#talkClient.on("chat_deleted", (feedChatlog, channel, feed) => { + this.log(`${feed.logId} deleted in channel ${channel.channelId} by user ${feedChatlog.sender.userId}`); + return this.write("chat_deleted", { + chatId: feed.logId, + senderId: feedChatlog.sender.userId, + timestamp: feedChatlog.sendAt, + channelId: channel.channelId, + channelType: channel.info.type, + }) + }) + + this.#talkClient.on("message_hidden", (hideLog, channel, feed) => { + this.log(`Message ${hideLog.logId} hid from channel ${channel.channelId} by user ${hideLog.sender.userId}`); + return this.write("chat_deleted", { + chatId: feed.logId, + senderId: hideLog.sender.userId, + timestamp: hideLog.sendAt, + channelId: channel.channelId, + channelType: channel.info.type, + }) + }) + /* TODO Many more listeners this.#talkClient.on("chat_read", (chat, channel, reader) => { this.log(`chat_read in channel ${channel.channelId}`)