Pronouns labels on Bluesky
1import { AppBskyActorDefs, ComAtprotoLabelDefs } from "@atproto/api";
2import {
3 DID,
4 PORT,
5 LABEL_LIMIT,
6 POSTS,
7 SIGNING_KEY,
8 DELETE,
9} from "./constants.js";
10import { LabelerServer } from "@skyware/labeler";
11
12const server = new LabelerServer({ did: DID, signingKey: SIGNING_KEY });
13
14server.start(PORT, (error, address) => {
15 if (error) {
16 console.error(error);
17 } else {
18 console.log(`Labeler server listening on ${address}`);
19 }
20});
21
22export const label = async (
23 subject: string | AppBskyActorDefs.ProfileView,
24 uri: string,
25) => {
26 const did = AppBskyActorDefs.isProfileView(subject) ? subject.did : subject;
27
28 const query = server.db
29 .prepare<
30 unknown[],
31 ComAtprotoLabelDefs.Label
32 >(`SELECT * FROM labels WHERE uri = ?`)
33 .all(did);
34
35 const labels = query.reduce((set, label) => {
36 if (!label.neg) set.add(label.val);
37 else set.delete(label.val);
38 return set;
39 }, new Set<string>());
40
41 if (POSTS[uri]?.includes(DELETE)) {
42 await server
43 .createLabels({ uri: did }, { negate: [...labels] })
44 .catch((err) => {
45 console.log(err);
46 })
47 .then(() => console.log(`Deleted labels for ${did}`));
48 } else if (labels.size < LABEL_LIMIT && POSTS[uri]) {
49 await server
50 .createLabel({ uri: did, val: POSTS[uri] })
51 .catch((err) => {
52 console.log(err);
53 })
54 .then(() => console.log(`Labeled ${did} with ${POSTS[uri]}`));
55 }
56};