"use server"; import "server-only"; import { cacheLife, cacheTag } from "next/cache"; import { Client, type l } from "@atproto/lex"; import * as getPostThread from "@/lib/lexicons/app/bsky/feed/getPostThread"; import * as feedDefs from "@/lib/lexicons/app/bsky/feed/defs"; import { loadTrailCardByUri } from "@/data/queries"; import { TrailCard } from "./TrailCard"; import { BlueskyPostEmbed } from "./at/(trail)/[handle]/trail/[rkey]/embeds/BlueskyPostEmbed"; import { LinkPreview } from "./at/(trail)/[handle]/trail/[rkey]/LinkPreview"; import { blueskyUrlToAtUri } from "./at/(trail)/[handle]/trail/[rkey]/utils/bluesky"; type BlueskyPost = feedDefs.ThreadViewPost; type LinkMetadata = { uri: string; title: string; description: string; thumb?: string; }; function isTrailUri(uri: string): boolean { return uri.includes("/app.sidetrail.trail/"); } function isBlueskyPostUri(uri: string): boolean { return ( uri.includes("/app.bsky.feed.post/") || (uri.includes("bsky.app") && uri.includes("/post/")) ); } // Cached fetch for Bluesky posts - throws on failure async function fetchBlueskyPost(atUri: string): Promise { "use cache: redis"; cacheTag(`embed:bsky:${atUri}`); cacheLife("days"); const atprotoClient = new Client("https://public.api.bsky.app"); const result = await atprotoClient.call(getPostThread.main, { uri: atUri as l.AtUri, depth: 0, parentHeight: 0, }); if (feedDefs.threadViewPost.$check(result.thread)) { // Serialize to strip non-plain objects (like CID) return JSON.parse(JSON.stringify(result.thread)) as BlueskyPost; } throw new Error(`Invalid thread response for ${atUri}`); } // Cached fetch for link metadata - throws on failure async function fetchLinkMetadata(url: string): Promise { "use cache: redis"; cacheTag(`embed:link:${url}`); cacheLife("days"); const response = await fetch(`https://cardyb.bsky.app/v1/extract?url=${encodeURIComponent(url)}`); if (!response.ok) { throw new Error(`Failed to fetch link metadata: ${response.status}`); } const data = await response.json(); return { uri: url, title: data.title || url, description: data.description || "", thumb: data.image || undefined, }; } export async function loadEmbed(uri: string): Promise { if (isTrailUri(uri)) { const trail = await loadTrailCardByUri(uri); if (!trail) throw new Error(`Trail not found: ${uri}`); return ; } if (isBlueskyPostUri(uri)) { const atUri = uri.startsWith("at://") ? uri : uri.startsWith("http") ? blueskyUrlToAtUri(uri) : null; if (!atUri) throw new Error(`Invalid Bluesky URI: ${uri}`); const post = await fetchBlueskyPost(atUri); return ; } // Regular link const metadata = await fetchLinkMetadata(uri); return ( ); }