feat: define type, prep for company announcements

This commit is contained in:
2025-12-23 12:57:20 -08:00
parent e462c9472d
commit 5b99450b7c
7 changed files with 66 additions and 25 deletions
+10
View File
@@ -0,0 +1,10 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
/**
* This really only exists so we can do a type guard.
*/
export type AnnouncementType = "products" | "community" | "company";
+15 -6
View File
@@ -5,14 +5,23 @@
*/ */
/* eslint-disable @typescript-eslint/naming-convention -- we are making raw API calls. */ /* eslint-disable @typescript-eslint/naming-convention -- we are making raw API calls. */
const channelIds = { import type { AnnouncementType } from "../interfaces/announcementType.js";
const channelIds: Record<AnnouncementType, string> = {
community: "1386105484313886820", community: "1386105484313886820",
company: "1422472775695728661",
products: "1386105452881776661", products: "1386105452881776661",
} as const; };
const roleIds = { const roleIds: Record<AnnouncementType, string> = {
community: "1386107941224054895", community: "1386107941224054895",
products: "1386107909699666121",
} as const; /**
* Note that this is not a role ID, but the server ID.
* Company announcements ping everyone.
*/
company: "1354624415861833870",
products: "1386107909699666121",
};
/** /**
* Forwards an announcement to our Discord server. * Forwards an announcement to our Discord server.
@@ -24,7 +33,7 @@ const roleIds = {
export const announceOnDiscord = async( export const announceOnDiscord = async(
title: string, title: string,
content: string, content: string,
type: "products" | "community", type: AnnouncementType,
): Promise<string> => { ): Promise<string> => {
const messageRequest = await fetch( const messageRequest = await fetch(
`https://discord.com/api/v10/channels/${channelIds[type]}/messages`, `https://discord.com/api/v10/channels/${channelIds[type]}/messages`,
+5 -2
View File
@@ -6,8 +6,11 @@
/* eslint-disable @typescript-eslint/naming-convention -- we are making raw API calls. */ /* eslint-disable @typescript-eslint/naming-convention -- we are making raw API calls. */
/* eslint-disable max-lines-per-function -- Big logic here. */ /* eslint-disable max-lines-per-function -- Big logic here. */
const flairIds = { import type { AnnouncementType } from "../interfaces/announcementType.js";
const flairIds: Record<AnnouncementType, string> = {
community: "7a01a5a6-0f29-11ef-a0c4-c6fb085f7c8f", community: "7a01a5a6-0f29-11ef-a0c4-c6fb085f7c8f",
company: "dd8057c0-9e30-11f0-b321-d683551dcb2b",
products: "335e57b6-083f-11ef-96b3-0202af2d9d99", products: "335e57b6-083f-11ef-96b3-0202af2d9d99",
}; };
@@ -21,7 +24,7 @@ const flairIds = {
export const announceOnReddit = async( export const announceOnReddit = async(
title: string, title: string,
content: string, content: string,
type: "products" | "community", type: AnnouncementType,
): Promise<string> => { ): Promise<string> => {
if ( if (
process.env.REDDIT_CLIENT_ID === undefined process.env.REDDIT_CLIENT_ID === undefined
+3 -2
View File
@@ -12,6 +12,7 @@ import { announceOnReddit } from "../modules/announceOnReddit.js";
import { announceOnTwitter } from "../modules/announceOnTwitter.js"; import { announceOnTwitter } from "../modules/announceOnTwitter.js";
import { getIpFromRequest } from "../modules/getIpFromRequest.js"; import { getIpFromRequest } from "../modules/getIpFromRequest.js";
import { summarisePost } from "../modules/summarisePost.js"; import { summarisePost } from "../modules/summarisePost.js";
import { isAnnouncementType } from "../utils/typeguards.js";
import type { FastifyPluginAsync } from "fastify"; import type { FastifyPluginAsync } from "fastify";
const oneDay = 24 * 60 * 60 * 1000; const oneDay = 24 * 60 * 60 * 1000;
@@ -73,10 +74,10 @@ export const announcementRoutes: FastifyPluginAsync = async(server) => {
}); });
} }
if (type !== "products" && type !== "community") { if (!isAnnouncementType(type)) {
return await reply.status(400).send({ return await reply.status(400).send({
error: error:
"Invalid announcement type. Available types: products, community.", `Invalid announcement type. Available types: products, community, company.`,
}); });
} }
+1 -1
View File
@@ -8,7 +8,7 @@ import { blockedIps } from "../cache/blockedIps.js";
import { database } from "../db/database.js"; import { database } from "../db/database.js";
import { getIpFromRequest } from "../modules/getIpFromRequest.js"; import { getIpFromRequest } from "../modules/getIpFromRequest.js";
import { getSanctionComponents } from "../modules/getSanctionComponents.js"; import { getSanctionComponents } from "../modules/getSanctionComponents.js";
import { isValidString } from "../utils/isValidString.js"; import { isValidString } from "../utils/typeguards.js";
import type { FastifyPluginAsync } from "fastify"; import type { FastifyPluginAsync } from "fastify";
const oneDay = 24 * 60 * 60 * 1000; const oneDay = 24 * 60 * 60 * 1000;
-14
View File
@@ -1,14 +0,0 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
/**
* Checks that a nullable value is a string and has length.
* @param maybeString -- The nullable value to check.
* @returns True if it is a string.
*/
export const isValidString = (maybeString: unknown): maybeString is string => {
return typeof maybeString === "string" && maybeString.length > 0;
};
+32
View File
@@ -0,0 +1,32 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import type { AnnouncementType } from "../interfaces/announcementType.js";
/**
* Checks if a string is a valid announcement type.
* @param maybeType - The string to check.
* @returns True if it is a valid announcement type.
*/
const isAnnouncementType
= (maybeType: string): maybeType is AnnouncementType => {
return [
"products",
"community",
"announcement",
].includes(maybeType);
};
/**
* Checks that a nullable value is a string and has length.
* @param maybeString -- The nullable value to check.
* @returns True if it is a string.
*/
const isValidString = (maybeString: unknown): maybeString is string => {
return typeof maybeString === "string" && maybeString.length > 0;
};
export { isAnnouncementType, isValidString };