This repository has no description
0

Configure Feed

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

papers / src / pds-writer.ts
2.1 kB 68 lines
1/** 2 * PDS writer — creates org.latha.papers.summary records on the researcher's PDS. 3 */ 4 5import { createPdsSession, dpopFetch, loadPrivateKey, type PdsSession } from "./auth.js"; 6import type { PaperSummary } from "./paper-summarizer.js"; 7import type { PaperPost } from "./feed-watcher.js"; 8 9const PDS_ORIGIN = "https://pds.latha.org"; 10const COLLECTION = "org.latha.papers.summary"; 11 12function generateRkey(): string { 13 const chars = "234567abcdefghijklmnopqrstuvwxyz"; 14 const now = Date.now() * 1000; 15 let tid = ""; 16 let n = now; 17 while (n > 0) { 18 tid = chars[n % 32] + tid; 19 n = Math.floor(n / 32); 20 } 21 return tid.padStart(13, "2"); 22} 23 24export async function writeSummaryToPds( 25 post: PaperPost, 26 summary: PaperSummary, 27): Promise<{ uri: string; cid: string }> { 28 const privateKeyPem = await loadPrivateKey(); 29 const session = await createPdsSession(privateKeyPem); 30 31 const rkey = generateRkey(); 32 const record: Record<string, any> = { 33 $type: COLLECTION, 34 sourceUri: post.postUri, 35 paperUrl: summary.paperUrl, 36 title: summary.title, 37 summary: summary.summary, 38 indexedAt: new Date().toISOString(), 39 }; 40 41 if (summary.authors.length > 0) record.authors = summary.authors; 42 if (summary.abstract) record.abstract = summary.abstract; 43 if (summary.summaryDoc) record.summaryDoc = summary.summaryDoc; 44 if (summary.domains.length > 0) record.domains = summary.domains; 45 if (summary.venue) record.venue = summary.venue; 46 if (summary.year) record.year = summary.year; 47 record.posterDid = post.posterDid; 48 record.posterHandle = post.posterHandle; 49 record.postText = post.postText; 50 51 const url = `${PDS_ORIGIN}/xrpc/com.atproto.repo.createRecord`; 52 const res = await dpopFetch(url, { 53 method: "POST", 54 body: JSON.stringify({ 55 repo: session.did, 56 collection: COLLECTION, 57 record, 58 }), 59 }, session); 60 61 if (!res.ok) { 62 const body = await res.text(); 63 throw new Error(`putRecord failed (${res.status}): ${body}`); 64 } 65 66 const data = await res.json() as { uri: string; cid: string }; 67 return { uri: data.uri, cid: data.cid }; 68}