返回 presentation-ai
unsplash.ts
根目录 / src / app / _actions / image / unsplash.ts
1 "use server";
2
3 import { type LayoutType } from "@/components/presentation/utils/parser";
4 import { env } from "@/env";
5 import { requireOptionalIntegration } from "@/lib/env/optional-integrations";
6 import { auth } from "@/server/auth";
7
8 export interface UnsplashImage {
9 id: string;
10 urls: {
11 raw: string;
12 full: string;
13 regular: string;
14 small: string;
15 thumb: string;
16 };
17 alt_description: string | null;
18 description: string | null;
19 user: {
20 name: string;
21 username: string;
22 };
23 links: {
24 download_location: string;
25 };
26 }
27
28 export interface UnsplashSearchResponse {
29 results: UnsplashImage[];
30 total: number;
31 total_pages: number;
32 }
33
34 export async function getImageFromUnsplash(
35 query: string,
36 layoutType?: LayoutType,
37 ): Promise<{ success: boolean; imageUrl?: string; error?: string }> {
38 // Get the current session
39 const session = await auth();
40
41 // Check if user is authenticated
42 if (!session?.user?.id) {
43 return { success: false, error: "You must be logged in to get images" };
44 }
45
46 const unsplashConfig = requireOptionalIntegration({
47 integration: "Unsplash",
48 envVar: "UNSPLASH_ACCESS_KEY",
49 value: env.UNSPLASH_ACCESS_KEY,
50 feature: "stock image search",
51 });
52
53 if (!unsplashConfig.ok) {
54 return {
55 success: false,
56 error: unsplashConfig.error,
57 };
58 }
59
60 const orientationQuery =
61 layoutType === "vertical"
62 ? "&orientation=landscape"
63 : layoutType === "left" || layoutType === "right"
64 ? "&orientation=portrait"
65 : "&orientation=landscape";
66 try {
67 // Search for images
68 const response = await fetch(
69 `https://api.unsplash.com/search/photos?query=${encodeURIComponent(query)}&page=1&per_page=1${orientationQuery}`,
70 {
71 headers: {
72 Authorization: `Client-ID ${unsplashConfig.value}`,
73 },
74 },
75 );
76
77 if (!response.ok) {
78 throw new Error(`Unsplash API error: ${response.status}`);
79 }
80
81 const data: UnsplashSearchResponse = await response.json();
82
83 if (!data.results || data.results.length === 0) {
84 return { success: false, error: "No images found for this query" };
85 }
86
87 const firstImage = data.results[0];
88 if (!firstImage) {
89 return { success: false, error: "No images found for this query" };
90 }
91
92 // Return the image URL directly without storing in database
93 return {
94 success: true,
95 imageUrl: firstImage.urls.regular,
96 };
97 } catch (error) {
98 console.error("Error getting Unsplash image:", error);
99 return {
100 success: false,
101 error: error instanceof Error ? error.message : "Failed to get image",
102 };
103 }
104 }
105
105 lines TYPESCRIPT