harisyammnv nsarrazin HF Staff commited on
Commit
037df62
·
unverified ·
1 Parent(s): 2a618ac

Websearch using Bing API (#1420)

Browse files

* feat: bing search enabled

* lint

* feat: bing url hardcoded

* lint

---------

Co-authored-by: Nathan Sarrazin <[email protected]>

.env CHANGED
@@ -27,6 +27,7 @@ SERPSTACK_API_KEY=#your serpstack api key here
27
  SEARCHAPI_KEY=#your searchapi api key here
28
  USE_LOCAL_WEBSEARCH=#set to true to parse google results yourself, overrides other API keys
29
  SEARXNG_QUERY_URL=# where '<query>' will be replaced with query keywords see https://docs.searxng.org/dev/search_api.html eg https://searxng.yourdomain.com/search?q=<query>&engines=duckduckgo,google&format=json
 
30
  PLAYWRIGHT_ADBLOCKER=true
31
 
32
  WEBSEARCH_ALLOWLIST=`[]` # if it's defined, allow websites from only this list.
 
27
  SEARCHAPI_KEY=#your searchapi api key here
28
  USE_LOCAL_WEBSEARCH=#set to true to parse google results yourself, overrides other API keys
29
  SEARXNG_QUERY_URL=# where '<query>' will be replaced with query keywords see https://docs.searxng.org/dev/search_api.html eg https://searxng.yourdomain.com/search?q=<query>&engines=duckduckgo,google&format=json
30
+ BING_SUBSCRIPTION_KEY=#your key
31
  PLAYWRIGHT_ADBLOCKER=true
32
 
33
  WEBSEARCH_ALLOWLIST=`[]` # if it's defined, allow websites from only this list.
src/lib/server/websearch/search/endpoints.ts CHANGED
@@ -7,10 +7,12 @@ import searchYouApi from "./endpoints/youApi";
7
  import searchWebLocal from "./endpoints/webLocal";
8
  import searchSearxng from "./endpoints/searxng";
9
  import searchSearchApi from "./endpoints/searchApi";
 
10
 
11
  export function getWebSearchProvider() {
12
  if (env.YDC_API_KEY) return WebSearchProvider.YOU;
13
  if (env.SEARXNG_QUERY_URL) return WebSearchProvider.SEARXNG;
 
14
  return WebSearchProvider.GOOGLE;
15
  }
16
 
@@ -23,6 +25,7 @@ export async function searchWeb(query: string): Promise<WebSearchSource[]> {
23
  if (env.SERPAPI_KEY) return searchSerpApi(query);
24
  if (env.SERPSTACK_API_KEY) return searchSerpStack(query);
25
  if (env.SEARCHAPI_KEY) return searchSearchApi(query);
 
26
  throw new Error(
27
  "No configuration found for web search. Please set USE_LOCAL_WEBSEARCH, SEARXNG_QUERY_URL, SERPER_API_KEY, YDC_API_KEY, SERPSTACK_API_KEY, or SEARCHAPI_KEY in your environment variables."
28
  );
 
7
  import searchWebLocal from "./endpoints/webLocal";
8
  import searchSearxng from "./endpoints/searxng";
9
  import searchSearchApi from "./endpoints/searchApi";
10
+ import searchBing from "./endpoints/bing";
11
 
12
  export function getWebSearchProvider() {
13
  if (env.YDC_API_KEY) return WebSearchProvider.YOU;
14
  if (env.SEARXNG_QUERY_URL) return WebSearchProvider.SEARXNG;
15
+ if (env.BING_SUBSCRIPTION_KEY) return WebSearchProvider.BING;
16
  return WebSearchProvider.GOOGLE;
17
  }
18
 
 
25
  if (env.SERPAPI_KEY) return searchSerpApi(query);
26
  if (env.SERPSTACK_API_KEY) return searchSerpStack(query);
27
  if (env.SEARCHAPI_KEY) return searchSearchApi(query);
28
+ if (env.BING_SUBSCRIPTION_KEY) return searchBing(query);
29
  throw new Error(
30
  "No configuration found for web search. Please set USE_LOCAL_WEBSEARCH, SEARXNG_QUERY_URL, SERPER_API_KEY, YDC_API_KEY, SERPSTACK_API_KEY, or SEARCHAPI_KEY in your environment variables."
31
  );
src/lib/server/websearch/search/endpoints/bing.ts ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import type { WebSearchSource } from "$lib/types/WebSearch";
2
+ import { env } from "$env/dynamic/private";
3
+
4
+ export default async function search(query: string): Promise<WebSearchSource[]> {
5
+ // const params = {
6
+ // q: query,
7
+ // // You can add other parameters if needed, like 'count', 'offset', etc.
8
+ // };
9
+
10
+ const response = await fetch(
11
+ "https://api.bing.microsoft.com/v7.0/search" + "?q=" + encodeURIComponent(query),
12
+ {
13
+ method: "GET",
14
+ headers: {
15
+ "Ocp-Apim-Subscription-Key": env.BING_SUBSCRIPTION_KEY,
16
+ "Content-type": "application/json",
17
+ },
18
+ }
19
+ );
20
+
21
+ /* eslint-disable @typescript-eslint/no-explicit-any */
22
+ const data = (await response.json()) as Record<string, any>;
23
+
24
+ if (!response.ok) {
25
+ throw new Error(
26
+ data["message"] ?? `Bing API returned error code ${response.status} - ${response.statusText}`
27
+ );
28
+ }
29
+
30
+ console.log(data["webPages"]?.["value"]);
31
+
32
+ // Adapt the data structure from the Bing response to match the WebSearchSource type
33
+ const webPages = data["webPages"]?.["value"] ?? [];
34
+ return webPages.map((page: any) => ({
35
+ title: page.name,
36
+ link: page.url,
37
+ text: page.snippet,
38
+ displayLink: page.displayUrl,
39
+ }));
40
+ }
src/lib/types/WebSearch.ts CHANGED
@@ -45,4 +45,5 @@ export enum WebSearchProvider {
45
  GOOGLE = "Google",
46
  YOU = "You.com",
47
  SEARXNG = "SearXNG",
 
48
  }
 
45
  GOOGLE = "Google",
46
  YOU = "You.com",
47
  SEARXNG = "SearXNG",
48
+ BING = "Bing",
49
  }
src/routes/+layout.server.ts CHANGED
@@ -155,7 +155,8 @@ export const load: LayoutServerLoad = async ({ locals, depends, request }) => {
155
  env.SEARCHAPI_KEY ||
156
  env.YDC_API_KEY ||
157
  env.USE_LOCAL_WEBSEARCH ||
158
- env.SEARXNG_QUERY_URL
 
159
  ),
160
  ethicsModalAccepted: !!settings?.ethicsModalAcceptedAt,
161
  ethicsModalAcceptedAt: settings?.ethicsModalAcceptedAt ?? null,
 
155
  env.SEARCHAPI_KEY ||
156
  env.YDC_API_KEY ||
157
  env.USE_LOCAL_WEBSEARCH ||
158
+ env.SEARXNG_QUERY_URL ||
159
+ env.BING_SUBSCRIPTION_KEY
160
  ),
161
  ethicsModalAccepted: !!settings?.ethicsModalAcceptedAt,
162
  ethicsModalAcceptedAt: settings?.ethicsModalAcceptedAt ?? null,