import { LabelerServer } from "@skyware/labeler"; import { BskyAgent, AppBskyGraphDefs } from '@atproto/api' const LABELER_HANDLE = process.env.LABELER_HANDLE!; const LABELER_PASSWORD = process.env.LABELER_PASSWORD!; const LABELER_PDS = process.env.LABELER_PDS!; const LABELER_DID = process.env.LABELER_DID!; const SIGNING_KEY = process.env.SIGNING_KEY!; const LABELS_LISTS = [ ['is-alien', `at://${LABELER_DID}/app.bsky.graph.list/3m72hhjgqww2u`], ['is-alienphobe', `at://${LABELER_DID}/app.bsky.graph.list/3m72h3vsecg2u`], ['ebil-club-member', 'at://did:plc:b26ewgkrnx3yvsp2cdao3ntu/app.bsky.graph.list/3madar3xkeb2p'] ]; const server = new LabelerServer({ did: LABELER_DID, signingKey: SIGNING_KEY }); const agent = new BskyAgent({ service: LABELER_PDS }) await agent.login({ identifier: LABELER_DID, password: LABELER_PASSWORD }) const agentPublic = new BskyAgent({ service: "https://public.api.bsky.app" }) server.app.get("/", (_, res) => res.redirect(`https://witchsky.app/profile/${LABELER_DID}`)); server.start(14831, (error) => { if (error) { console.error("failed to start server:", error); } else { console.log("labeler server running on port 14831"); } }); let isFetching = false; async function fetchAndLabel() { if (isFetching) return; isFetching = true; try { console.log("labeling..."); const query = await server.db.execute({ sql: "SELECT uri, val, neg FROM labels", args: [] }); console.log(`fetched ${query.rows.length} existing labels`); for (const [label, list] of LABELS_LISTS) { let cursor: string | undefined let members: AppBskyGraphDefs.ListItemView[] = [] do { let res = await agentPublic.app.bsky.graph.getList({ list: list, limit: 100, cursor }) cursor = res.data.cursor members = members.concat(res.data.items) } while (cursor) for (const member of members) { try { if (query.rows.find((row: any) => row.uri === member.subject.did && row.val === label && row.neg === 0)) continue; await server.createLabel({ uri: member.subject.did, val: label }); } catch (err) { console.error(`failed to create label ${label} for ${member.subject.did}:`, err); } } console.log(`labeled ${members.length} members with ${label}`); } console.log("labeling completed"); } catch (err) { console.error("labeling failed:", err); } finally { isFetching = false; } } await fetchAndLabel(); setInterval(fetchAndLabel, 30 * 60 * 1000); // 30 minutes