generated from nhcarrigan/template
feat: incorporate more socials #6
Generated
+8
@@ -133,6 +133,9 @@ importers:
|
||||
gray-matter:
|
||||
specifier: 4.0.3
|
||||
version: 4.0.3
|
||||
twitter-api-v2:
|
||||
specifier: 1.24.0
|
||||
version: 1.24.0
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: 24.0.10
|
||||
@@ -4589,6 +4592,9 @@ packages:
|
||||
resolution: {integrity: sha512-kc8ZibdRcuWUG1pbYSBFWqmIjynlD8Lp7IB6U3vIzvOv9VG+6Sp8bzyeBWE3Oi8XV5KsQrznyRTBPvrf99E4mA==}
|
||||
hasBin: true
|
||||
|
||||
twitter-api-v2@1.24.0:
|
||||
resolution: {integrity: sha512-RDEiuNwnFirvf4c5f1sysgg0rfMQgekXgKt+/UdbNu+Bs5bJ1VbXkqKzdd2a2lPMlDVDbdGUoe2pOd4n25fFVQ==}
|
||||
|
||||
type-check@0.4.0:
|
||||
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
@@ -10097,6 +10103,8 @@ snapshots:
|
||||
turbo-windows-64: 2.5.4
|
||||
turbo-windows-arm64: 2.5.4
|
||||
|
||||
twitter-api-v2@1.24.0: {}
|
||||
|
||||
type-check@0.4.0:
|
||||
dependencies:
|
||||
prelude-ls: 1.2.1
|
||||
|
||||
+2
-1
@@ -22,7 +22,8 @@
|
||||
"@nhcarrigan/logger": "1.0.0",
|
||||
"@prisma/client": "6.11.1",
|
||||
"fastify": "5.4.0",
|
||||
"gray-matter": "4.0.3"
|
||||
"gray-matter": "4.0.3",
|
||||
"twitter-api-v2": "1.24.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "24.0.10",
|
||||
|
||||
+6
-1
@@ -8,4 +8,9 @@ REDDIT_CLIENT_SECRET="op://Environment Variables - Naomi/Hikari/reddit_client_se
|
||||
REDDIT_PASSWORD="op://Environment Variables - Naomi/Hikari/reddit_password"
|
||||
REDDIT_USERNAME="op://Environment Variables - Naomi/Hikari/reddit_username"
|
||||
BSKY_APP_PASSWORD="op://Environment Variables - Naomi/Hikari/bsky_password"
|
||||
ANTHROPIC_KEY="op://Environment Variables - Naomi/Hikari/anthropic_key"
|
||||
ANTHROPIC_KEY="op://Environment Variables - Naomi/Hikari/anthropic_key"
|
||||
TWITTER_TOKEN="op://Environment Variables - Naomi/Hikari/twitter_access_token"
|
||||
TWITTER_SECRET="op://Environment Variables - Naomi/Hikari/twitter_access_secret"
|
||||
TWITTER_CONSUMER_KEY="op://Environment Variables - Naomi/Hikari/twitter_consumer_key"
|
||||
TWITTER_CONSUMER_SECRET="op://Environment Variables - Naomi/Hikari/twitter_consumer_secret"
|
||||
TWITTER_BEARER_TOKEN="op://Environment Variables - Naomi/Hikari/twitter_bearer_token"
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @copyright nhcarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import { TwitterApi } from "twitter-api-v2";
|
||||
|
||||
/**
|
||||
* Forwards an announcement to our Twitter account.
|
||||
* @param content - The main body of the announcement.
|
||||
* @returns A message indicating the success or failure of the operation.
|
||||
*/
|
||||
export const announceOnTwitter = async(content: string): Promise<string> => {
|
||||
if (
|
||||
process.env.TWITTER_CONSUMER_KEY === undefined
|
||||
|| process.env.TWITTER_CONSUMER_SECRET === undefined
|
||||
|| process.env.TWITTER_TOKEN === undefined
|
||||
|| process.env.TWITTER_SECRET === undefined
|
||||
) {
|
||||
return "Twitter credentials are not set.";
|
||||
}
|
||||
const twitterClient = new TwitterApi({
|
||||
accessSecret: process.env.TWITTER_SECRET,
|
||||
accessToken: process.env.TWITTER_TOKEN,
|
||||
appKey: process.env.TWITTER_CONSUMER_KEY,
|
||||
appSecret: process.env.TWITTER_CONSUMER_SECRET,
|
||||
});
|
||||
|
||||
const result = await twitterClient.v2.
|
||||
tweet(content).
|
||||
catch((error: unknown) => {
|
||||
return error instanceof Error
|
||||
? error.message
|
||||
: String(error);
|
||||
});
|
||||
if (typeof result === "string") {
|
||||
return `Failed to send message to Twitter. ${result}`;
|
||||
}
|
||||
return "Successfully sent message to Twitter.";
|
||||
};
|
||||
@@ -4,11 +4,12 @@
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention -- 'Tis a class.
|
||||
import Anthropic from "@anthropic-ai/sdk";
|
||||
|
||||
/**
|
||||
* Summarises an announcement using AI, to condense the content for platforms like Bluesky and Twitter.
|
||||
* @param title
|
||||
* @param title - The title of the announcement.
|
||||
* @param content - The main body of the announcement.
|
||||
* @returns A message indicating the success or failure of the operation.
|
||||
*/
|
||||
|
||||
@@ -10,6 +10,7 @@ import { announceOnBluesky } from "../modules/announceOnBluesky.js";
|
||||
import { announceOnDiscord } from "../modules/announceOnDiscord.js";
|
||||
import { announceOnForum } from "../modules/announceOnForum.js";
|
||||
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 type { FastifyPluginAsync } from "fastify";
|
||||
@@ -109,18 +110,19 @@ export const announcementRoutes: FastifyPluginAsync = async(server) => {
|
||||
const summary = await summarisePost(title, content);
|
||||
if (summary === null) {
|
||||
return await reply.status(201).send({
|
||||
message: `Announcement processed. Discord: ${discord}, Forum: ${forum}, Reddit: ${reddit}, Bluesky: Skipped (AI summarisation failed).`,
|
||||
message: `Announcement processed. Discord: ${discord}, Forum: ${forum}, Reddit: ${reddit}, Bluesky: Skipped (AI summarisation failed), Twitter: Skipped (AI summarisation failed).`,
|
||||
});
|
||||
}
|
||||
if (summary.length > 280) {
|
||||
return await reply.status(201).send({
|
||||
message: `Announcement processed. Discord: ${discord}, Forum: ${forum}, Reddit: ${reddit}, Bluesky: Skipped (AI summary too long).`,
|
||||
message: `Announcement processed. Discord: ${discord}, Forum: ${forum}, Reddit: ${reddit}, Bluesky: Skipped (AI summary too long), Twitter: Skipped (AI summary too long).`,
|
||||
});
|
||||
}
|
||||
|
||||
const bluesky = await announceOnBluesky(summary);
|
||||
const twitter = await announceOnTwitter(summary);
|
||||
return await reply.status(201).send({
|
||||
message: `Announcement processed. Discord: ${discord}, Forum: ${forum}, Reddit: ${reddit}, Bluesky: ${bluesky}`,
|
||||
message: `Announcement processed. Discord: ${discord}, Forum: ${forum}, Reddit: ${reddit}, Bluesky: ${bluesky}, Twitter: ${twitter}`,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user