generated from arvinxx/vercel-serverless-api-template
-
-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
422 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { PluginItem } from '../types/pluginItem'; | ||
import searchEngine from './searchEngine'; | ||
import getWeather from './weather'; | ||
import webCrawler from './webCrawler'; | ||
|
||
export const PluginsMap: Record<string, PluginItem> = { | ||
[getWeather.name]: getWeather, | ||
[searchEngine.name]: searchEngine, | ||
[webCrawler.name]: webCrawler, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { PluginItem } from '../../types/pluginItem'; | ||
import runner from './runner'; | ||
import { Result } from './type'; | ||
|
||
const schema: PluginItem['schema'] = { | ||
description: '查询搜索引擎获取信息', | ||
name: 'searchEngine', | ||
parameters: { | ||
properties: { | ||
keywords: { | ||
description: '关键词', | ||
type: 'string', | ||
}, | ||
}, | ||
required: ['keywords'], | ||
type: 'object', | ||
}, | ||
}; | ||
|
||
const searchEngine: PluginItem<Result> = { | ||
avatar: '🔍', | ||
name: 'searchEngine', | ||
runner, | ||
schema, | ||
}; | ||
|
||
export default searchEngine; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import querystring from 'query-string'; | ||
|
||
import { PluginRunner } from '../../types/pluginItem'; | ||
import { OrganicResults, Result } from './type'; | ||
|
||
const BASE_URL = 'https://serpapi.com/search'; | ||
|
||
const API_KEY = process.env.SERPAI_API_KEY; | ||
|
||
const fetchResult: PluginRunner<{ keywords: string }, Result> = async ({ keywords }) => { | ||
const params = { | ||
api_key: API_KEY, | ||
engine: 'google', | ||
gl: 'cn', | ||
google_domain: 'google.com', | ||
hl: 'zh-cn', | ||
location: 'China', | ||
q: keywords, | ||
}; | ||
|
||
const query = querystring.stringify(params); | ||
|
||
const res = await fetch(`${BASE_URL}?${query}`); | ||
|
||
const data = await res.json(); | ||
|
||
const results = data.organic_results as OrganicResults; | ||
|
||
return results.map((r) => ({ | ||
content: r.snippet, | ||
date: r.date, | ||
displayed_link: r.displayed_link, | ||
favicon: r.favicon, | ||
link: r.link, | ||
source: r.source, | ||
title: r.title, | ||
})); | ||
}; | ||
|
||
export default fetchResult; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
export type OrganicResults = OrganicResult[]; | ||
|
||
export interface SearchItem { | ||
content: string; | ||
date?: string; | ||
displayed_link?: string; | ||
favicon?: string; | ||
link: string; | ||
source?: string; | ||
title: string; | ||
} | ||
export type Result = SearchItem[]; | ||
|
||
interface OrganicResult { | ||
about_page_link: string; | ||
about_page_serpapi_link: string; | ||
about_this_result: AboutThisResult; | ||
cached_page_link?: string; | ||
date?: string; | ||
displayed_link: string; | ||
favicon?: string; | ||
link: string; | ||
position: number; | ||
related_results?: RelatedResult[]; | ||
rich_snippet?: RichSnippet; | ||
snippet: string; | ||
snippet_highlighted_words?: string[]; | ||
source: string; | ||
thumbnail?: string; | ||
title: string; | ||
} | ||
|
||
interface AboutThisResult { | ||
languages: string[]; | ||
regions: string[]; | ||
source: Source; | ||
} | ||
|
||
interface Source { | ||
description: string; | ||
icon: string; | ||
security?: string; | ||
source_info_link?: string; | ||
} | ||
|
||
interface RelatedResult { | ||
about_page_link: string; | ||
about_page_serpapi_link: string; | ||
about_this_result: AboutThisResult2; | ||
cached_page_link: string; | ||
date: string; | ||
displayed_link: string; | ||
link: string; | ||
position: number; | ||
snippet: string; | ||
snippet_highlighted_words: string[]; | ||
title: string; | ||
} | ||
|
||
interface AboutThisResult2 { | ||
languages: string[]; | ||
regions: string[]; | ||
source: Source2; | ||
} | ||
|
||
interface Source2 { | ||
description: string; | ||
icon: string; | ||
} | ||
|
||
interface RichSnippet { | ||
top: Top; | ||
} | ||
|
||
interface Top { | ||
detected_extensions: DetectedExtensions; | ||
extensions: string[]; | ||
} | ||
|
||
interface DetectedExtensions { | ||
month_ago: number; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { PluginItem } from '../../types/pluginItem'; | ||
import runner from './runner'; | ||
import { WeatherResult } from './type'; | ||
|
||
const schema: PluginItem['schema'] = { | ||
description: '获取当前天气情况', | ||
name: 'realtimeWeather', | ||
parameters: { | ||
properties: { | ||
city: { | ||
description: '城市名称', | ||
type: 'string', | ||
}, | ||
}, | ||
required: ['city'], | ||
type: 'object', | ||
}, | ||
}; | ||
|
||
const getWeather: PluginItem<WeatherResult> = { | ||
avatar: '☂️', | ||
name: 'realtimeWeather', | ||
runner, | ||
schema, | ||
}; | ||
|
||
export default getWeather; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { PluginRunner } from '../../types/pluginItem'; | ||
import { Response, WeatherParams, WeatherResult } from './type'; | ||
|
||
const weatherBaseURL = 'https://restapi.amap.com/v3/weather/weatherInfo'; | ||
|
||
const citySearchURL = 'https://restapi.amap.com/v3/config/district'; | ||
|
||
const KEY = process.env.GAODE_WEATHER_KEY; | ||
|
||
const fetchCityCode = async (keywords: string): Promise<string> => { | ||
const URL = `${citySearchURL}?keywords=${keywords}&subdistrict=0&extensions=base&key=${KEY}`; | ||
const res = await fetch(URL); | ||
|
||
const data = await res.json(); | ||
console.log(data); | ||
|
||
return data.districts[0].adcode; | ||
}; | ||
|
||
const fetchWeather: PluginRunner<WeatherParams, WeatherResult> = async ({ | ||
city, | ||
extensions = 'all', | ||
}) => { | ||
const cityCode = await fetchCityCode(city); | ||
|
||
const URL = `${weatherBaseURL}?city=${cityCode}&extensions=${extensions}&key=${KEY}`; | ||
const res = await fetch(URL); | ||
|
||
const data: Response = await res.json(); | ||
|
||
return data.forecasts; | ||
}; | ||
|
||
export default fetchWeather; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
export interface WeatherParams { | ||
city: string; | ||
extensions?: 'base' | 'all'; | ||
} | ||
export type WeatherResult = Forecast[]; | ||
|
||
export interface Response { | ||
count: string; | ||
forecasts: Forecast[]; | ||
info: string; | ||
infocode: string; | ||
status: string; | ||
} | ||
|
||
export interface Forecast { | ||
adcode: string; | ||
casts: Cast[]; | ||
city: string; | ||
province: string; | ||
reporttime: string; | ||
} | ||
|
||
export interface Cast { | ||
date: string; | ||
daypower: string; | ||
daytemp: string; | ||
daytemp_float: string; | ||
dayweather: string; | ||
daywind: string; | ||
nightpower: string; | ||
nighttemp: string; | ||
nighttemp_float: string; | ||
nightweather: string; | ||
nightwind: string; | ||
week: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { PluginItem } from '../../types/pluginItem'; | ||
import runner from './runner'; | ||
import { Result } from './type'; | ||
|
||
const schema = { | ||
description: '提取网页内容并总结', | ||
name: 'websiteCrawler', | ||
parameters: { | ||
properties: { | ||
url: { | ||
description: '网页内容', | ||
type: 'string', | ||
}, | ||
}, | ||
required: ['url'], | ||
type: 'object', | ||
}, | ||
}; | ||
|
||
const getWeather: PluginItem<Result> = { avatar: '🕸', name: 'websiteCrawler', runner, schema }; | ||
|
||
export default getWeather; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { PluginRunner } from '../../types/pluginItem'; | ||
import { ParserResponse, Result } from './type'; | ||
|
||
const BASE_URL = process.env.BROWSERLESS_URL ?? 'https://chrome.browserless.io'; | ||
const BROWSERLESS_TOKEN = process.env.BROWSERLESS_TOKEN; | ||
|
||
// service from: https://github.com/lobehub/html-parser/tree/master | ||
const HTML_PARSER_URL = process.env.HTML_PARSER_URL; | ||
|
||
const runner: PluginRunner<{ url: string }, Result> = async ({ url }) => { | ||
const input = { | ||
gotoOptions: { waitUntil: 'networkidle2' }, | ||
url, | ||
}; | ||
|
||
try { | ||
const res = await fetch(`${BASE_URL}/content?token=${BROWSERLESS_TOKEN}`, { | ||
body: JSON.stringify(input), | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
method: 'POST', | ||
}); | ||
const html = await res.text(); | ||
|
||
const parserBody = { html, url }; | ||
|
||
const parseRes = await fetch(`${HTML_PARSER_URL}`, { | ||
body: JSON.stringify(parserBody), | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
method: 'POST', | ||
}); | ||
|
||
const { title, textContent, siteName } = (await parseRes.json()) as ParserResponse; | ||
|
||
return { content: textContent, title, url, website: siteName }; | ||
} catch (error) { | ||
console.error(error); | ||
return { content: '抓取失败', errorMessage: (error as any).message, url }; | ||
} | ||
}; | ||
|
||
export default runner; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
export type Result = { | ||
content: string; | ||
title?: string; | ||
url: string; | ||
website?: string; | ||
}; | ||
|
||
export interface ParserResponse { | ||
/** author metadata */ | ||
byline: string; | ||
|
||
/** HTML string of processed article content */ | ||
content: string; | ||
|
||
/** content direction */ | ||
dir: string; | ||
|
||
/** article description, or short excerpt from the content */ | ||
excerpt: string; | ||
|
||
/** content language */ | ||
lang: string; | ||
|
||
/** length of an article, in characters */ | ||
length: number; | ||
|
||
/** name of the site */ | ||
siteName: string; | ||
|
||
/** text content of the article, with all the HTML tags removed */ | ||
textContent: string; | ||
|
||
/** article title */ | ||
title: string; | ||
} |
Oops, something went wrong.