From 0ccec84eef55103ae614229884b9a0e3efc9574f Mon Sep 17 00:00:00 2001 From: Guilhem Saurel Date: Sat, 31 Jul 2021 15:16:07 +0200 Subject: [PATCH] room_id can come from url, content, or parameters --- CHANGELOG.md | 1 + matrix_webhook/__main__.py | 16 ++++++++--- tests/start.py | 13 +++++++-- tests/tests.py | 58 ++++++++++++++++++++++++++++++++++---- 4 files changed, 77 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7778fc..2ec7b0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - add formatted_body to bypass markdown with direct [matrix-custom-HTML](https://matrix.org/docs/spec/client_server/r0.6.1#m-room-message-msgtypes) - allow "key" to be passed as a parameter +- allow "room_id" to be passed as a parameter or with the data - rename "text" to "body". ## [3.1.0] - 2021-07-18 diff --git a/matrix_webhook/__main__.py b/matrix_webhook/__main__.py index c1ac638..4416ccb 100644 --- a/matrix_webhook/__main__.py +++ b/matrix_webhook/__main__.py @@ -52,9 +52,18 @@ async def handler(request): except AttributeError: return create_json_response(HTTPStatus.BAD_REQUEST, "Unknown formatter") - if not all(key in data for key in ["body", "key"]): + if "room_id" in request.rel_url.query and "room_id" not in data: + data["room_id"] = request.rel_url.query["room_id"] + if "room_id" not in data: + data["room_id"] = request.path.lstrip("/") + + missing = [] + for key in ["body", "key", "room_id"]: + if key not in data or not data[key]: + missing.append(key) + if missing: return create_json_response( - HTTPStatus.BAD_REQUEST, "Missing body and/or API key property" + HTTPStatus.BAD_REQUEST, f"Missing {', '.join(missing)}" ) if data["key"] != conf.API_KEY: @@ -65,7 +74,6 @@ async def handler(request): else: formatted_body = markdown(str(data["body"]), extensions=["extra"]) - room_id = request.path[1:] content = { "msgtype": "m.text", "body": data["body"], @@ -74,7 +82,7 @@ async def handler(request): } for _ in range(10): try: - resp = await send_room_message(room_id, content) + resp = await send_room_message(data["room_id"], content) if isinstance(resp, RoomSendError): if resp.status_code == "M_UNKNOWN_TOKEN": LOGGER.warning("Reconnecting") diff --git a/tests/start.py b/tests/start.py index ea76b56..c4160bd 100755 --- a/tests/start.py +++ b/tests/start.py @@ -25,7 +25,14 @@ parser.add_argument( ) -def bot_req(req=None, key=None, room_id=None, params=None, key_as_param=False): +def bot_req( + req=None, + key=None, + room_id=None, + params=None, + key_as_param=False, + room_as_parameter=False, +): """Bot requests boilerplate.""" if params is None: params = {} @@ -34,7 +41,9 @@ def bot_req(req=None, key=None, room_id=None, params=None, key_as_param=False): params["key"] = key else: req["key"] = key - url = BOT_URL if room_id is None else f"{BOT_URL}/{room_id}" + if room_as_parameter: + params["room_id"] = room_id + url = BOT_URL if room_id is None or room_as_parameter else f"{BOT_URL}/{room_id}" return httpx.post(url, params=params, json=req).json() diff --git a/tests/tests.py b/tests/tests.py index 1b17f9e..a997aea 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -15,13 +15,14 @@ class BotTest(unittest.IsolatedAsyncioTestCase): self.assertEqual(bot_req(), {"status": 400, "ret": "Invalid JSON"}) self.assertEqual( bot_req({"toto": 3}), - {"status": 400, "ret": "Missing body and/or API key property"}, + {"status": 400, "ret": "Missing body, key, room_id"}, ) self.assertEqual( - bot_req({"body": 3}, "wrong_key"), {"status": 401, "ret": "Invalid API key"} + bot_req({"body": 3}, "wrong_key", "wrong_room"), + {"status": 401, "ret": "Invalid API key"}, ) self.assertEqual( - bot_req({"body": 3}, "wrong_key", key_as_param=True), + bot_req({"body": 3}, "wrong_key", "wrong_room", key_as_param=True), {"status": 401, "ret": "Invalid API key"}, ) self.assertEqual( @@ -31,10 +32,11 @@ class BotTest(unittest.IsolatedAsyncioTestCase): # TODO: if the client from matrix_webhook has olm support, this won't be a 403 from synapse, # but a LocalProtocolError from matrix_webhook self.assertEqual( - bot_req({"body": 3}, KEY), {"status": 403, "ret": "Unknown room"} + bot_req({"body": 3}, KEY, "wrong_room"), + {"status": 403, "ret": "Unknown room"}, ) self.assertEqual( - bot_req({"body": 3}, KEY, key_as_param=True), + bot_req({"body": 3}, KEY, "wrong_room", key_as_param=True), {"status": 403, "ret": "Unknown room"}, ) @@ -60,6 +62,52 @@ class BotTest(unittest.IsolatedAsyncioTestCase): self.assertEqual(message.body, text) self.assertEqual(message.formatted_body, "

Hello

") + async def test_room_id_req(self): + """Send a markdown message in a room given as data, and check the result.""" + body = "# Hello" + messages = [] + client = nio.AsyncClient(MATRIX_URL, MATRIX_ID) + + await client.login(MATRIX_PW) + room = await client.room_create() + + self.assertEqual( + bot_req({"body": body, "room_id": room.room_id}, KEY, room.room_id), + {"status": 200, "ret": "OK"}, + ) + + sync = await client.sync() + messages = await client.room_messages(room.room_id, sync.next_batch) + await client.close() + + message = messages.chunk[0] + self.assertEqual(message.sender, FULL_ID) + self.assertEqual(message.body, body) + self.assertEqual(message.formatted_body, "

Hello

") + + async def test_room_id_parameter(self): + """Send a markdown message in a room given as parameter, and check the result.""" + body = "# Hello" + messages = [] + client = nio.AsyncClient(MATRIX_URL, MATRIX_ID) + + await client.login(MATRIX_PW) + room = await client.room_create() + + self.assertEqual( + bot_req({"body": body}, KEY, room.room_id, room_as_parameter=True), + {"status": 200, "ret": "OK"}, + ) + + sync = await client.sync() + messages = await client.room_messages(room.room_id, sync.next_batch) + await client.close() + + message = messages.chunk[0] + self.assertEqual(message.sender, FULL_ID) + self.assertEqual(message.body, body) + self.assertEqual(message.formatted_body, "

Hello

") + async def test_markdown_body(self): """Send a markdown message, and check the result.""" body = "# Hello"