yasomi/src/index.ts

69 lines
1.6 KiB
TypeScript

import * as dotenv from "dotenv";
import express from "express";
import _Ajv from "ajv";
const Ajv = _Ajv as unknown as typeof _Ajv.default;
import { CreatePostRequest, CreatePostRequestSchema } from "./types.js";
import bsky from "@atproto/api";
const { BskyAgent, RichText } = bsky;
const ajv = new Ajv({ allErrors: true });
const valid = {
CreatePostRequest: ajv.compile(CreatePostRequestSchema),
};
dotenv.config();
const agent = new BskyAgent({
service: process.env.BLUESKY_ENDPOINT as string,
});
await agent.login({
identifier: process.env.BLUESKY_EMAIL as string,
password: process.env.BLUESKY_PASSWORD as string,
});
const app: express.Application = express();
const port: number = 3000;
app.get("/", async (_req, resp) => {
resp.send("Yasomi online.");
});
app.post("/create", express.json(), async (req, resp) => {
if (!valid.CreatePostRequest(req.body)) {
resp.status(400);
resp.json({
errors: valid.CreatePostRequest.errors,
});
return;
}
const cpr = req.body as unknown as CreatePostRequest;
const rt = new RichText({ text: cpr.body });
await rt.detectFacets(agent);
if (rt.graphemeLength > 300) {
resp.status(400);
resp.json({
errors: ["message must be less than 300 characters"],
});
return;
}
const postRecord = {
$type: "app.bsky.feed.post",
text: rt.text,
facets: rt.facets,
createdAt: new Date().toISOString(),
};
const postData = await agent.post(postRecord);
resp.json({ atProto: postData });
});
app.listen(port, () => {
console.log("http://pneuma:3000");
});