Compare commits

4 Commits

Author SHA1 Message Date
1913ba5614 feat: ci
All checks were successful
Node.js CI / Lint and Test (pull_request) Successful in 41s
2025-03-07 11:50:15 -08:00
83ea0a33f2 feat: add mastodon 2025-03-07 11:47:45 -08:00
ef00f107e9 fix: ephemeral response 2025-03-07 11:25:06 -08:00
790be688ea fix: scopes 2025-03-07 11:24:31 -08:00
4 changed files with 61 additions and 8 deletions

38
.gitea/workflows/ci.yml Normal file
View File

@ -0,0 +1,38 @@
name: Node.js CI
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
lint:
name: Lint and Test
steps:
- name: Checkout Source Files
uses: actions/checkout@v4
- name: Use Node.js v22
uses: actions/setup-node@v4
with:
node-version: 22
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 10
- name: Install Dependencies
run: pnpm install
- name: Lint Source Files
run: pnpm run lint
- name: Verify Build
run: pnpm run build
- name: Run Tests
run: pnpm run test

View File

@ -9,7 +9,7 @@
"dev": "tsx watch src/index.ts", "dev": "tsx watch src/index.ts",
"lint": "eslint src --max-warnings 0", "lint": "eslint src --max-warnings 0",
"start": "op run --env-file=prod.env --no-masking -- node prod/index.js", "start": "op run --env-file=prod.env --no-masking -- node prod/index.js",
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 0"
}, },
"keywords": [], "keywords": [],
"author": "Naomi Carrigan", "author": "Naomi Carrigan",

View File

@ -4,4 +4,5 @@ SLACK_CLIENT_SECRET="op://Environment Variables - Naomi/Mommy/slack_client_secre
SLACK_SIGNING_SECRET="op://Environment Variables - Naomi/Mommy/slack_signing_secret" SLACK_SIGNING_SECRET="op://Environment Variables - Naomi/Mommy/slack_signing_secret"
SLACK_CLIENT_ID="op://Environment Variables - Naomi/Mommy/slack_client_id" SLACK_CLIENT_ID="op://Environment Variables - Naomi/Mommy/slack_client_id"
BSKY_PASSWORD="op://Environment Variables - Naomi/Mommy/bsky_pass" BSKY_PASSWORD="op://Environment Variables - Naomi/Mommy/bsky_pass"
SLACK_STATE_SECRET="op://Environment Variables - Naomi/Mommy/slack_state_secret" SLACK_STATE_SECRET="op://Environment Variables - Naomi/Mommy/slack_state_secret"
FEDI_TOKEN="op://Environment Variables - Naomi/Mommy/mastodon_token"

View File

@ -6,12 +6,13 @@
import { AtpAgent } from "@atproto/api"; import { AtpAgent } from "@atproto/api";
import pkg from "@slack/bolt"; import pkg from "@slack/bolt";
import { Client, Events } from "discord.js"; import { Client, Events, MessageFlags } from "discord.js";
import { scheduleJob } from "node-schedule"; import { scheduleJob } from "node-schedule";
import { serve } from "./server/serve.js"; import { serve } from "./server/serve.js";
import { getMommy } from "./utils/getMommy.js"; import { getMommy } from "./utils/getMommy.js";
import { logger } from "./utils/logger.js"; import { logger } from "./utils/logger.js";
// eslint-disable-next-line @typescript-eslint/naming-convention -- Classes.
const { App, FileInstallationStore } = pkg; const { App, FileInstallationStore } = pkg;
const discord = new Client({ intents: [ ] }); const discord = new Client({ intents: [ ] });
@ -25,7 +26,7 @@ discord.on(Events.InteractionCreate, async(interaction) => {
if (!interaction.isChatInputCommand()) { if (!interaction.isChatInputCommand()) {
return; return;
} }
await interaction.deferReply(); await interaction.deferReply({ flags: MessageFlags.Ephemeral });
const name = interaction.options.getString("name"); const name = interaction.options.getString("name");
const response = await getMommy(name ?? undefined); const response = await getMommy(name ?? undefined);
await interaction.editReply(response); await interaction.editReply(response);
@ -38,19 +39,19 @@ const slack = new App({
installerOptions: { installerOptions: {
directInstall: true, directInstall: true,
}, },
scopes: [ "commands", "chat:write" ], scopes: [ "commands" ],
signingSecret: process.env.SLACK_SIGNING_SECRET ?? "", signingSecret: process.env.SLACK_SIGNING_SECRET ?? "",
stateSecret: process.env.SLACK_STATE_SECRET ?? "", stateSecret: process.env.SLACK_STATE_SECRET ?? "",
}); });
slack.command("/mommy", async({ ack, body, say }) => { slack.command("/mommy", async({ ack, body, respond }) => {
await ack(); await ack();
const trimmed = body.text.trim(); const trimmed = body.text.trim();
const name = trimmed.length > 0 const name = trimmed.length > 0
? trimmed ? trimmed
: undefined; : undefined;
const response = await getMommy(name); const response = await getMommy(name);
await say(response); await respond(response);
}); });
const bsky = new AtpAgent({ const bsky = new AtpAgent({
@ -73,7 +74,20 @@ scheduleJob("0 9 * * *", async() => {
await bsky.post({ await bsky.post({
text: response, text: response,
}); });
await logger.log("info", "Posted to bsky.social!"); await fetch(`https://fedi.nhcarrigan.com/api/notes/create`, {
body: JSON.stringify({
text: response,
visibility: "public",
}),
headers: {
// eslint-disable-next-line @typescript-eslint/naming-convention -- Header name.
"Authorization": `Bearer ${process.env.FEDI_TOKEN ?? ""}`,
// eslint-disable-next-line @typescript-eslint/naming-convention -- Header name.
"Content-Type": "application/json",
},
method: "POST",
});
await logger.log("info", "Posted to bsky and fedi!");
}); });
serve(); serve();