a tool to help your Letta AI agents navigate bluesky
1import { bsky } from "./bsky.ts";
2
3type threadPost = {
4 authorHandle: string;
5 message: string;
6 uri: string;
7 authorDID: string;
8 postedDateTime: string;
9 bookmarks: number;
10 replies: number;
11 reposts: number;
12 likes: number;
13 quotes: number;
14};
15
16export const getCleanThread = async (uri: string): Promise<threadPost[]> => {
17 const res = await bsky.getPostThread({ uri: uri });
18 const { thread } = res.data;
19
20 const postsThread: threadPost[] = [];
21
22 // Type guard to check if thread is a ThreadViewPost
23 if (thread && "post" in thread) {
24 postsThread.push({
25 authorHandle: `@${thread.post.author.handle}`,
26 message: (thread.post.record as { text: string }).text,
27 uri: thread.post.uri,
28 authorDID: thread.post.author.did,
29 postedDateTime: (thread.post.record as { createdAt: string }).createdAt,
30 bookmarks: thread.post.bookmarkCount ?? 0,
31 replies: thread.post.replyCount ?? 0,
32 reposts: thread.post.repostCount ?? 0,
33 likes: thread.post.likeCount ?? 0,
34 quotes: thread.post.quoteCount ?? 0,
35 });
36
37 // Now traverse the parent chain
38 if ("parent" in thread) {
39 let current = thread.parent;
40
41 while (current && "post" in current) {
42 postsThread.push({
43 authorHandle: `@${current.post.author.handle}`,
44 message: (current.post.record as { text: string }).text,
45 uri: current.post.uri,
46 authorDID: current.post.author.did,
47 postedDateTime: (current.post.record as { createdAt: string }).createdAt,
48 bookmarks: current.post.bookmarkCount ?? 0,
49 replies: current.post.replyCount ?? 0,
50 reposts: current.post.repostCount ?? 0,
51 likes: current.post.likeCount ?? 0,
52 quotes: current.post.quoteCount ?? 0,
53 });
54 current = "parent" in current ? current.parent : undefined;
55 }
56 postsThread.reverse();
57 }
58 }
59
60 return postsThread;
61};