Daily Bluesky bot for AT Mot. Invites players and congratulates yesterday's solvers.
0

Configure Feed

Select the types of activity you want to include in your feed.

at trunk 1.8 kB View raw
1/** 2 * Identity resolution (handle/DID -> PDS) and per-PDS record reads. 3 * Mirrors the app's read path; failures resolve to null and drop the entry. 4 */ 5import { 6 CompositeDidDocumentResolver, 7 LocalActorResolver, 8 PlcDidDocumentResolver, 9 WebDidDocumentResolver, 10 XrpcHandleResolver, 11 type ResolvedActor, 12} from '@atcute/identity-resolver'; 13import { Client, simpleFetchHandler } from '@atcute/client'; 14import { APPVIEW_URL } from './config.js'; 15 16const actorResolver = new LocalActorResolver({ 17 handleResolver: new XrpcHandleResolver({ serviceUrl: APPVIEW_URL }), 18 didDocumentResolver: new CompositeDidDocumentResolver({ 19 methods: { plc: new PlcDidDocumentResolver(), web: new WebDidDocumentResolver() }, 20 }), 21}); 22 23/** Resolve a handle or DID to { did, handle, pds }. May reject. */ 24export function resolveActor(identifier: string): Promise<ResolvedActor> { 25 return actorResolver.resolve(identifier as Parameters<typeof actorResolver.resolve>[0]); 26} 27 28/** Unauthenticated read client pointed at a specific PDS. */ 29export function pdsClient(pds: string): Client { 30 return new Client({ handler: simpleFetchHandler({ service: pds }) }); 31} 32 33/** Public read of a record by at:// URI; null on any failure. */ 34export async function getRecordByUri<T = unknown>(uri: string): Promise<T | null> { 35 const m = /^at:\/\/([^/]+)\/([^/]+)\/([^/]+)$/.exec(uri); 36 if (!m) return null; 37 try { 38 const actor = await resolveActor(m[1]!); 39 const rpc = pdsClient(actor.pds); 40 const res = await rpc.get('com.atproto.repo.getRecord', { 41 params: { 42 repo: m[1]! as `did:${string}:${string}`, 43 collection: m[2]! as `${string}.${string}.${string}`, 44 rkey: m[3]!, 45 }, 46 }); 47 if (!res.ok) return null; 48 return res.data.value as unknown as T; 49 } catch { 50 return null; 51 } 52}