my-fullstack-ai-platform/app/api/linkedin/connect/route.ts

68 lines
2.1 KiB
TypeScript
Raw Normal View History

import { NextResponse } from "next/server";
import { createClient } from "@/lib/supabase/server";
export async function POST() {
const supabase = await createClient();
const { data: userData, error: userError } = await supabase.auth.getUser();
if (userError || !userData.user) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
const apiKey = process.env.UNIPILE_API_KEY;
const dsn = process.env.UNIPILE_DSN;
const appUrl = process.env.NEXT_PUBLIC_APP_URL;
if (!apiKey || !dsn || !appUrl) {
return NextResponse.json(
{ error: "Unipile is not configured. Please add UNIPILE_API_KEY, UNIPILE_DSN, and NEXT_PUBLIC_APP_URL to your environment." },
{ status: 500 }
);
}
// Check if user already has an account (reconnect flow)
const { data: profile } = await supabase
.from("profiles")
.select("unipile_account_id")
.eq("id", userData.user.id)
.single();
const type = profile?.unipile_account_id ? "reconnect" : "create";
const body: Record<string, unknown> = {
type,
providers: ["LINKEDIN"],
notify_url: `${appUrl}/api/linkedin/callback`,
success_redirect_url: `${appUrl}/dashboard/settings/account?linkedin=connected`,
failure_redirect_url: `${appUrl}/dashboard/settings/account?linkedin=failed`,
// 'name' is returned as-is in the webhook payload, used to map account_id → user
name: userData.user.id,
};
// For reconnect we need the existing account_id
if (type === "reconnect" && profile?.unipile_account_id) {
body.account_id = profile.unipile_account_id;
}
const response = await fetch(`https://${dsn}/api/v1/hosted/accounts/link`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
body: JSON.stringify(body),
});
if (!response.ok) {
const text = await response.text();
console.error("Unipile connect error:", text);
return NextResponse.json(
{ error: "Failed to generate LinkedIn connection link" },
{ status: 502 }
);
}
const data = await response.json();
return NextResponse.json({ url: data.url });
}