/** * @copyright nhcarrigan * @license Naomi's Public License * @author Naomi Carrigan */ /* eslint-disable @typescript-eslint/naming-convention -- we are making raw API calls. */ /* eslint-disable no-await-in-loop -- Sequential chunk posting requires awaiting each request. */ /* eslint-disable max-lines-per-function -- Chunked posting requires more logic. */ import { chunkContent } from "../utils/chunkContent.js"; import type { AnnouncementType } from "../interfaces/announcementType.js"; const announcementCategoryId = 16; const discourseLimit = 32_000; const tags: Record = { community: "Community", company: "Company", products: "Products", }; /** * Posts an announcement to the NHCarrigan Discourse support forum. * Sends overflow content as sequential replies if it exceeds the 32,000 character limit. * @param title - The title of the announcement. * @param content - The main body of the announcement in markdown. * @param type - Whether the announcement is for a product, community, or company. * @returns A message indicating the success or failure of the operation. */ export const announceOnDiscourse = async( title: string, content: string, type: AnnouncementType, ): Promise => { if (process.env.FORUM_API_KEY === undefined) { return "Discourse API key is not set."; } const chunks = chunkContent(content, discourseLimit); const firstChunk = chunks[0] ?? ""; const remainingChunks = chunks.slice(1); const response = await fetch("https://support.nhcarrigan.com/posts.json", { body: JSON.stringify({ category: announcementCategoryId, raw: firstChunk, tags: [ tags[type] ], title: title, }), headers: { "Api-Key": process.env.FORUM_API_KEY, "Api-Username": "hikari", "Content-Type": "application/json", }, method: "POST", }); if (!response.ok) { return `Failed to post to Discourse. Status: ${response.status.toString()} ${response.statusText}`; } // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Fetch does not accept generic. const data = (await response.json()) as { topic_id?: number }; for (const chunk of remainingChunks) { if (data.topic_id === undefined) { return "Failed to retrieve Discourse topic ID for continuation posts."; } const replyResponse = await fetch( "https://support.nhcarrigan.com/posts.json", { body: JSON.stringify({ raw: chunk, topic_id: data.topic_id, }), headers: { "Api-Key": process.env.FORUM_API_KEY, "Api-Username": "hikari", "Content-Type": "application/json", }, method: "POST", }, ); if (!replyResponse.ok) { return `Failed to post continuation chunk to Discourse. Status: ${replyResponse.status.toString()} ${replyResponse.statusText}`; } } return "Successfully posted announcement to Discourse~! ✨"; };