diff --git a/server/src/interfaces/announcementType.ts b/server/src/interfaces/announcementType.ts new file mode 100644 index 0000000..432200d --- /dev/null +++ b/server/src/interfaces/announcementType.ts @@ -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"; diff --git a/server/src/modules/announceOnDiscord.ts b/server/src/modules/announceOnDiscord.ts index 5262716..5b886cd 100644 --- a/server/src/modules/announceOnDiscord.ts +++ b/server/src/modules/announceOnDiscord.ts @@ -5,14 +5,23 @@ */ /* eslint-disable @typescript-eslint/naming-convention -- we are making raw API calls. */ -const channelIds = { +import type { AnnouncementType } from "../interfaces/announcementType.js"; + +const channelIds: Record = { community: "1386105484313886820", + company: "1422472775695728661", products: "1386105452881776661", -} as const; -const roleIds = { +}; +const roleIds: Record = { 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. @@ -24,7 +33,7 @@ const roleIds = { export const announceOnDiscord = async( title: string, content: string, - type: "products" | "community", + type: AnnouncementType, ): Promise => { const messageRequest = await fetch( `https://discord.com/api/v10/channels/${channelIds[type]}/messages`, diff --git a/server/src/modules/announceOnReddit.ts b/server/src/modules/announceOnReddit.ts index f38423d..d1c3a57 100644 --- a/server/src/modules/announceOnReddit.ts +++ b/server/src/modules/announceOnReddit.ts @@ -6,8 +6,11 @@ /* eslint-disable @typescript-eslint/naming-convention -- we are making raw API calls. */ /* eslint-disable max-lines-per-function -- Big logic here. */ -const flairIds = { +import type { AnnouncementType } from "../interfaces/announcementType.js"; + +const flairIds: Record = { community: "7a01a5a6-0f29-11ef-a0c4-c6fb085f7c8f", + company: "dd8057c0-9e30-11f0-b321-d683551dcb2b", products: "335e57b6-083f-11ef-96b3-0202af2d9d99", }; @@ -21,7 +24,7 @@ const flairIds = { export const announceOnReddit = async( title: string, content: string, - type: "products" | "community", + type: AnnouncementType, ): Promise => { if ( process.env.REDDIT_CLIENT_ID === undefined diff --git a/server/src/routes/announcement.ts b/server/src/routes/announcement.ts index 6ccfba5..ec4370d 100644 --- a/server/src/routes/announcement.ts +++ b/server/src/routes/announcement.ts @@ -12,6 +12,7 @@ import { announceOnReddit } from "../modules/announceOnReddit.js"; import { announceOnTwitter } from "../modules/announceOnTwitter.js"; import { getIpFromRequest } from "../modules/getIpFromRequest.js"; import { summarisePost } from "../modules/summarisePost.js"; +import { isAnnouncementType } from "../utils/typeguards.js"; import type { FastifyPluginAsync } from "fastify"; 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({ error: - "Invalid announcement type. Available types: products, community.", + `Invalid announcement type. Available types: products, community, company.`, }); } diff --git a/server/src/routes/sanction.ts b/server/src/routes/sanction.ts index 29c93ee..3036d03 100644 --- a/server/src/routes/sanction.ts +++ b/server/src/routes/sanction.ts @@ -8,7 +8,7 @@ import { blockedIps } from "../cache/blockedIps.js"; import { database } from "../db/database.js"; import { getIpFromRequest } from "../modules/getIpFromRequest.js"; import { getSanctionComponents } from "../modules/getSanctionComponents.js"; -import { isValidString } from "../utils/isValidString.js"; +import { isValidString } from "../utils/typeguards.js"; import type { FastifyPluginAsync } from "fastify"; const oneDay = 24 * 60 * 60 * 1000; diff --git a/server/src/utils/isValidString.ts b/server/src/utils/isValidString.ts deleted file mode 100644 index 923b6cf..0000000 --- a/server/src/utils/isValidString.ts +++ /dev/null @@ -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; -}; diff --git a/server/src/utils/typeguards.ts b/server/src/utils/typeguards.ts new file mode 100644 index 0000000..38be550 --- /dev/null +++ b/server/src/utils/typeguards.ts @@ -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 };