Matrix: Add more messages events and handle errors.

This commit is contained in:
Rhea Parekh 2018-05-11 03:08:29 -07:00 committed by Tim Abbott
parent 979c0e50d6
commit 9362755039

View file

@ -1,15 +1,16 @@
#!/usr/bin/env python #!/usr/bin/env python
import os import os
import logging import logging
import signal import signal
import traceback import traceback
import zulip
import sys
from types import FrameType from types import FrameType
from typing import Any, Callable, Dict from typing import Any, Callable, Dict
from matrix_bridge_config import config from matrix_bridge_config import config
import zulip from matrix_client.api import MatrixRequestError
from matrix_client.client import MatrixClient from matrix_client.client import MatrixClient
def die(signal: int, frame: FrameType) -> None: def die(signal: int, frame: FrameType) -> None:
@ -19,41 +20,62 @@ def die(signal: int, frame: FrameType) -> None:
def zulip_to_matrix_username(full_name: str, site: str) -> str: def zulip_to_matrix_username(full_name: str, site: str) -> str:
return "@**{0}**:{1}".format(full_name, site) return "@**{0}**:{1}".format(full_name, site)
def matrix_to_zulip(zulip_client: zulip.Client, def matrix_to_zulip(zulip_client: zulip.Client, zulip_config: Dict[str, Any],
cfg: Dict[str, Any]) -> Callable[[Any, Dict[str, Any]], None]: matrix_config: Dict[str, Any]) -> Callable[[Any, Dict[str, Any]], None]:
def _matrix_to_zulip(room: Any, event: Dict[str, Any]) -> None: def _matrix_to_zulip(room: Any, event: Dict[str, Any]) -> None:
"""Matrix -> Zulip
""" """
if event['type'] == "m.room.member": Matrix -> Zulip
if event['membership'] == "join": """
content = "{0} joined".format(event['content']['displayname']) content = get_message_content_from_event(event)
elif event['type'] == "m.room.message":
if event['content']['msgtype'] == "m.text": zulip_bot_user = ('@%s:matrix.org' % matrix_config['username'])
content = "{0}: {1}".format(event['sender'], event['content']['body']) # We do this to identify the messages generated from Zulip -> Matrix
else: # and we make sure we don't forward it again to the Zulip stream.
content = event['type'] not_from_zulip_bot = ('body' not in event['content'] or
not_from_bot = ('body' not in event['content'] or event['sender'] != zulip_bot_user)
not event['content']['body'].startswith("@**"))
if not_from_bot: if not_from_zulip_bot:
print(zulip_client.send_message({ try:
"sender": zulip_client.email, result = zulip_client.send_message({
"type": "stream", "sender": zulip_client.email,
"to": cfg["stream"], "type": "stream",
"subject": cfg["subject"], "to": zulip_config["stream"],
"content": content, "subject": zulip_config["subject"],
})) "content": content,
})
except MatrixRequestError as e:
# Generally raised when user is forbidden
raise Exception(e)
if result['result'] != 'success':
# Generally raised when API key is invalid
raise Exception(result['msg'])
return _matrix_to_zulip return _matrix_to_zulip
def zulip_to_matrix(cfg: Dict[str, Any], room: Any) -> Callable[[Dict[str, Any]], None]: def get_message_content_from_event(event: Dict[str, Any]) -> str:
site_without_http = cfg["site"].replace("https://", "").replace("http://", "") if event['type'] == "m.room.member":
if event['membership'] == "join":
content = "{0} joined".format(event['sender'])
elif event['membership'] == "leave":
content = "{0} quit".format(event['sender'])
elif event['type'] == "m.room.message":
if event['content']['msgtype'] == "m.text" or event['content']['msgtype'] == "m.emote":
content = "{0}: {1}".format(event['sender'], event['content']['body'])
else:
content = event['type']
return content
def zulip_to_matrix(config: Dict[str, Any], room: Any) -> Callable[[Dict[str, Any]], None]:
site_without_http = config["site"].replace("https://", "").replace("http://", "")
def _zulip_to_matrix(msg: Dict[str, Any]) -> None: def _zulip_to_matrix(msg: Dict[str, Any]) -> None:
"""Zulip -> Matrix """
Zulip -> Matrix
""" """
isa_stream = msg["type"] == "stream" isa_stream = msg["type"] == "stream"
not_from_bot = msg["sender_email"] != cfg["email"] not_from_bot = msg["sender_email"] != config["email"]
in_the_specified_stream = msg["display_recipient"] == cfg["stream"] in_the_specified_stream = msg["display_recipient"] == config["stream"]
at_the_specified_subject = msg["subject"] == cfg["subject"] at_the_specified_subject = msg["subject"] == config["subject"]
if isa_stream and not_from_bot and in_the_specified_stream and at_the_specified_subject: if isa_stream and not_from_bot and in_the_specified_stream and at_the_specified_subject:
matrix_username = zulip_to_matrix_username(msg["sender_full_name"], site_without_http) matrix_username = zulip_to_matrix_username(msg["sender_full_name"], site_without_http)
matrix_text = "{0}: {1}".format(matrix_username, matrix_text = "{0}: {1}".format(matrix_username,
@ -84,7 +106,7 @@ if __name__ == '__main__':
matrix_client.login_with_password(matrix_config["username"], matrix_client.login_with_password(matrix_config["username"],
matrix_config["password"]) matrix_config["password"])
room = matrix_client.join_room(matrix_config["room_id"]) room = matrix_client.join_room(matrix_config["room_id"])
room.add_listener(matrix_to_zulip(zulip_client, zulip_config)) room.add_listener(matrix_to_zulip(zulip_client, zulip_config, matrix_config))
print("Starting listener thread on Matrix client") print("Starting listener thread on Matrix client")
matrix_client.start_listener_thread() matrix_client.start_listener_thread()