import logging from typing import List from aiohttp import web, web_request from nio import AsyncClient, SendRetryError from matrix_alertbot.cache import Cache from matrix_alertbot.chat_functions import send_text_to_room from matrix_alertbot.config import Config from matrix_alertbot.storage import Alert logger = logging.getLogger(__name__) routes = web.RouteTableDef() @routes.post("/alert") async def create_alert(request: web_request.Request) -> web.Response: data = await request.json() logger.info(f"Received alert: {data}") client = request.app["client"] cache = request.app["cache"] plaintext = "" html = "" for i, alert in enumerate(data["alerts"]): alert = Alert.from_dict(alert) if i != 0: plaintext += "\n" html += "
\n" plaintext += alert.plaintext() html += alert.html() try: event = await send_text_to_room( client, request.app["room_id"], plaintext, html, notice=False ) except SendRetryError as e: logger.error(e) return web.Response(status=500) cache[event.event_id] = tuple(alert["fingerprint"] for alert in data["alerts"]) return web.Response(status=200) class Webhook: def __init__(self, client: AsyncClient, cache: Cache, config: Config) -> None: self.app = web.Application(logger=logger) self.app["client"] = client self.app["room_id"] = config.room self.app["cache"] = cache self.app.add_routes(routes) self.runner = web.AppRunner(self.app) self.config = config self.address = config.address self.port = config.port self.socket = config.socket async def start(self) -> None: await self.runner.setup() site: web.BaseSite if self.address and self.port: site = web.TCPSite(self.runner, self.address, self.port) logger.info(f"Listenning on {self.address}:{self.port}") elif self.socket: site = web.UnixSite(self.runner, self.socket) logger.info(f"Listenning on unix://{self.socket}") await site.start() async def close(self) -> None: await self.runner.cleanup()