service status on atproto
at 982d5ceb24677c1ff4e4650ae261ad1908dfedab 102 lines 2.7 kB view raw
1import { 2 Client, 3 CredentialManager, 4 ok, 5 simpleFetchHandler, 6} from "@atcute/client"; 7import { getPdsEndpoint } from "@atcute/identity"; 8import { 9 CompositeDidDocumentResolver, 10 PlcDidDocumentResolver, 11 WebDidDocumentResolver, 12} from "@atcute/identity-resolver"; 13import { isDid, type AtprotoDid } from "@atcute/lexicons/syntax"; 14import { env } from "process"; 15import type {} from "@atcute/atproto"; 16import {} from "barometer-lexicon"; 17import { SystemsGazeBarometerState } from "barometer-lexicon"; 18import { now as generateTid } from "@atcute/tid"; 19import { is, safeParse } from "@atcute/lexicons"; 20 21interface Config { 22 repoDid: AtprotoDid; 23 appPass: string; 24} 25 26const getConfig = (prefix: string): Config => { 27 const get = <Value>( 28 name: string, 29 check: (value: unknown) => boolean = (value) => 30 typeof value !== "undefined", 31 ): Value => { 32 const value = env[`${prefix}${name}`]; 33 if (check(value)) { 34 return value as Value; 35 } 36 throw `config key ${name} is invalid`; 37 }; 38 return { 39 repoDid: get("REPO_DID", isDid), 40 appPass: get("APP_PASSWORD"), 41 }; 42}; 43 44const config = getConfig("BAROMETER_"); 45 46const docResolver = new CompositeDidDocumentResolver({ 47 methods: { 48 plc: new PlcDidDocumentResolver(), 49 web: new WebDidDocumentResolver(), 50 }, 51}); 52 53const pdsUrl = getPdsEndpoint(await docResolver.resolve(config.repoDid)); 54if (pdsUrl === undefined) { 55 throw `no pds found`; 56} 57console.info(`pds is ${pdsUrl}`); 58 59const creds = new CredentialManager({ service: pdsUrl }); 60const session = await creds.login({ 61 identifier: config.repoDid, 62 password: config.appPass, 63}); 64const atpClient = new Client({ handler: creds }); 65 66const server = Bun.serve({ 67 routes: { 68 "/push": { 69 POST: async (req) => { 70 const maybeState = safeParse( 71 SystemsGazeBarometerState.mainSchema, 72 await req.json(), 73 ); 74 if (!maybeState.ok) { 75 return new Response( 76 JSON.stringify({ 77 msg: `invalid state: ${maybeState.message}`, 78 issues: maybeState.issues, 79 }), 80 { status: 400 }, 81 ); 82 } 83 const state = maybeState.value; 84 const result = await ok( 85 atpClient.post("com.atproto.repo.putRecord", { 86 input: { 87 collection: state.$type, 88 record: state, 89 repo: config.repoDid, 90 rkey: generateTid(), 91 }, 92 }), 93 ); 94 return new Response( 95 JSON.stringify({ cid: result.cid, uri: result.uri }), 96 ); 97 }, 98 }, 99 }, 100}); 101 102console.log(`server running on http://localhost:${server.port}`);