@@ -20,7 +20,7 @@ index 46c91bb..b8d6005 100644
2020 await utils.CLIENT.close()
2121
2222diff --git a/matrix_webhook/formatters.py b/matrix_webhook/formatters.py
23- index 63040bf..e61f387 100644
23+ index 63040bf..17606f3 100644
2424--- a/matrix_webhook/formatters.py
2525+++ b/matrix_webhook/formatters.py
2626@@ -1,6 +1,7 @@
@@ -64,8 +64,82 @@ index 63040bf..e61f387 100644
6464+ data["body"] = text
6565+ return data
6666+
67+ diff --git a/matrix_webhook/handler.py b/matrix_webhook/handler.py
68+ index ed40449..405ea89 100644
69+ --- a/matrix_webhook/handler.py
70+ +++ b/matrix_webhook/handler.py
71+ @@ -25,11 +25,11 @@ async def matrix_webhook(request):
72+ return utils.create_json_response(HTTPStatus.OK, "OK")
73+
74+ data_b = await request.read()
75+ -
76+ + formatter = request.rel_url.query.get('formatter', None)
77+ try:
78+ data = json.loads(data_b.decode())
79+ except json.decoder.JSONDecodeError:
80+ - return utils.create_json_response(HTTPStatus.BAD_REQUEST, "Invalid JSON")
81+ + return utils.create_json_response(status=HTTPStatus.BAD_REQUEST, ret="Invalid JSON", formatter=formatter)
82+
83+ # legacy naming
84+ if "text" in data and "body" not in data:
85+ @@ -47,8 +47,9 @@ async def matrix_webhook(request):
86+ )
87+ except AttributeError:
88+ return utils.create_json_response(
89+ - HTTPStatus.BAD_REQUEST,
90+ - "Unknown formatter",
91+ + status=HTTPStatus.BAD_REQUEST,
92+ + ret="Unknown formatter",
93+ + formatter=formatter,
94+ )
95+
96+ if "room_id" in request.rel_url.query and "room_id" not in data:
97+ @@ -63,8 +64,9 @@ async def matrix_webhook(request):
98+ data["key"] = conf.API_KEY
99+ else: # but if there is a wrong digest, an informative error should be provided
100+ return utils.create_json_response(
101+ - HTTPStatus.UNAUTHORIZED,
102+ - "Invalid SHA-256 HMAC digest",
103+ + status=HTTPStatus.UNAUTHORIZED,
104+ + ret="Invalid SHA-256 HMAC digest",
105+ + formatter=formatter,
106+ )
107+
108+ missing = []
109+ @@ -73,12 +75,13 @@ async def matrix_webhook(request):
110+ missing.append(key)
111+ if missing:
112+ return utils.create_json_response(
113+ - HTTPStatus.BAD_REQUEST,
114+ - f"Missing {', '.join(missing)}",
115+ + status=HTTPStatus.BAD_REQUEST,
116+ + ret=f"Missing {', '.join(missing)}",
117+ + formatter=formatter,
118+ )
119+
120+ if data["key"] != conf.API_KEY:
121+ - return utils.create_json_response(HTTPStatus.UNAUTHORIZED, "Invalid API key")
122+ + return utils.create_json_response(status=HTTPStatus.UNAUTHORIZED, ret="Invalid API key",formatter=formatter)
123+
124+ if "formatted_body" in data:
125+ formatted_body = data["formatted_body"]
126+ @@ -86,7 +89,7 @@ async def matrix_webhook(request):
127+ formatted_body = markdown(str(data["body"]), extensions=["extra"])
128+
129+ # try to join room first -> non none response means error
130+ - resp = await utils.join_room(data["room_id"])
131+ + resp = await utils.join_room(room_id=data["room_id"], formatter=formatter)
132+ if resp is not None:
133+ return resp
134+
135+ @@ -96,4 +99,4 @@ async def matrix_webhook(request):
136+ "format": "org.matrix.custom.html",
137+ "formatted_body": formatted_body,
138+ }
139+ - return await utils.send_room_message(data["room_id"], content)
140+ + return await utils.send_room_message(room_id=data["room_id"], content=content, formatter=formatter)
67141diff --git a/matrix_webhook/utils.py b/matrix_webhook/utils.py
68- index 72172a7..940c7c1 100644
142+ index 7b70e11..db2712c 100644
69143--- a/matrix_webhook/utils.py
70144+++ b/matrix_webhook/utils.py
71145@@ -5,11 +5,13 @@ from collections import defaultdict
@@ -85,18 +159,53 @@ index 72172a7..940c7c1 100644
85159 lambda: HTTPStatus.INTERNAL_SERVER_ERROR,
86160@@ -21,6 +23,9 @@ ERROR_MAP = defaultdict(
87161 LOGGER = logging.getLogger("matrix_webhook.utils")
88- CLIENT = AsyncClient(conf.MATRIX_URL, conf.MATRIX_ID)
162+ CLIENT = AsyncClient(conf.MATRIX_URL, conf.MATRIX_ID, proxy=conf.PROXY )
89163
90164+ def format_url(data):
91165+ data = sub(r"(<(https?://[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+)\|([\w\s]+)>)", r'<a href="\2">\3</a>', data)
92166+ return sub(r"(<)(https?://[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+)(>)", r'<a href="\2">\2</a>', data)
93167
94168 def error_map(resp):
95169 """Map response errors to HTTP status."""
96- @@ -66,6 +71,16 @@ async def join_room(room_id):
97- return create_json_response(HTTPStatus.GATEWAY_TIMEOUT, "Homeserver not responding")
98-
99-
170+ @@ -31,15 +36,17 @@ def error_map(resp):
171+ return ERROR_MAP[resp.status_code]
172+
173+
174+ - def create_json_response(status, ret):
175+ + def create_json_response(status, ret, formatter: str = None):
176+ """Create a JSON response."""
177+ msg = f"Creating json response: {status=}, {ret=}"
178+ - LOGGER.debug(msg)
179+ - response_data = {"status": status, "ret": ret}
180+ + if formatter == "slack":
181+ + response_data = {"ok": 200 <= status.value < 300, "error": ret}
182+ + else:
183+ + response_data = {"status": status, "ret": ret}
184+ return web.json_response(response_data, status=status)
185+
186+
187+ - async def join_room(room_id):
188+ + async def join_room(room_id,formatter: str = None):
189+ """Try to join the room."""
190+ msg = f"Join room {room_id=}"
191+ LOGGER.debug(msg)
192+ @@ -53,7 +60,7 @@ async def join_room(room_id):
193+ if conf.MATRIX_PW:
194+ await CLIENT.login(conf.MATRIX_PW)
195+ else:
196+ - return create_json_response(error_map(resp), resp.message)
197+ + return create_json_response(status=error_map(resp), ret=resp.message, formatter=formatter)
198+ else:
199+ return None
200+ except LocalProtocolError as e:
201+ @@ -63,10 +70,20 @@ async def join_room(room_id):
202+ if conf.MATRIX_PW:
203+ await CLIENT.login(conf.MATRIX_PW)
204+ LOGGER.warning("Trying again")
205+ - return create_json_response(HTTPStatus.GATEWAY_TIMEOUT, "Homeserver not responding")
206+ + return create_json_response(status=HTTPStatus.GATEWAY_TIMEOUT, ret="Homeserver not responding", formatter=formatter)
207+ +
208+ +
100209+ async def accept_invitation(room: MatrixRoom, event: InviteEvent):
101210+ LOGGER.info(f"Got invite to room {room.room_id=}")
102211+ await CLIENT.join(room.room_id)
@@ -105,8 +214,28 @@ index 72172a7..940c7c1 100644
105214+ def watch_for_invitation():
106215+ CLIENT.add_event_callback(accept_invitation, InviteEvent)
107216+ return create_task(CLIENT.sync_forever())
108- +
109- +
110- async def send_room_message(room_id, content):
217+
218+
219+ - async def send_room_message(room_id, content):
220+ + async def send_room_message(room_id, content, formatter: str = None):
111221 """Send a message to a room."""
112222 msg = f"Sending room message in {room_id=}: {content=}"
223+ LOGGER.debug(msg)
224+ @@ -84,9 +101,9 @@ async def send_room_message(room_id, content):
225+ if conf.MATRIX_PW:
226+ await CLIENT.login(conf.MATRIX_PW)
227+ else:
228+ - return create_json_response(error_map(resp), resp.message)
229+ + return create_json_response(status=error_map(resp), ret=resp.message,formatter=formatter)
230+ else:
231+ - return create_json_response(HTTPStatus.OK, "OK")
232+ + return create_json_response(status=HTTPStatus.OK, ret="OK", formatter=formatter)
233+ except LocalProtocolError as e:
234+ msg = f"Send error: {e}"
235+ LOGGER.error(msg)
236+ @@ -94,4 +111,4 @@ async def send_room_message(room_id, content):
237+ if conf.MATRIX_PW:
238+ await CLIENT.login(conf.MATRIX_PW)
239+ LOGGER.warning("Trying again")
240+ - return create_json_response(HTTPStatus.GATEWAY_TIMEOUT, "Homeserver not responding")
241+ + return create_json_response(status=HTTPStatus.GATEWAY_TIMEOUT, ret="Homeserver not responding", formatter=formatter)
0 commit comments