/** * @copyright nhcarrigan * @license Naomi's Public License * @author Naomi Carrigan */ import fastify from "fastify"; import { MsgType, type MatrixClient } from "matrix-js-sdk"; import { errorSchema } from "../schemas/errorSchema.js"; import { logSchema } from "../schemas/logSchema.js"; import { uptimeSchema } from "../schemas/uptimeSchema.js"; import type { Error } from "../interfaces/error.js"; import type { Log } from "../interfaces/log.js"; import type { Uptime } from "../interfaces/uptime.js"; const html = ` Alert Server

Alert Server

AI-powered multi-purpose assistant for Discord!

Links

Source Code

Documentation

Support

`; /** * Starts up the server to receive events. * @param client - The authenticated Matrix client. */ // eslint-disable-next-line max-lines-per-function -- This function is long because it is setting up a server. export const instantiateServer = (client: MatrixClient): void => { try { const server = fastify({ logger: false, }); server.get("/", (_request, response) => { response.header("Content-Type", "text/html"); response.send(html); }); // eslint-disable-next-line @typescript-eslint/naming-convention -- Body must be capitalised for Fastify. server.post<{ Body: Log }>("/log", logSchema, async(request, response) => { const { application, level, message } = request.body; await client.sendMessage(process.env.MATRIX_ROOM_ID ?? "", { body: `**${application}** - *${level}*\n${message}`, format: "org.matrix.custom.html", // eslint-disable-next-line @typescript-eslint/naming-convention -- Requirement of the SDK. formatted_body: `${application} - ${level}
${message}`, msgtype: MsgType.Text, }); await response.status(200).send({ success: true }); }); // eslint-disable-next-line @typescript-eslint/naming-convention -- Body must be capitalised for Fastify. server.post<{ Body: Error }>( "/error", errorSchema, async(request, response) => { const { application, context, stack, message } = request.body; await client.sendMessage(process.env.MATRIX_ROOM_ID ?? "", { body: `**${application}** - *Error in ${context}*\n${message}\n\`\`\`\n${stack}\n\`\`\``, format: "org.matrix.custom.html", // eslint-disable-next-line @typescript-eslint/naming-convention -- Requirement of the SDK. formatted_body: `${application} - Error in ${context}
${message}
${stack}`, msgtype: MsgType.Text, }); await response.status(200).send({ success: true }); }, ); // eslint-disable-next-line @typescript-eslint/naming-convention -- Body must be capitalised for Fastify. server.post<{ Body: Uptime }>( "/uptime", uptimeSchema, async(request, response) => { const { application, message } = request.body; await client.sendMessage(process.env.MATRIX_ROOM_ID ?? "", { body: `${message}\n${application}`, format: "org.matrix.custom.html", // eslint-disable-next-line @typescript-eslint/naming-convention -- Requirement of the SDK. formatted_body: `${message}
${application}`, msgtype: MsgType.Text, }); await response.status(200).send({ success: true }); }, ); server.listen({ port: 5003 }, (error) => { const application = "Alert Server"; if (error) { const { message, stack } = error; const context = "Server Startup"; void client.sendMessage(process.env.MATRIX_ROOM_ID ?? "", { body: `**${application}** - *Error in ${context}*\n${message}\n\`\`\`\n${stack ?? "No stack trace available."}\n\`\`\``, format: "org.matrix.custom.html", // eslint-disable-next-line @typescript-eslint/naming-convention -- Requirement of the SDK. formatted_body: `${application} - Error in ${context}
${message}
${stack ?? "No stack trace available."}`, msgtype: MsgType.Text, }); return; } const level = "debug"; const message = `Server listening on port 5003.`; void client.sendMessage(process.env.MATRIX_ROOM_ID ?? "", { body: `**${application}** - *${level}*\n${message}`, format: "org.matrix.custom.html", // eslint-disable-next-line @typescript-eslint/naming-convention -- Requirement of the SDK. formatted_body: `${application} - ${level}
${message}`, msgtype: MsgType.Text, }); }); } catch (error) { const application = "Alert Server"; const context = "Server Startup"; // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Totally being lazy. const { message, stack } = error as Error; void client.sendMessage(process.env.MATRIX_ROOM_ID ?? "", { body: `**${application}** - *Error in ${context}*\n${message}\n\`\`\`\n${stack}\n\`\`\``, format: "org.matrix.custom.html", // eslint-disable-next-line @typescript-eslint/naming-convention -- Requirement of the SDK. formatted_body: `${application} - Error in ${context}
${message}
${stack}`, msgtype: MsgType.Text, }); } };