Sync articles marked toread in kipclip to Crosspoint Reader (Xteink X4)
1import { resolveHandle } from "./backend/atproto-client.ts";
2
3const did = await resolveHandle("tijs.org");
4const res = await fetch(`https://plc.directory/${did}`);
5const doc = await res.json();
6const pds = doc.service.find((s: { id: string }) => s.id === "#atproto_pds").serviceEndpoint;
7
8type Rec = { uri: string; value: { tags?: string[]; subject?: string; createdAt?: string } };
9
10// Find where "toread" bookmarks sit in the record ordering
11const allRecords: Rec[] = [];
12let cursor: string | undefined;
13let page = 0;
14do {
15 const params = new URLSearchParams({ repo: did, collection: "community.lexicon.bookmarks.bookmark", limit: "100" });
16 if (cursor) params.set("cursor", cursor);
17 const r = await fetch(`${pds}/xrpc/com.atproto.repo.listRecords?${params}`);
18 const data = await r.json();
19 const toreadOnPage = data.records.filter((r: Rec) => r.value.tags?.includes("toread"));
20 if (toreadOnPage.length > 0) {
21 console.log(`Page ${page}: ${data.records.length} records, ${toreadOnPage.length} toread`);
22 // Show rkey of first record on this page
23 const rkey = data.records[0].uri.split("/").pop();
24 console.log(` First rkey on page: ${rkey}`);
25 }
26 allRecords.push(...data.records);
27 cursor = data.cursor;
28 page++;
29} while (cursor);
30
31console.log(`\nTotal: ${allRecords.length} bookmarks across ${page} pages`);
32
33// Show rkeys of toread bookmarks
34const toread = allRecords.filter((r) => r.value.tags?.includes("toread"));
35console.log(`Toread: ${toread.length}`);
36for (const r of toread.slice(0, 5)) {
37 const rkey = r.uri.split("/").pop();
38 console.log(` rkey: ${rkey} url: ${r.value.subject?.slice(0, 60)}`)
39}