mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-18 06:17:06 +00:00
fix: 加个天气小工具
This commit is contained in:
parent
39478d2928
commit
e192e51ef2
7 changed files with 104 additions and 30 deletions
|
|
@ -55,6 +55,7 @@ import { SearchVideoTool } from '../utils/tools/SearchBilibiliTool.js'
|
||||||
import { SearchMusicTool } from '../utils/tools/SearchMusicTool.js'
|
import { SearchMusicTool } from '../utils/tools/SearchMusicTool.js'
|
||||||
import { QueryStarRailTool } from '../utils/tools/QueryStarRailTool.js'
|
import { QueryStarRailTool } from '../utils/tools/QueryStarRailTool.js'
|
||||||
import { WebsiteTool } from '../utils/tools/WebsiteTool.js'
|
import { WebsiteTool } from '../utils/tools/WebsiteTool.js'
|
||||||
|
import {WeatherTool} from "../utils/tools/WeatherTool.js";
|
||||||
try {
|
try {
|
||||||
await import('emoji-strip')
|
await import('emoji-strip')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
@ -1938,7 +1939,8 @@ export class chatgpt extends plugin {
|
||||||
new QueryStarRailTool(),
|
new QueryStarRailTool(),
|
||||||
new WebsiteTool(),
|
new WebsiteTool(),
|
||||||
new JinyanTool(),
|
new JinyanTool(),
|
||||||
new KickOutTool()
|
new KickOutTool(),
|
||||||
|
new WeatherTool()
|
||||||
]
|
]
|
||||||
// if (e.sender.role === 'admin' || e.sender.role === 'owner') {
|
// if (e.sender.role === 'admin' || e.sender.role === 'owner') {
|
||||||
// tools.push(...[new JinyanTool(), new KickOutTool()])
|
// tools.push(...[new JinyanTool(), new KickOutTool()])
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,8 @@ ${translateLangLabels}
|
||||||
await e.reply('请在群里发送此命令')
|
await e.reply('请在群里发送此命令')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async wordcloud_latest(e) {
|
|
||||||
|
async wordcloud_latest (e) {
|
||||||
if (e.isGroup) {
|
if (e.isGroup) {
|
||||||
let groupId = e.group_id
|
let groupId = e.group_id
|
||||||
let lock = await redis.get(`CHATGPT:WORDCLOUD:${groupId}`)
|
let lock = await redis.get(`CHATGPT:WORDCLOUD:${groupId}`)
|
||||||
|
|
@ -216,13 +217,13 @@ ${translateLangLabels}
|
||||||
const match = e.msg.trim().match(regExp)
|
const match = e.msg.trim().match(regExp)
|
||||||
const duration = !match[1] ? 12 : parseInt(match[1]) // default 12h
|
const duration = !match[1] ? 12 : parseInt(match[1]) // default 12h
|
||||||
|
|
||||||
if(duration > 24) {
|
if (duration > 24) {
|
||||||
await e.reply('最多只能统计24小时内的记录哦')
|
await e.reply('最多只能统计24小时内的记录哦')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
await e.reply('在统计啦,请稍等...')
|
await e.reply('在统计啦,请稍等...')
|
||||||
|
|
||||||
await redis.set(`CHATGPT:WORDCLOUD:${groupId}`, '1', {EX: 600})
|
await redis.set(`CHATGPT:WORDCLOUD:${groupId}`, '1', { EX: 600 })
|
||||||
try {
|
try {
|
||||||
await makeWordcloud(e, e.group_id, duration)
|
await makeWordcloud(e, e.group_id, duration)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
@ -476,8 +477,8 @@ ${translateLangLabels}
|
||||||
let url = e.msg.replace(/^#url(:|:)/, '')
|
let url = e.msg.replace(/^#url(:|:)/, '')
|
||||||
if (url.length === 0) { return false }
|
if (url.length === 0) { return false }
|
||||||
try {
|
try {
|
||||||
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
if (!url.startsWith('http://') && !url.startsWith('https://')) {
|
||||||
url = "http://" + url
|
url = 'http://' + url
|
||||||
}
|
}
|
||||||
let urlLink = new URL(url)
|
let urlLink = new URL(url)
|
||||||
await e.reply(
|
await e.reply(
|
||||||
|
|
|
||||||
|
|
@ -788,6 +788,12 @@ export function supportGuoba () {
|
||||||
label: 'Live2D模型',
|
label: 'Live2D模型',
|
||||||
bottomHelpMessage: '选择Live2D使用的模型',
|
bottomHelpMessage: '选择Live2D使用的模型',
|
||||||
component: 'Input'
|
component: 'Input'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'amapKey',
|
||||||
|
label: '高德APIKey',
|
||||||
|
bottomHelpMessage: '用于查询天气',
|
||||||
|
component: 'Input'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
// 获取配置数据方法(用于前端填充显示数据)
|
// 获取配置数据方法(用于前端填充显示数据)
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,7 @@ const defaultConfig = {
|
||||||
enhanceAzureTTSEmotion: false,
|
enhanceAzureTTSEmotion: false,
|
||||||
autoJapanese: false,
|
autoJapanese: false,
|
||||||
enableGenerateContents: false,
|
enableGenerateContents: false,
|
||||||
|
amapKey: '',
|
||||||
version: 'v2.6.2'
|
version: 'v2.6.2'
|
||||||
}
|
}
|
||||||
const _path = process.cwd()
|
const _path = process.cwd()
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ export class JinyanTool extends AbstractTool {
|
||||||
},
|
},
|
||||||
time: {
|
time: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: '禁言时长,单位为秒'
|
description: '禁言时长,单位为秒,默认为600'
|
||||||
},
|
},
|
||||||
isPunish: {
|
isPunish: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
|
|
||||||
32
utils/tools/WeatherTool.js
Normal file
32
utils/tools/WeatherTool.js
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { AbstractTool } from './AbstractTool.js'
|
||||||
|
import {Config} from "../config.js";
|
||||||
|
|
||||||
|
export class WeatherTool extends AbstractTool {
|
||||||
|
name = 'weather'
|
||||||
|
|
||||||
|
parameters = {
|
||||||
|
properties: {
|
||||||
|
city: {
|
||||||
|
type: 'string',
|
||||||
|
description: '要查询的地点,细化到县/区级'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
required: ['city']
|
||||||
|
}
|
||||||
|
|
||||||
|
func = async function (opts) {
|
||||||
|
let { city } = opts
|
||||||
|
let key = Config.amapKey
|
||||||
|
|
||||||
|
let adcodeRes = await fetch(`https://restapi.amap.com/v3/config/district?keywords=${city}&subdistrict=1&key=${key}`)
|
||||||
|
adcodeRes = await adcodeRes.json()
|
||||||
|
let adcode = adcodeRes.districts[0].adcode
|
||||||
|
let cityName = adcodeRes.districts[0].name
|
||||||
|
let res = await fetch(`https://restapi.amap.com/v3/weather/weatherInfo?city=${adcode}&key=${key}`)
|
||||||
|
res = await res.json()
|
||||||
|
let result = res.lives[0]
|
||||||
|
return `the weather information of area ${cityName} in json format is:\n${JSON.stringify(result)}`
|
||||||
|
}
|
||||||
|
|
||||||
|
description = 'Useful when you want to query weather '
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
import { AbstractTool } from './AbstractTool.js'
|
import { AbstractTool } from './AbstractTool.js'
|
||||||
|
import { ChatGPTAPI } from '../openai/chatgpt-api.js'
|
||||||
|
import { Config } from '../config.js'
|
||||||
|
import fetch from 'node-fetch'
|
||||||
|
import proxy from 'https-proxy-agent'
|
||||||
|
import { getMaxModelTokens } from '../common.js'
|
||||||
export class WebsiteTool extends AbstractTool {
|
export class WebsiteTool extends AbstractTool {
|
||||||
name = 'website'
|
name = 'website'
|
||||||
|
|
||||||
|
|
@ -15,14 +19,42 @@ export class WebsiteTool extends AbstractTool {
|
||||||
|
|
||||||
func = async function (opts) {
|
func = async function (opts) {
|
||||||
let { url } = opts
|
let { url } = opts
|
||||||
|
try {
|
||||||
let res = await fetch(url, {
|
let res = await fetch(url, {
|
||||||
headers: {
|
headers: {
|
||||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
let text = await res.text()
|
let text = await res.text()
|
||||||
text = text.slice(0, Math.min(text.length, 4000))
|
let maxModelTokens = getMaxModelTokens(Config.model)
|
||||||
return `this is part of the content of website:\n ${text}`
|
text = text.slice(0, Math.min(text.length, maxModelTokens - 1600))
|
||||||
|
let api = new ChatGPTAPI({
|
||||||
|
apiBaseUrl: Config.openAiBaseUrl,
|
||||||
|
apiKey: Config.apiKey,
|
||||||
|
debug: false,
|
||||||
|
completionParams: {
|
||||||
|
model: Config.model
|
||||||
|
},
|
||||||
|
fetch: (url, options = {}) => {
|
||||||
|
const defaultOptions = Config.proxy
|
||||||
|
? {
|
||||||
|
agent: proxy(Config.proxy)
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
const mergedOptions = {
|
||||||
|
...defaultOptions,
|
||||||
|
...options
|
||||||
|
}
|
||||||
|
return fetch(url, mergedOptions)
|
||||||
|
},
|
||||||
|
maxModelTokens
|
||||||
|
})
|
||||||
|
const htmlContentSummaryRes = await api.sendMessage(`这是一个网页html的内容,请你从中提取出其中的主体内容告诉我。${text}`)
|
||||||
|
let htmlContentSummary = htmlContentSummaryRes.text
|
||||||
|
return `this is the main content of website:\n ${htmlContentSummary}`
|
||||||
|
} catch (err) {
|
||||||
|
return `failed to visit the website, error: ${err.toString()}`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
description = 'Useful when you want to browse a website by url'
|
description = 'Useful when you want to browse a website by url'
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue