Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion server/.env.template
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ GOOGLE_KEY=XXX
OPEN_WEATHER_KEY=XXX
BING_KEY=XXX
FINNHUB_KEY=XXX
WOLFRAM_KEY=XXX
WOLFRAM_KEY=XXX
BRAVE_KEY=XXX
95 changes: 85 additions & 10 deletions server/src/services/search.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,60 @@
import axios from "axios";

const getKey = () => process.env.BING_KEY as string;
// Function to get the Bing API key
const getBingKey = () => process.env.BING_KEY as string | undefined;

interface WebPagesItem {
// Function to get the Brave API key
const getBraveKey = () => process.env.BRAVE_KEY as string;

// Bing Search types
interface BingWebPagesItem {
name: string;
snippet: string;
}

interface WebPages {
interface BingWebPages {
webSearchUrl: string;
totalEstimatedMatches: number;
value: WebPagesItem[];
value: BingWebPagesItem[];
}

interface BingSearchResponse {
webPages: BingWebPages;
}

// Brave Search types
interface BraveWebPagesItem {
title: string;
url: string;
description: string;
}

interface BraveQuery {
original: string;
}

interface SearchResponse {
webPages: WebPages;
interface BraveWebPages {
type: string;
results: BraveWebPagesItem[];
}

export const getSearchResults = async (query: string) => {
interface BraveResponse {
query: BraveQuery;
web: BraveWebPages;
}

// Common result type for both search engines
interface SearchResult {
title: string;
snippet: string;
}

// Bing search implementation
async function bingSearch(query: string): Promise<SearchResult[]> {
const searchClient = axios.create({
baseURL: "https://api.bing.microsoft.com/v7.0",
headers: {
"Ocp-Apim-Subscription-Key": getKey(),
"Ocp-Apim-Subscription-Key": getBingKey(),
},
});

Expand All @@ -32,10 +65,52 @@ export const getSearchResults = async (query: string) => {
},
});

const { webPages } = res.data as SearchResponse;
const { webPages } = res.data as BingSearchResponse;

return webPages.value.map((page) => ({
title: page.name,
snippet: page.snippet,
}));
};
}

// Brave search implementation
async function braveSearch(query: string): Promise<SearchResult[]> {
const searchClient = axios.create({
baseURL: "https://api.search.brave.com/res/v1/web",
headers: {
"X-Subscription-Token": getBraveKey(),
"Accept": "application/json"
},
});

const res = await searchClient.get("/search", {
params: {
q: query,
},
});

const { web } = res.data as BraveResponse;

return web.results.map((page) => ({
title: page.title,
snippet: page.description,
}));
}

// Combined search implementation
export const getSearchResults = async (query: string): Promise<SearchResult[]> => {
const bingKey = getBingKey();

try {
if (bingKey) {
// If Bing key exists, use Bing search
return await bingSearch(query);
} else {
// Otherwise fall back to Brave search
return await braveSearch(query);
}
} catch (error) {
console.error("Search failed:", error);
throw error;
}
};