generated from nhcarrigan/template
feat: announce on Discourse support forum (#17)
## Summary - Adds `announceOnDiscourse` module to post announcements to the NHCarrigan Discourse support forum (category 16), tagged by announcement type - Adds `chunkContent` utility to split long announcements at paragraph/line boundaries for Discord (2000 chars), Reddit (40,000 chars), and Discourse (32,000 chars); Reddit overflows chain as nested replies, Discord as sequential messages, Discourse as sequential replies - Refactors the announcement route to run all platforms concurrently via `Promise.allSettled`, ensuring a failure on any one platform never blocks the others, with all results reported back - Fixes generation failure response from incorrect `201` to `500` ✨ This PR was created with love from Hikari~ 🌸 Reviewed-on: #17 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com>
This commit was merged in pull request #17.
This commit is contained in:
@@ -8,6 +8,7 @@ import { blockedIps } from "../cache/blockedIps.js";
|
||||
import { database } from "../db/database.js";
|
||||
import { announceOnBluesky } from "../modules/announceOnBluesky.js";
|
||||
import { announceOnDiscord } from "../modules/announceOnDiscord.js";
|
||||
import { announceOnDiscourse } from "../modules/announceOnDiscourse.js";
|
||||
import { announceOnFacebook } from "../modules/announceOnFacebook.js";
|
||||
import { announceOnMastodon } from "../modules/announceOnMastodon.js";
|
||||
import { announceOnReddit } from "../modules/announceOnReddit.js";
|
||||
@@ -20,6 +21,12 @@ import type { FastifyPluginAsync } from "fastify";
|
||||
|
||||
const oneDay = 24 * 60 * 60 * 1000;
|
||||
|
||||
const getPlatformResult = (result: PromiseSettledResult<string>): string => {
|
||||
return result.status === "fulfilled"
|
||||
? result.value
|
||||
: `Unexpected error: ${String(result.reason)}`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mounts the entry routes for the application. These routes
|
||||
* should not require CORS, as they are used by external services
|
||||
@@ -53,7 +60,6 @@ export const announcementRoutes: FastifyPluginAsync = async(server) => {
|
||||
server.post<{ Body: { content: string; type: string } }>(
|
||||
"/announcement",
|
||||
|
||||
// eslint-disable-next-line max-statements -- This is a long function.
|
||||
async(request, reply) => {
|
||||
const token = request.headers.authorization;
|
||||
if (token === undefined || token !== process.env.ANNOUNCEMENT_TOKEN) {
|
||||
@@ -84,8 +90,8 @@ export const announcementRoutes: FastifyPluginAsync = async(server) => {
|
||||
const announcement = await generateAnnouncements(content);
|
||||
|
||||
if (announcement === null) {
|
||||
return await reply.status(201).send({
|
||||
message: `Failed to generate announcements.`,
|
||||
return await reply.status(500).send({
|
||||
error: `Failed to generate announcements.`,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -104,25 +110,30 @@ export const announcementRoutes: FastifyPluginAsync = async(server) => {
|
||||
},
|
||||
});
|
||||
|
||||
const discordPost = await announceOnDiscord(
|
||||
markdownTitle,
|
||||
markdownContent,
|
||||
type,
|
||||
);
|
||||
const redditPost = await announceOnReddit(
|
||||
markdownTitle,
|
||||
markdownContent,
|
||||
type,
|
||||
);
|
||||
const blueskyPost = await announceOnBluesky(threaded);
|
||||
const twitterPost = await announceOnTwitter(threaded);
|
||||
const facebookPost = await announceOnFacebook(plaintext);
|
||||
const threadsPost = await announceOnThreads(threaded);
|
||||
const mastodonPost = await announceOnMastodon(threaded);
|
||||
const [
|
||||
discordResult,
|
||||
redditResult,
|
||||
blueskyResult,
|
||||
twitterResult,
|
||||
facebookResult,
|
||||
threadsResult,
|
||||
mastodonResult,
|
||||
discourseResult,
|
||||
] = await Promise.allSettled([
|
||||
announceOnDiscord(markdownTitle, markdownContent, type),
|
||||
announceOnReddit(markdownTitle, markdownContent, type),
|
||||
announceOnBluesky(threaded),
|
||||
announceOnTwitter(threaded),
|
||||
announceOnFacebook(plaintext),
|
||||
announceOnThreads(threaded),
|
||||
announceOnMastodon(threaded),
|
||||
announceOnDiscourse(markdownTitle, markdownContent, type),
|
||||
]);
|
||||
|
||||
return await reply.status(201).send({
|
||||
alert: `Please remember to manually post to: LinkedIn, Peerlist, Ko-fi, and Patreon.`,
|
||||
cost: announcement.cost,
|
||||
message: `Announcement processed. Discord: ${discordPost}, Reddit: ${redditPost}, Bluesky: ${blueskyPost}, Twitter: ${twitterPost}, Facebook: ${facebookPost}, Threads: ${threadsPost}, Mastodon: ${mastodonPost}`,
|
||||
message: `Announcement processed. Discord: ${getPlatformResult(discordResult)}, Reddit: ${getPlatformResult(redditResult)}, Bluesky: ${getPlatformResult(blueskyResult)}, Twitter: ${getPlatformResult(twitterResult)}, Facebook: ${getPlatformResult(facebookResult)}, Threads: ${getPlatformResult(threadsResult)}, Mastodon: ${getPlatformResult(mastodonResult)}, Discourse: ${getPlatformResult(discourseResult)}`,
|
||||
rawPost: announcement.response,
|
||||
});
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user