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

Add Messenger -> Matrix sticker bridging (ref #2)

parent 7706efb1
Branches
Tags
No related merge requests found
...@@ -4,6 +4,10 @@ ...@@ -4,6 +4,10 @@
* [ ] Message content * [ ] Message content
* [x] Text * [x] Text
* [ ] Media * [ ] Media
* [ ] Stickers
* [ ] Files
* [ ] Voice messages
* [ ] Images
* [ ] Formatting * [ ] Formatting
* [ ] Replies * [ ] Replies
* [ ] Mentions * [ ] Mentions
...@@ -25,6 +29,10 @@ ...@@ -25,6 +29,10 @@
* [ ] Message content * [ ] Message content
* [x] Text * [x] Text
* [ ] Media * [ ] Media
* [x] Stickers
* [ ] Files
* [ ] Voice messages
* [ ] Images
* [ ] Formatting * [ ] Formatting
* [ ] Replies * [ ] Replies
* [ ] Mentions * [ ] Mentions
......
...@@ -19,10 +19,12 @@ import logging ...@@ -19,10 +19,12 @@ import logging
from yarl import URL from yarl import URL
import aiohttp import aiohttp
import magic
from fbchat import (ThreadType, Thread, User as FBUser, Group as FBGroup, Page as FBPage, from fbchat import (ThreadType, Thread, User as FBUser, Group as FBGroup, Page as FBPage,
Message as FBMessage) Message as FBMessage, Sticker as FBSticker)
from mautrix.types import RoomID, EventType, ContentURI, MessageEventContent, EventID from mautrix.types import (RoomID, EventType, ContentURI, MessageEventContent, EventID,
MediaMessageEventContent, ImageInfo, MessageType)
from mautrix.appservice import AppService, IntentAPI from mautrix.appservice import AppService, IntentAPI
from mautrix.errors import MForbidden from mautrix.errors import MForbidden
...@@ -141,11 +143,12 @@ class Portal: ...@@ -141,11 +143,12 @@ class Portal:
return path[path.rfind("/") + 1:] return path[path.rfind("/") + 1:]
@staticmethod @staticmethod
async def _reupload_photo(url: str, client: IntentAPI) -> ContentURI: async def _reupload_photo(url: str, intent: IntentAPI) -> Tuple[ContentURI, str]:
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
resp = await session.get(url) resp = await session.get(url)
data = await resp.read() data = await resp.read()
return await client.upload_media(data) mime = magic.from_buffer(data, mime=True)
return await intent.upload_media(data, mime_type=mime), mime
async def _update_name(self, name: str) -> None: async def _update_name(self, name: str) -> None:
if self.name != name: if self.name != name:
...@@ -159,7 +162,7 @@ class Portal: ...@@ -159,7 +162,7 @@ class Portal:
if self.photo_id != photo_id or len(self.avatar_uri) == 0: if self.photo_id != photo_id or len(self.avatar_uri) == 0:
self.photo_id = photo_id self.photo_id = photo_id
if self.mxid and not self.is_direct: if self.mxid and not self.is_direct:
self.avatar_uri = await self._reupload_photo(photo_url, self.main_intent) self.avatar_uri, _ = await self._reupload_photo(photo_url, self.main_intent)
await self.main_intent.set_room_avatar(self.mxid, self.avatar_uri) await self.main_intent.set_room_avatar(self.mxid, self.avatar_uri)
async def _update_participants(self, source: 'u.User', info: ThreadClass) -> None: async def _update_participants(self, source: 'u.User', info: ThreadClass) -> None:
...@@ -250,12 +253,33 @@ class Portal: ...@@ -250,12 +253,33 @@ class Portal:
if not self.mxid: if not self.mxid:
await self.create_matrix_room(source) await self.create_matrix_room(source)
self.messages_by_fbid[message.uid] = None self.messages_by_fbid[message.uid] = None
event_id = await sender.intent.send_text(self.mxid, message.text) if message.sticker is not None:
event_id = await self._handle_facebook_sticker(sender.intent, message.sticker)
elif len(message.attachments) > 0:
pass
return
else:
event_id = await self._handle_facebook_text(sender.intent, message)
self.messages_by_mxid[event_id] = message.uid self.messages_by_mxid[event_id] = message.uid
self.messages_by_fbid[message.uid] = event_id self.messages_by_fbid[message.uid] = event_id
self.last_bridged_mxid = event_id self.last_bridged_mxid = event_id
await source.markAsDelivered(self.fbid, message.uid) await source.markAsDelivered(self.fbid, message.uid)
async def _handle_facebook_text(self, intent: IntentAPI, message: FBMessage) -> EventID:
return await intent.send_text(self.mxid, message.text)
async def _handle_facebook_sticker(self, intent: IntentAPI, sticker: FBSticker) -> EventID:
# TODO handle animated stickers?
mxc, mime = await self._reupload_photo(sticker.url, intent)
return await intent.send_sticker(room_id=self.mxid, url=mxc,
info=ImageInfo(width=sticker.width,
height=sticker.height,
mimetype=mime),
text=sticker.label)
async def _handle_facebook_attachment(self, sender: 'p.Puppet', attachment) -> None:
pass
async def handle_facebook_unsend(self, source: 'u.User', sender: 'p.Puppet', message_id: str async def handle_facebook_unsend(self, source: 'u.User', sender: 'p.Puppet', message_id: str
) -> None: ) -> None:
if not self.mxid: if not self.mxid:
......
...@@ -90,7 +90,7 @@ class Puppet: ...@@ -90,7 +90,7 @@ class Puppet:
print(photo_id, self.photo_id) print(photo_id, self.photo_id)
if photo_id != self.photo_id or len(self.avatar_uri) == 0: if photo_id != self.photo_id or len(self.avatar_uri) == 0:
self.photo_id = photo_id self.photo_id = photo_id
self.avatar_uri = await p.Portal._reupload_photo(photo_url, self.intent) self.avatar_uri, _ = await p.Portal._reupload_photo(photo_url, self.intent)
await self.intent.set_avatar_url(self.avatar_uri) await self.intent.set_avatar_url(self.avatar_uri)
@classmethod @classmethod
......
...@@ -194,7 +194,7 @@ class User(Client): ...@@ -194,7 +194,7 @@ class User(Client):
self.log.debug(f"Ignoring message from self ({mid}, {author_id}, {message}, " self.log.debug(f"Ignoring message from self ({mid}, {author_id}, {message}, "
f"{thread_id}, {thread_type})") f"{thread_id}, {thread_type})")
return return
self.log.debug(f"onMessage({mid}, {author_id}, {message}, {thread_id}, {thread_type})") self.log.debug(f"onMessage({message_object}, {thread_id}, {thread_type})")
fb_receiver = self.uid if thread_type == ThreadType.USER else None fb_receiver = self.uid if thread_type == ThreadType.USER else None
portal = po.Portal.get_by_fbid(thread_id, fb_receiver, thread_type) portal = po.Portal.get_by_fbid(thread_id, fb_receiver, thread_type)
puppet = pu.Puppet.get(author_id) puppet = pu.Puppet.get(author_id)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment