A Astro blog hosted on Vercel
at main 2.2 kB view raw
1import { BLUESKY_DID } from "@/consts"; 2import formatBlogTitleUrl from "./formatBlogTitleUrl"; 3import { AppBskyFeedPost, AtpAgent } from '@atproto/api' 4import { isThreadViewPost } from "@atproto/api/dist/client/types/app/bsky/feed/defs"; 5 6async function getBlogPostComments(blogTitle: string) { 7 8 const agent = new AtpAgent({ service: new URL("https://api.bsky.app") }); 9 10 const post = await agent.app.bsky.feed.searchPosts({ 11 q: `#blog #${formatBlogTitleUrl(blogTitle)}`, 12 author: BLUESKY_DID, 13 limit: 1 14 }).then(({ data }) => { 15 if (!data.posts) return undefined; 16 17 return data.posts[0]; 18 }).catch(console.error); 19 20 if (!post) return []; 21 22 if (post.replyCount === 0) return []; 23 24 const comments = await agent.app.bsky.feed.getPostThread({ 25 uri: post.uri, 26 depth: 1 27 }).then(({ data }) => { 28 if (!isThreadViewPost(data.thread)) return []; 29 30 if (!data.thread.replies) return []; 31 32 return data.thread.replies.map((reply) => { 33 if (!isThreadViewPost(reply)) return null; 34 35 const record = reply.post.record as AppBskyFeedPost.Record; 36 37 const postId = reply.post.uri.split('/').at(-1); 38 39 if (!postId) return null; 40 41 return { 42 likeCount: reply.post.likeCount, 43 replyCount: reply.post.replyCount, 44 repostCount: reply.post.repostCount, 45 displayName: reply.post.author.displayName, 46 handle: reply.post.author.handle, 47 createdAt: record.createdAt, 48 text: record.text, 49 authorUrl: `https://bsky.app/profile/${reply.post.author.did}`, 50 postUrl: `https://bsky.app/profile/${reply.post.author.did}/post/${postId}`, 51 cid: reply.post.cid 52 // ...reply.post, 53 // record: { 54 // ...reply.post.record as AppBskyFeedPost.Record 55 // } 56 }; 57 }).filter(reply => reply !== null); 58 }) 59 .catch((error) => { 60 console.error(error); 61 return []; 62 }); 63 64 return comments; 65} 66 67export default getBlogPostComments;