+38
-4
app/api/bsky/thread/route.ts
+38
-4
app/api/bsky/thread/route.ts
···
1
1
import { Agent, lexToJson } from "@atproto/api";
2
2
import { ThreadViewPost } from "@atproto/api/dist/client/types/app/bsky/feed/defs";
3
+
import { cookies } from "next/headers";
3
4
import { NextRequest } from "next/server";
5
+
import { createOauthClient } from "src/atproto-oauth";
6
+
import { supabaseServerClient } from "supabase/serverClient";
4
7
5
8
export const runtime = "nodejs";
6
9
10
+
async function getAuthenticatedAgent(): Promise<Agent | null> {
11
+
try {
12
+
const cookieStore = await cookies();
13
+
const authToken =
14
+
cookieStore.get("auth_token")?.value ||
15
+
cookieStore.get("external_auth_token")?.value;
16
+
17
+
if (!authToken || authToken === "null") return null;
18
+
19
+
const { data } = await supabaseServerClient
20
+
.from("email_auth_tokens")
21
+
.select("identities(atp_did)")
22
+
.eq("id", authToken)
23
+
.eq("confirmed", true)
24
+
.single();
25
+
26
+
const did = data?.identities?.atp_did;
27
+
if (!did) return null;
28
+
29
+
const oauthClient = await createOauthClient();
30
+
const session = await oauthClient.restore(did);
31
+
return new Agent(session);
32
+
} catch (error) {
33
+
console.error("Failed to get authenticated agent:", error);
34
+
return null;
35
+
}
36
+
}
37
+
7
38
export async function GET(req: NextRequest) {
8
39
try {
9
40
const searchParams = req.nextUrl.searchParams;
···
18
49
);
19
50
}
20
51
21
-
// Fetch thread from Bluesky
22
-
let agent = new Agent({
23
-
service: "https://public.api.bsky.app",
24
-
});
52
+
// Try to use authenticated agent if user is logged in, otherwise fall back to public API
53
+
let agent = await getAuthenticatedAgent();
54
+
if (!agent) {
55
+
agent = new Agent({
56
+
service: "https://public.api.bsky.app",
57
+
});
58
+
}
25
59
26
60
const response = await agent.getPostThread({
27
61
uri,