async def handle_matrix_reaction(self, sender: 'u.User', event_id: EventID, reacting_to: EventID, emoji: str) -> None: # Signal doesn't seem to use variation selectors at all emoji = emoji.rstrip("\ufe0f") message = await DBMessage.get_by_mxid(reacting_to, self.mxid) if not message: self.log.debug(f"Ignoring reaction to unknown event {reacting_to}") return existing = await DBReaction.get_by_signal_id(self.chat_id, self.receiver, message.sender, message.timestamp, sender.address) if existing and existing.emoji == emoji: return dedup_id = (message.sender, message.timestamp, emoji) self._reaction_dedup.appendleft(dedup_id) async with self._reaction_lock: reaction = Reaction(emoji=emoji, remove=False, target_author=message.sender, target_sent_timestamp=message.timestamp) await self.signal.react(username=sender.username, recipient=self.chat_id, reaction=reaction) await self._upsert_reaction(existing, self.main_intent, event_id, sender, message, emoji) self.log.trace( f"{sender.mxid} reacted to {message.timestamp} with {emoji}") await self._send_delivery_receipt(event_id)
async def handle_matrix_redaction(self, sender: 'u.User', event_id: EventID, redaction_event_id: EventID) -> None: if not self.mxid: return reaction = await DBReaction.get_by_mxid(event_id, self.mxid) if reaction: try: await reaction.delete() remove_reaction = Reaction(emoji=reaction.emoji, remove=True, target_author=Address(uuid=reaction.msg_author), target_sent_timestamp=reaction.msg_timestamp) await self.signal.react(username=sender.username, recipient=self.recipient, reaction=remove_reaction) await self._send_delivery_receipt(redaction_event_id) self.log.trace(f"Removed {reaction} after Matrix redaction") except Exception: self.log.exception("Removing reaction failed")