Something went wrong. Try again.
a tool for shared writing and social publishing
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879import { Agent, lexToJson } from "@atproto/api";import { ThreadViewPost } from "@atproto/api/dist/client/types/app/bsky/feed/defs";import { cookies } from "next/headers";import { NextRequest } from "next/server";import { createOauthClient } from "src/atproto-oauth";import { supabaseServerClient } from "supabase/serverClient";
export const runtime = "nodejs";
async function getAuthenticatedAgent(): Promise<Agent | null> { try { const cookieStore = await cookies(); const authToken = cookieStore.get("auth_token")?.value || cookieStore.get("external_auth_token")?.value;
if (!authToken || authToken === "null") return null;
const { data } = await supabaseServerClient .from("email_auth_tokens") .select("identities(atp_did)") .eq("id", authToken) .eq("confirmed", true) .single();
const did = data?.identities?.atp_did; if (!did) return null;
const oauthClient = await createOauthClient(); const session = await oauthClient.restore(did); return new Agent(session); } catch (error) { console.error("Failed to get authenticated agent:", error); return null; }}
export async function GET(req: NextRequest) { try { const searchParams = req.nextUrl.searchParams; const uri = searchParams.get("uri"); const depth = searchParams.get("depth"); const parentHeight = searchParams.get("parentHeight");
if (!uri) { return Response.json( { error: "uri parameter is required" }, { status: 400 }, ); }
// Try to use authenticated agent if user is logged in, otherwise fall back to public API let agent = await getAuthenticatedAgent(); if (!agent) { agent = new Agent({ service: "https://public.api.bsky.app", }); }
const response = await agent.getPostThread({ uri, depth: depth ? parseInt(depth, 10) : 6, parentHeight: parentHeight ? parseInt(parentHeight, 10) : 80, });
const thread = lexToJson(response.data.thread);
return Response.json(thread, { headers: { // Cache for 5 minutes on CDN, allow stale content for 1 hour while revalidating "Cache-Control": "public, s-maxage=300, stale-while-revalidate=3600", }, }); } catch (error) { console.error("Error fetching Bluesky thread:", error); return Response.json({ error: "Failed to fetch thread" }, { status: 500 }); }}