Skip to content
Snippets Groups Projects
Commit e7efc33a authored by Tulir Asokan's avatar Tulir Asokan :cat2:
Browse files

Add Matrix -> Messenger reply and mention bridging

parent aca29921
No related branches found
No related tags found
No related merge requests found
......@@ -11,8 +11,8 @@
* [x] Images
* [ ] Locations
* [x] Formatting
* [ ] Replies
* [ ] Mentions
* [x] Replies
* [x] Mentions
* [x] Message redactions
* [x] Message reactions
* [x] Presence
......
......@@ -13,12 +13,17 @@
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from typing import Optional
from enum import Enum
import re
from fbchat.models import Message
from fbchat.models import Message, Mention
from mautrix.types import TextMessageEventContent, Format
from mautrix.util.formatter import MatrixParser as BaseMatrixParser
from mautrix.types import TextMessageEventContent, Format, UserID, RoomID, RelationType
from mautrix.util.formatter import MatrixParser as BaseMatrixParser, FormattedString
from .. import puppet as pu, user as u
from ..db import Message as DBMessage
class EntityType(Enum):
......@@ -48,13 +53,39 @@ class EntityType(Enum):
return text
MENTION_REGEX = re.compile(r"@([0-9]{15})\u2063(.+)\u2063")
class MatrixParser(BaseMatrixParser):
e = EntityType
@classmethod
def user_pill_to_fstring(cls, msg: FormattedString, user_id: UserID
) -> Optional[FormattedString]:
user = u.User.get_by_mxid(user_id, create=False)
if user and user.fbid:
return FormattedString(f"@{user.fbid}\u2063{msg.text}\u2063")
puppet = pu.Puppet.get_by_mxid(user_id, create=False)
if puppet:
return FormattedString(f"@{puppet.fbid}\u2063{puppet.name or msg.text}\u2063")
return msg
def matrix_to_facebook(content: TextMessageEventContent) -> Message:
def matrix_to_facebook(content: TextMessageEventContent, room_id: RoomID) -> Message:
mentions = []
reply_to_id = None
if content.relates_to.rel_type == RelationType.REFERENCE:
message = DBMessage.get_by_mxid(content.relates_to.event_id, room_id)
if message:
content.trim_reply_fallback()
reply_to_id = message.fbid
if content.format == Format.HTML and content.formatted_body:
text = MatrixParser.parse(content.formatted_body).text
for mention in MENTION_REGEX.finditer(text):
fbid, name = mention.groups()
start, end = mention.start(), mention.end()
text = f"{text[:start]}{name}{text[end:]}"
mentions.append(Mention(thread_id=fbid, offset=start, length=len(name)))
else:
text = content.body
return Message(text=text)
return Message(text=text, mentions=mentions, reply_to_id=reply_to_id)
......@@ -362,7 +362,7 @@ class Portal:
self._last_bridged_mxid = event_id
async def _handle_matrix_text(self, sender: 'u.User', message: TextMessageEventContent) -> str:
return await sender.send(matrix_to_facebook(message), self.fbid, self.fb_type)
return await sender.send(matrix_to_facebook(message, self.mxid), self.fbid, self.fb_type)
async def _handle_matrix_image(self, sender: 'u.User',
message: MediaMessageEventContent) -> str:
......@@ -496,6 +496,8 @@ class Portal:
if message:
evt = await self.main_intent.get_event(message.mx_room, message.mxid)
if evt:
if isinstance(evt.content, TextMessageEventContent):
evt.content.trim_reply_fallback()
content.set_reply(evt)
def _get_facebook_reply(self, reply: str) -> Optional[RelatesTo]:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment