diff --git a/server/src/config/announcements.ts b/server/src/config/announcements.ts index 5062239..f7f2a96 100644 --- a/server/src/config/announcements.ts +++ b/server/src/config/announcements.ts @@ -16,60 +16,30 @@ Your personality traits: Platform-specific requirements: -**Discord & Reddit:** +**Markdown (for Discord, Reddit, Ko-fi, and Patreon):** - Use markdown formatting (bold, italic, links, lists, etc.) - Include engaging titles that capture attention - Write full, detailed content that tells the complete story - Do NOT use hashtags (these platforms don't use them effectively) - Include clear calls to action +- The same content will be used for Discord, Reddit, Ko-fi, and Patreon, so make it work well for all these platforms -**Twitter:** +**Threaded (for Threads, Twitter, Bluesky, and Mastodon):** - Break content into a thread of individual posts -- Each post should be under 280 characters +- Each post should be under 280 characters (to work for Twitter's limit, which is the most restrictive) - Posts should flow naturally from one to the next - Use relevant hashtags (2-3 per post maximum) - Make the first post compelling to encourage thread reading - Do NOT include post numbers or thread indicators (e.g., "1/5" or "🧵") - -**BlueSky:** -- Break content into a thread of individual posts -- Each post should be under 300 characters -- Posts should flow naturally from one to the next -- Use relevant hashtags sparingly (1-2 per post) -- Make the first post compelling to encourage thread reading -- Do NOT include post numbers or thread indicators - -**Mastodon:** -- Break content into a thread of individual posts -- Each post should be under 500 characters (Mastodon's limit) -- Posts should flow naturally from one to the next -- Use relevant hashtags (2-3 per post) -- Make the first post compelling to encourage thread reading -- Do NOT include post numbers or thread indicators -- Mastodon supports markdown, so you can use basic formatting like **bold** and *italic* - -**Threads:** -- Break content into a thread of individual posts -- Each post should be under 500 characters (Threads' limit) -- Posts should flow naturally from one to the next -- Use relevant hashtags (2-3 per post) -- Make the first post compelling to encourage thread reading -- Do NOT include post numbers or thread indicators - Plain text format (no markdown) +- The same thread will be used for Threads, Twitter, Bluesky, and Mastodon -**Facebook:** +**Plaintext (for LinkedIn, Facebook, and Peerlist):** - Plain text format (no markdown) -- Professional yet friendly tone -- Include relevant hashtags (3-5 total) -- Write in a conversational style suitable for a broader audience +- Professional yet friendly tone, conversational style suitable for a broader audience +- Include 3-5 relevant hashtags - Keep it concise but informative - -**LinkedIn:** -- Plain text format (no markdown) -- More professional tone while maintaining Hikari's personality -- Include relevant professional hashtags (3-5 total) -- Focus on value proposition and impact -- Slightly more formal than other platforms but still engaging +- The same content will be used for LinkedIn, Facebook, and Peerlist **Universal requirements:** - All announcements must include a call to action to donate (https://donate.nhcarrigan.com) @@ -80,83 +50,36 @@ Platform-specific requirements: const announcementJsonSchema = { additionalProperties: false, properties: { - bluesky: { - description: "Array of individual BlueSky posts that form a thread. Each post should be under 300 characters and flow naturally from one to the next.", - items: { - description: "A single BlueSky post in the thread (max 300 characters, no post numbers or thread indicators)", - maxLength: 300, - type: "string", - }, - minItems: 1, - type: "array", - }, - discord: { + markdown: { additionalProperties: false, - description: "Discord announcement with title and markdown-formatted content", + description: "Markdown-formatted announcement for Discord, Reddit, Ko-fi, and Patreon (shared content)", properties: { content: { - description: "Full announcement content formatted with markdown (bold, italic, links, lists, etc.). Should include calls to action for donating and joining Discord.", + description: "Full announcement content formatted with markdown (bold, italic, links, lists, etc.). Should include calls to action for donating and joining Discord. Will be used for Discord, Reddit, Ko-fi, and Patreon.", maxLength: 1900, + minLength: 100, type: "string", }, title: { - description: "Engaging title for the Discord announcement (should capture attention and summarize the key point)", + description: "Engaging title for the announcement (should capture attention and summarize the key point). Will be used for Discord, Reddit, Ko-fi, and Patreon.", maxLength: 256, + minLength: 25, type: "string", }, }, required: [ "content", "title" ], type: "object", }, - facebook: { - description: "Plain text announcement for Facebook with relevant hashtags. Should be conversational and suitable for a broader audience. Include calls to action for donating and joining Discord.", + plaintext: { + description: "Plain text announcement for LinkedIn, Facebook, and Peerlist (shared content). Should be professional yet friendly, conversational style suitable for a broader audience. Include 3-5 relevant hashtags and calls to action for donating and joining Discord.", + maxLength: 1900, + minLength: 100, type: "string", }, - linkedin: { - description: "Plain text announcement for LinkedIn with professional hashtags. Should maintain Hikari's personality while being slightly more formal. Focus on value proposition and impact. Include calls to action for donating and joining Discord.", - type: "string", - }, - mastodon: { - description: "Array of individual Mastodon posts that form a thread. Each post should be under 500 characters and flow naturally from one to the next. Mastodon supports markdown formatting.", + threaded: { + description: "Array of individual posts that form a thread. Will be used for Threads, Twitter, Bluesky, and Mastodon. Each post should be under 280 characters (Twitter's limit) and flow naturally from one to the next.", items: { - description: "A single Mastodon post in the thread (max 500 characters, no post numbers or thread indicators)", - maxLength: 500, - type: "string", - }, - minItems: 1, - type: "array", - }, - reddit: { - additionalProperties: false, - description: "Reddit announcement with title and markdown-formatted content", - properties: { - content: { - description: "Full announcement content formatted with markdown (bold, italic, links, lists, etc.). Should include calls to action for donating and joining Discord.", - type: "string", - }, - title: { - description: "Engaging title for the Reddit post (should be clear, informative, and follow Reddit title conventions)", - maxLength: 256, - type: "string", - }, - }, - required: [ "content", "title" ], - type: "object", - }, - threads: { - description: "Array of individual Threads posts that form a thread. Each post should be under 500 characters and flow naturally from one to the next.", - items: { - description: "A single Threads post in the thread (max 500 characters, no post numbers or thread indicators)", - maxLength: 500, - type: "string", - }, - minItems: 1, - type: "array", - }, - twitter: { - description: "Array of individual Twitter posts that form a thread. Each post should be under 280 characters and flow naturally from one to the next.", - items: { - description: "A single Twitter post in the thread (max 280 characters, no post numbers or thread indicators)", + description: "A single post in the thread (max 280 characters, no post numbers or thread indicators)", maxLength: 280, type: "string", }, @@ -165,14 +88,9 @@ const announcementJsonSchema = { }, }, required: [ - "bluesky", - "discord", - "facebook", - "linkedin", - "mastodon", - "reddit", - "threads", - "twitter", + "markdown", + "plaintext", + "threaded", ], type: "object", }; diff --git a/server/src/interfaces/announcementResponse.ts b/server/src/interfaces/announcementResponse.ts index 8ddbd8c..6c58499 100644 --- a/server/src/interfaces/announcementResponse.ts +++ b/server/src/interfaces/announcementResponse.ts @@ -9,18 +9,10 @@ * @see {@link announcementJsonSchema} */ export interface AnnouncementResponse { - bluesky: Array; - discord: { + markdown: { content: string; title: string; }; - facebook: string; - linkedin: string; - mastodon: Array; - reddit: { - content: string; - title: string; - }; - threads: Array; - twitter: Array; + plaintext: string; + threaded: Array; } diff --git a/server/src/routes/announcement.ts b/server/src/routes/announcement.ts index 5dee9b6..178d865 100644 --- a/server/src/routes/announcement.ts +++ b/server/src/routes/announcement.ts @@ -90,43 +90,39 @@ export const announcementRoutes: FastifyPluginAsync = async(server) => { } const { - bluesky, - discord, - facebook, - mastodon, - reddit, - threads, - twitter, + markdown, + plaintext, + threaded, } = announcement.response; - const { title: discordTitle, content: discordContent } = discord; - const { title: redditTitle, content: redditContent } = reddit; + const { title: markdownTitle, content: markdownContent } = markdown; await database.getInstance().announcements.create({ data: { - content: discordContent, - title: discordTitle, + content: markdownContent, + title: markdownTitle, type: type, }, }); const discordPost = await announceOnDiscord( - discordTitle, - discordContent, + markdownTitle, + markdownContent, type, ); const redditPost = await announceOnReddit( - redditTitle, - redditContent, + markdownTitle, + markdownContent, type, ); - const blueskyPost = await announceOnBluesky(bluesky); - const twitterPost = await announceOnTwitter(twitter); - const facebookPost = await announceOnFacebook(facebook); - const mastodonPost = await announceOnMastodon(mastodon); - const threadsPost = await announceOnThreads(threads); + 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); 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}, Mastodon: ${mastodonPost}, Threads: ${threadsPost}`, + message: `Announcement processed. Discord: ${discordPost}, Reddit: ${redditPost}, Bluesky: ${blueskyPost}, Twitter: ${twitterPost}, Facebook: ${facebookPost}, Threads: ${threadsPost}, Mastodon: ${mastodonPost}`, rawPost: announcement.response, }); },