From 7ffa47c26714cbc7e3e92097ba131ff298523560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20B=C3=B6hmke?= Date: Sat, 18 Sep 2021 12:12:54 +0200 Subject: [PATCH 1/2] join room before sending message --- matrix_webhook/handler.py | 5 +++++ matrix_webhook/utils.py | 25 ++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/matrix_webhook/handler.py b/matrix_webhook/handler.py index 1f1ac5f..3460810 100644 --- a/matrix_webhook/handler.py +++ b/matrix_webhook/handler.py @@ -76,6 +76,11 @@ async def matrix_webhook(request): else: formatted_body = markdown(str(data["body"]), extensions=["extra"]) + # try to join room first -> non none response means error + resp = await utils.join_room(data["room_id"]) + if resp is not None: + return resp + content = { "msgtype": "m.text", "body": data["body"], diff --git a/matrix_webhook/utils.py b/matrix_webhook/utils.py index 2b4d74d..339472b 100644 --- a/matrix_webhook/utils.py +++ b/matrix_webhook/utils.py @@ -6,7 +6,7 @@ from http import HTTPStatus from aiohttp import web from nio import AsyncClient from nio.exceptions import LocalProtocolError -from nio.responses import RoomSendError +from nio.responses import RoomSendError, JoinError from . import conf @@ -22,6 +22,29 @@ def create_json_response(status, ret): return web.json_response(response_data, status=status) +async def join_room(room_id): + """Try to join the room.""" + LOGGER.debug(f"Join room {room_id=}") + + for _ in range(10): + try: + resp = await CLIENT.join(room_id) + if isinstance(resp, JoinError): + if resp.status_code == "M_UNKNOWN_TOKEN": + LOGGER.warning("Reconnecting") + await CLIENT.login(conf.MATRIX_PW) + else: + return create_json_response( + ERROR_MAP[resp.status_code], resp.message + ) + else: + return None + except LocalProtocolError as e: + LOGGER.error(f"Send error: {e}") + LOGGER.warning("Trying again") + return create_json_response(HTTPStatus.GATEWAY_TIMEOUT, "Homeserver not responding") + + async def send_room_message(room_id, content): """Send a message to a room.""" LOGGER.debug(f"Sending room message in {room_id=}: {content=}") From d2a3e618f489baf83be78a4e3fe52b3a97b6819c Mon Sep 17 00:00:00 2001 From: Guilhem Saurel Date: Tue, 28 Sep 2021 10:39:41 +0200 Subject: [PATCH 2/2] join room: fix error code & unit tests --- matrix_webhook/utils.py | 15 +++++++++------ tests/tests.py | 4 ++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/matrix_webhook/utils.py b/matrix_webhook/utils.py index 339472b..4c7917a 100644 --- a/matrix_webhook/utils.py +++ b/matrix_webhook/utils.py @@ -15,6 +15,13 @@ LOGGER = logging.getLogger("matrix_webhook.utils") CLIENT = AsyncClient(conf.MATRIX_URL, conf.MATRIX_ID) +def error_map(resp): + """Map response errors to HTTP status.""" + if resp.status_code == "M_UNKNOWN": + return resp.transport_response.status + return ERROR_MAP[resp.status_code] + + def create_json_response(status, ret): """Create a JSON response.""" LOGGER.debug(f"Creating json response: {status=}, {ret=}") @@ -34,9 +41,7 @@ async def join_room(room_id): LOGGER.warning("Reconnecting") await CLIENT.login(conf.MATRIX_PW) else: - return create_json_response( - ERROR_MAP[resp.status_code], resp.message - ) + return create_json_response(error_map(resp), resp.message) else: return None except LocalProtocolError as e: @@ -59,9 +64,7 @@ async def send_room_message(room_id, content): LOGGER.warning("Reconnecting") await CLIENT.login(conf.MATRIX_PW) else: - return create_json_response( - ERROR_MAP[resp.status_code], resp.message - ) + return create_json_response(error_map(resp), resp.message) else: return create_json_response(HTTPStatus.OK, "OK") except LocalProtocolError as e: diff --git a/tests/tests.py b/tests/tests.py index aa5991c..7d44d7e 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -33,11 +33,11 @@ class BotTest(unittest.IsolatedAsyncioTestCase): # this won't be a 403 from synapse, but a LocalProtocolError from matrix_webhook self.assertEqual( bot_req({"body": 3}, KEY, "wrong_room"), - {"status": 403, "ret": "Unknown room"}, + {"status": 400, "ret": "wrong_room was not legal room ID or room alias"}, ) self.assertEqual( bot_req({"body": 3}, KEY, "wrong_room", key_as_param=True), - {"status": 403, "ret": "Unknown room"}, + {"status": 400, "ret": "wrong_room was not legal room ID or room alias"}, ) async def test_message(self):