Some checks failed
Monorepo Pipeline / ⚡ Prioritize Release (push) Successful in 2s
Monorepo Pipeline / 🧹 Lint (push) Successful in 1m12s
Monorepo Pipeline / 🧪 Test (push) Successful in 2m59s
Monorepo Pipeline / 🏗️ Build (push) Successful in 6m52s
Monorepo Pipeline / 🚀 Release (push) Has been skipped
Monorepo Pipeline / 🐳 Build Directus (Base) (push) Has been skipped
Monorepo Pipeline / 🐳 Build Gatekeeper (Product) (push) Has been skipped
Monorepo Pipeline / 🐳 Build Build-Base (push) Has been skipped
Monorepo Pipeline / 🐳 Build Production Runtime (push) Has been skipped
🏥 Server Maintenance / 🧹 Prune & Clean (push) Failing after 4s
129 lines
3.2 KiB
TypeScript
129 lines
3.2 KiB
TypeScript
export interface SerperVideoResult {
|
|
title: string;
|
|
link: string;
|
|
snippet?: string;
|
|
date?: string;
|
|
duration?: string;
|
|
channel?: string;
|
|
}
|
|
|
|
export interface SerperVideoResponse {
|
|
searchParameters: any;
|
|
videos: SerperVideoResult[];
|
|
}
|
|
|
|
export interface SerperWebResult {
|
|
title: string;
|
|
link: string;
|
|
snippet: string;
|
|
date?: string;
|
|
sitelinks?: any[];
|
|
position: number;
|
|
}
|
|
|
|
export interface SerperWebResponse {
|
|
searchParameters: any;
|
|
organic: SerperWebResult[];
|
|
}
|
|
|
|
export class SerperClient {
|
|
private apiKey: string;
|
|
|
|
constructor(apiKey?: string) {
|
|
const key = apiKey || process.env.SERPER_API_KEY;
|
|
if (!key) {
|
|
console.warn("⚠️ SERPER_API_KEY is not defined. SerperClient will fail.");
|
|
}
|
|
this.apiKey = key || "";
|
|
}
|
|
|
|
/**
|
|
* Performs a video search via Serper (Google Video Search).
|
|
* Great for finding relevant YouTube videos.
|
|
*/
|
|
async searchVideos(
|
|
query: string,
|
|
num: number = 5,
|
|
): Promise<SerperVideoResult[]> {
|
|
if (!this.apiKey) {
|
|
console.error("❌ SERPER_API_KEY missing - cannot execute search.");
|
|
return [];
|
|
}
|
|
|
|
try {
|
|
console.log(`🔍 [Serper] Searching videos for: "${query}"`);
|
|
const response = await fetch("https://google.serper.dev/videos", {
|
|
method: "POST",
|
|
headers: {
|
|
"X-API-KEY": this.apiKey,
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
q: query,
|
|
num: num,
|
|
gl: "de", // Germany for localized results
|
|
hl: "de", // German language
|
|
}),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
console.error(
|
|
`❌ [Serper] API Error: ${response.status} ${response.statusText}`,
|
|
);
|
|
const text = await response.text();
|
|
console.error(text);
|
|
return [];
|
|
}
|
|
|
|
const data = (await response.json()) as SerperVideoResponse;
|
|
return data.videos || [];
|
|
} catch (e) {
|
|
console.error("❌ [Serper] Request failed", e);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Performs a standard web search via Serper.
|
|
* Crucial for B2B competitor analysis and context gathering.
|
|
*/
|
|
async searchWeb(query: string, num: number = 5): Promise<SerperWebResult[]> {
|
|
if (!this.apiKey) {
|
|
console.error("❌ SERPER_API_KEY missing - cannot execute web search.");
|
|
return [];
|
|
}
|
|
|
|
try {
|
|
console.log(`🔍 [Serper] Web Search for Competitor Insights: "${query}"`);
|
|
const response = await fetch("https://google.serper.dev/search", {
|
|
method: "POST",
|
|
headers: {
|
|
"X-API-KEY": this.apiKey,
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
q: query,
|
|
num: num,
|
|
gl: "de", // Germany for localized results
|
|
hl: "de", // German language
|
|
}),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
console.error(
|
|
`❌ [Serper] API Error: ${response.status} ${response.statusText}`,
|
|
);
|
|
const text = await response.text();
|
|
console.error(text);
|
|
return [];
|
|
}
|
|
|
|
const data = (await response.json()) as SerperWebResponse;
|
|
return data.organic || [];
|
|
} catch (e) {
|
|
console.error("❌ [Serper] Web Request failed", e);
|
|
return [];
|
|
}
|
|
}
|
|
}
|