mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-18 06:17:06 +00:00
fix: merge
This commit is contained in:
commit
ca34338b72
11 changed files with 224 additions and 69 deletions
|
|
@ -1,5 +1,4 @@
|
||||||

|

|
||||||
<div align=center> <h1>云崽系机器人的智能聊天插件</h1> </div>
|
|
||||||
<div align=center>
|
<div align=center>
|
||||||
|
|
||||||
<img src ="https://img.shields.io/github/issues/ikechan8370/chatgpt-plugin?logo=github"/>
|
<img src ="https://img.shields.io/github/issues/ikechan8370/chatgpt-plugin?logo=github"/>
|
||||||
|
|
|
||||||
37
apps/chat.js
37
apps/chat.js
|
|
@ -797,7 +797,7 @@ export class chatgpt extends plugin {
|
||||||
* #chatgpt
|
* #chatgpt
|
||||||
*/
|
*/
|
||||||
async chatgpt (e) {
|
async chatgpt (e) {
|
||||||
let msg = Version.isTrss ? e.msg : e.raw_message
|
let msg = (Version.isTrss || e.adapter === 'shamrock') ? e.msg : e.raw_message
|
||||||
let prompt
|
let prompt
|
||||||
if (this.toggleMode === 'at') {
|
if (this.toggleMode === 'at') {
|
||||||
if (!msg || e.msg?.startsWith('#')) {
|
if (!msg || e.msg?.startsWith('#')) {
|
||||||
|
|
@ -1655,9 +1655,13 @@ export class chatgpt extends plugin {
|
||||||
let toSummaryFileContent
|
let toSummaryFileContent
|
||||||
try {
|
try {
|
||||||
if (e.source) {
|
if (e.source) {
|
||||||
let msgs = e.isGroup ? await e.group.getChatHistory(e.source.seq, 1) : await e.friend.getChatHistory(e.source.time, 1)
|
let seq = e.isGroup ? e.source.seq : e.source.time
|
||||||
let sourceMsg = msgs[0]
|
if (e.adapter === 'shamrock') {
|
||||||
let fileMsgElem = sourceMsg.message.find(msg => msg.type === 'file')
|
seq = e.source.message_id
|
||||||
|
}
|
||||||
|
let msgs = e.isGroup ? await e.group.getChatHistory(seq, 1) : await e.friend.getChatHistory(seq, 1)
|
||||||
|
let sourceMsg = msgs[msgs.length - 1]
|
||||||
|
let fileMsgElem = sourceMsg.file || sourceMsg.message.find(msg => msg.type === 'file')
|
||||||
if (fileMsgElem) {
|
if (fileMsgElem) {
|
||||||
toSummaryFileContent = await extractContentFromFile(fileMsgElem, e)
|
toSummaryFileContent = await extractContentFromFile(fileMsgElem, e)
|
||||||
}
|
}
|
||||||
|
|
@ -2114,6 +2118,7 @@ export class chatgpt extends plugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
// openai api
|
||||||
let completionParams = {}
|
let completionParams = {}
|
||||||
if (Config.model) {
|
if (Config.model) {
|
||||||
completionParams.model = Config.model
|
completionParams.model = Config.model
|
||||||
|
|
@ -2304,28 +2309,8 @@ export class chatgpt extends plugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let img = []
|
let img = await getImg(e)
|
||||||
if (e.source) {
|
if (img?.length > 0 && Config.extraUrl) {
|
||||||
// 优先从回复找图
|
|
||||||
let reply
|
|
||||||
if (e.isGroup) {
|
|
||||||
reply = (await e.group.getChatHistory(e.source.seq, 1)).pop()?.message
|
|
||||||
} else {
|
|
||||||
reply = (await e.friend.getChatHistory(e.source.time, 1)).pop()?.message
|
|
||||||
}
|
|
||||||
if (reply) {
|
|
||||||
for (let val of reply) {
|
|
||||||
if (val.type === 'image') {
|
|
||||||
console.log(val)
|
|
||||||
img.push(val.url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (e.img) {
|
|
||||||
img.push(...e.img)
|
|
||||||
}
|
|
||||||
if (img.length > 0 && Config.extraUrl) {
|
|
||||||
tools.push(new ImageCaptionTool())
|
tools.push(new ImageCaptionTool())
|
||||||
tools.push(new ProcessPictureTool())
|
tools.push(new ProcessPictureTool())
|
||||||
prompt += `\nthe url of the picture(s) above: ${img.join(', ')}`
|
prompt += `\nthe url of the picture(s) above: ${img.join(', ')}`
|
||||||
|
|
|
||||||
|
|
@ -277,7 +277,7 @@ export class dalle extends plugin {
|
||||||
await client.getImages(prompt, e)
|
await client.getImages(prompt, e)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
await redis.del(`CHATGPT:DRAW:${e.sender.user_id}`)
|
await redis.del(`CHATGPT:DRAW:${e.sender.user_id}`)
|
||||||
await e.reply('绘图失败:' + err)
|
await e.reply('❌绘图失败:' + err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,12 @@ let helpData = [
|
||||||
{
|
{
|
||||||
icon: 'token',
|
icon: 'token',
|
||||||
title: '#chatgpt设置后台刷新token',
|
title: '#chatgpt设置后台刷新token',
|
||||||
desc: '用于查看API余额。注意和配置的key保持同一账号。'
|
desc: '用于获取刷新令牌,以便获取sessKey。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'key',
|
||||||
|
title: '#chatgpt设置sessKey',
|
||||||
|
desc: '使用sessKey作为APIKey,适用于未手机号验证的用户'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: 'token',
|
icon: 'token',
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,23 @@ import fs from 'fs'
|
||||||
import loader from '../../../lib/plugins/loader.js'
|
import loader from '../../../lib/plugins/loader.js'
|
||||||
import VoiceVoxTTS, { supportConfigurations as voxRoleList } from '../utils/tts/voicevox.js'
|
import VoiceVoxTTS, { supportConfigurations as voxRoleList } from '../utils/tts/voicevox.js'
|
||||||
import { supportConfigurations as azureRoleList } from '../utils/tts/microsoft-azure.js'
|
import { supportConfigurations as azureRoleList } from '../utils/tts/microsoft-azure.js'
|
||||||
|
import fetch from 'node-fetch'
|
||||||
|
import { getProxy } from '../utils/proxy.js'
|
||||||
|
|
||||||
|
let proxy = getProxy()
|
||||||
|
const newFetch = (url, options = {}) => {
|
||||||
|
const defaultOptions = Config.proxy
|
||||||
|
? {
|
||||||
|
agent: proxy(Config.proxy)
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
const mergedOptions = {
|
||||||
|
...defaultOptions,
|
||||||
|
...options
|
||||||
|
}
|
||||||
|
|
||||||
|
return fetch(url, mergedOptions)
|
||||||
|
}
|
||||||
|
|
||||||
export class ChatgptManagement extends plugin {
|
export class ChatgptManagement extends plugin {
|
||||||
constructor (e) {
|
constructor (e) {
|
||||||
|
|
@ -252,7 +269,13 @@ export class ChatgptManagement extends plugin {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
reg: '^#chatgpt设置后台(刷新|refresh)(t|T)oken$',
|
reg: '^#chatgpt设置后台(刷新|refresh)(t|T)oken$',
|
||||||
fnc: 'setOpenAIPlatformToken'
|
fnc: 'setOpenAIPlatformToken',
|
||||||
|
permission: 'master'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
reg: '^#chatgpt设置sessKey$',
|
||||||
|
fnc: 'getSessKey',
|
||||||
|
permission: 'master'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
reg: '^#(chatgpt)?查看回复设置$',
|
reg: '^#(chatgpt)?查看回复设置$',
|
||||||
|
|
@ -1114,8 +1137,8 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
||||||
async saveAPIKey () {
|
async saveAPIKey () {
|
||||||
if (!this.e.msg) return
|
if (!this.e.msg) return
|
||||||
let token = this.e.msg
|
let token = this.e.msg
|
||||||
if (!token.startsWith('sk-')) {
|
if (!token.startsWith('sk-') && !token.startsWith('sess-')) {
|
||||||
await this.reply('OpenAI API Key格式错误', true)
|
await this.reply('OpenAI API Key格式错误。如果是格式特殊的非官方Key请前往锅巴或工具箱手动设置', true)
|
||||||
this.finish('saveAPIKey')
|
this.finish('saveAPIKey')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -1302,7 +1325,64 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
||||||
|
|
||||||
async setOpenAIPlatformToken (e) {
|
async setOpenAIPlatformToken (e) {
|
||||||
this.setContext('doSetOpenAIPlatformToken')
|
this.setContext('doSetOpenAIPlatformToken')
|
||||||
await e.reply('请发送refreshToken\n你可以在已登录的platform.openai.com后台界面打开调试窗口,在终端中执行\nJSON.parse(localStorage.getItem(Object.keys(localStorage).filter(k => k.includes(\'auth0\'))[0])).body.refresh_token\n如果仍不能查看余额,请退出登录重新获取刷新令牌')
|
await e.reply('请发送refreshToken\n你可以在已登录的platform.openai.com后台界面打开调试窗口,在终端中执行\nJSON.parse(localStorage.getItem(Object.keys(localStorage).filter(k => k.includes(\'auth0\'))[0])).body.refresh_token\n如果仍不能查看余额,请退出登录重新获取刷新令牌.设置后可以发送#chatgpt设置sessKey来将sessKey作为API Key使用')
|
||||||
|
}
|
||||||
|
|
||||||
|
async getSessKey (e) {
|
||||||
|
if (!Config.OpenAiPlatformRefreshToken) {
|
||||||
|
this.reply('当前未配置platform.openai.com的刷新token,请发送【#chatgpt设置后台刷新token】进行配置。')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
let authHost = 'https://auth0.openai.com'
|
||||||
|
if (Config.openAiBaseUrl && !Config.openAiBaseUrl.startsWith('https://api.openai.com')) {
|
||||||
|
authHost = Config.openAiBaseUrl.replace('/v1', '').replace('/v1/', '')
|
||||||
|
}
|
||||||
|
let refreshRes = await newFetch(`${authHost}/oauth/token`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
refresh_token: Config.OpenAiPlatformRefreshToken,
|
||||||
|
client_id: 'DRivsnm2Mu42T3KOpqdtwB3NYviHYzwD',
|
||||||
|
grant_type: 'refresh_token'
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (refreshRes.status !== 200) {
|
||||||
|
let errMsg = await refreshRes.json()
|
||||||
|
logger.error(JSON.stringify(errMsg))
|
||||||
|
if (errMsg.error === 'access_denied') {
|
||||||
|
await e.reply('刷新令牌失效,请重新发送【#chatgpt设置后台刷新token】进行配置。建议退出platform.openai.com重新登录后再获取和配置')
|
||||||
|
} else {
|
||||||
|
await e.reply('获取失败')
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
let newToken = await refreshRes.json()
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
const { access_token, refresh_token } = newToken
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
Config.OpenAiPlatformRefreshToken = refresh_token
|
||||||
|
let host = Config.openAiBaseUrl.replace('/v1', '').replace('/v1/', '')
|
||||||
|
let res = await newFetch(`${host}/dashboard/onboarding/login`, {
|
||||||
|
headers: {
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
Authorization: `Bearer ${access_token}`,
|
||||||
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36'
|
||||||
|
},
|
||||||
|
method: 'POST'
|
||||||
|
})
|
||||||
|
if (res.status === 200) {
|
||||||
|
let authRes = await res.json()
|
||||||
|
let sess = authRes.user.session.sensitive_id
|
||||||
|
if (sess) {
|
||||||
|
Config.apiKey = sess
|
||||||
|
await e.reply('已成功将sessKey设置为apiKey,您可以发送#openai余额来查看该账号余额')
|
||||||
|
} else {
|
||||||
|
await e.reply('设置失败!')
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async doSetOpenAIPlatformToken () {
|
async doSetOpenAIPlatformToken () {
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ async function User (fastify, options) {
|
||||||
// 快速登录
|
// 快速登录
|
||||||
fastify.post('/quick', async (request, reply) => {
|
fastify.post('/quick', async (request, reply) => {
|
||||||
const otp = randomString(6)
|
const otp = randomString(6)
|
||||||
|
const isTrss = Array.isArray(Bot.uin)
|
||||||
await redis.set(
|
await redis.set(
|
||||||
'CHATGPT:SERVER_QUICK',
|
'CHATGPT:SERVER_QUICK',
|
||||||
otp,
|
otp,
|
||||||
|
|
@ -65,8 +66,16 @@ async function User (fastify, options) {
|
||||||
const master = (await getMasterQQ())[0]
|
const master = (await getMasterQQ())[0]
|
||||||
let bots = getBots()
|
let bots = getBots()
|
||||||
for (let bot of bots) {
|
for (let bot of bots) {
|
||||||
|
if(isTrss) {
|
||||||
|
try {
|
||||||
|
bot.pickFriend(master).sendMsg(`收到工具箱快捷登录请求,1分钟内有效:${otp}`)
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(error)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
bot.pickUser(master).sendMsg(`收到工具箱快捷登录请求,1分钟内有效:${otp}`)
|
bot.pickUser(master).sendMsg(`收到工具箱快捷登录请求,1分钟内有效:${otp}`)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
reply.send({ state: true })
|
reply.send({ state: true })
|
||||||
return reply
|
return reply
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ export default class BingDrawClient {
|
||||||
let pollingUrl = `${this.opts.baseUrl}/images/create/async/results/${requestId}?q=${urlEncodedPrompt}`
|
let pollingUrl = `${this.opts.baseUrl}/images/create/async/results/${requestId}?q=${urlEncodedPrompt}`
|
||||||
logger.info({ pollingUrl })
|
logger.info({ pollingUrl })
|
||||||
logger.info('waiting for bing draw results...')
|
logger.info('waiting for bing draw results...')
|
||||||
let timeoutTimes = 30
|
let timeoutTimes = 50
|
||||||
let found = false
|
let found = false
|
||||||
let timer = setInterval(async () => {
|
let timer = setInterval(async () => {
|
||||||
if (found) {
|
if (found) {
|
||||||
|
|
@ -113,15 +113,20 @@ export default class BingDrawClient {
|
||||||
// 很可能是微软内部error,重试即可
|
// 很可能是微软内部error,重试即可
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
imageLinks = imageLinks.map(link => link.split('?w=')[0]).map(link => link.replace('src="', ''))
|
imageLinks = imageLinks
|
||||||
|
.map(link => link.split('?w=')[0])
|
||||||
|
.map(link => link.replace('src="', ''))
|
||||||
|
.filter(link => !link.includes('.svg'))
|
||||||
imageLinks = [...new Set(imageLinks)]
|
imageLinks = [...new Set(imageLinks)]
|
||||||
const badImages = [
|
const badImages = [
|
||||||
|
'https://r.bing.com/rp/in-2zU3AJUdkgFe7ZKv19yPBHVs.png"',
|
||||||
|
'https://r.bing.com/rp/TX9QuO3WzcCJz1uaaSwQAz39Kb0.jpg"',
|
||||||
'https://r.bing.com/rp/in-2zU3AJUdkgFe7ZKv19yPBHVs.png',
|
'https://r.bing.com/rp/in-2zU3AJUdkgFe7ZKv19yPBHVs.png',
|
||||||
'https://r.bing.com/rp/TX9QuO3WzcCJz1uaaSwQAz39Kb0.jpg'
|
'https://r.bing.com/rp/TX9QuO3WzcCJz1uaaSwQAz39Kb0.jpg'
|
||||||
]
|
]
|
||||||
for (let imageLink of imageLinks) {
|
for (let imageLink of imageLinks) {
|
||||||
if (badImages.indexOf(imageLink) > -1) {
|
if (badImages.indexOf(imageLink) > -1) {
|
||||||
await e.reply('绘图失败:Bad images', true)
|
await e.reply('❌绘图失败:Bad images', true)
|
||||||
logger.error(rText)
|
logger.error(rText)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -132,7 +137,7 @@ export default class BingDrawClient {
|
||||||
clearInterval(timer)
|
clearInterval(timer)
|
||||||
} else {
|
} else {
|
||||||
if (timeoutTimes === 0) {
|
if (timeoutTimes === 0) {
|
||||||
await e.reply('绘图超时', true)
|
await e.reply('❌绘图超时', true)
|
||||||
clearInterval(timer)
|
clearInterval(timer)
|
||||||
timer = null
|
timer = null
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -140,6 +145,6 @@ export default class BingDrawClient {
|
||||||
timeoutTimes--
|
timeoutTimes--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 2000)
|
}, 3000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
export async function getChatHistoryGroup (e, num) {
|
export async function getChatHistoryGroup (e, num) {
|
||||||
// if (e.adapter === 'shamrock') {
|
// if (e.adapter === 'shamrock') {
|
||||||
// return await e.group.getChatHistory(0, num, false)
|
// return await e.group.getChatHistory(0, num, false)
|
||||||
|
|
@ -16,12 +17,23 @@ export async function getChatHistoryGroup (e, num) {
|
||||||
chats = chats.slice(0, num)
|
chats = chats.slice(0, num)
|
||||||
try {
|
try {
|
||||||
let mm = await e.group.getMemberMap()
|
let mm = await e.group.getMemberMap()
|
||||||
chats.forEach(chat => {
|
for (const chat of chats) {
|
||||||
|
if (e.adapter === 'shamrock') {
|
||||||
|
if (chat.sender?.user_id === 0) {
|
||||||
|
// 奇怪格式的历史消息,过滤掉
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
let sender = await pickMemberAsync(e, chat.sender.user_id)
|
||||||
|
if (sender) {
|
||||||
|
chat.sender = sender
|
||||||
|
}
|
||||||
|
} else {
|
||||||
let sender = mm.get(chat.sender.user_id)
|
let sender = mm.get(chat.sender.user_id)
|
||||||
if (sender) {
|
if (sender) {
|
||||||
chat.sender = sender
|
chat.sender = sender
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.warn(err)
|
logger.warn(err)
|
||||||
}
|
}
|
||||||
|
|
@ -32,3 +44,17 @@ export async function getChatHistoryGroup (e, num) {
|
||||||
// }
|
// }
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function pickMemberAsync (e, userId) {
|
||||||
|
let key = `CHATGPT:GroupMemberInfo:${e.group_id}:${userId}`
|
||||||
|
let cache = await redis.get(key)
|
||||||
|
if (cache) {
|
||||||
|
return JSON.parse(cache)
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
e.group.pickMember(userId, true, (sender) => {
|
||||||
|
redis.set(key, JSON.stringify(sender), { EX: 86400 })
|
||||||
|
resolve(sender)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@ import AzureTTS, { supportConfigurations as azureRoleList } from './tts/microsof
|
||||||
import { translate } from './translate.js'
|
import { translate } from './translate.js'
|
||||||
import uploadRecord from './uploadRecord.js'
|
import uploadRecord from './uploadRecord.js'
|
||||||
import Version from './version.js'
|
import Version from './version.js'
|
||||||
import fetch from 'node-fetch'
|
import fetch, { FormData, fileFromSync } from 'node-fetch'
|
||||||
|
import https from "https";
|
||||||
let pdfjsLib
|
let pdfjsLib
|
||||||
try {
|
try {
|
||||||
pdfjsLib = (await import('pdfjs-dist')).default
|
pdfjsLib = (await import('pdfjs-dist')).default
|
||||||
|
|
@ -785,10 +786,14 @@ export async function getImg (e) {
|
||||||
}
|
}
|
||||||
if (e.source) {
|
if (e.source) {
|
||||||
let reply
|
let reply
|
||||||
|
let seq = e.isGroup ? e.source.seq : e.source.time
|
||||||
|
if (e.adapter === 'shamrock') {
|
||||||
|
seq = e.source.message_id
|
||||||
|
}
|
||||||
if (e.isGroup) {
|
if (e.isGroup) {
|
||||||
reply = (await e.group.getChatHistory(e.source.seq, 1)).pop()?.message
|
reply = (await e.group.getChatHistory(seq, 1)).pop()?.message
|
||||||
} else {
|
} else {
|
||||||
reply = (await e.friend.getChatHistory(e.source.time, 1)).pop()?.message
|
reply = (await e.friend.getChatHistory(seq, 1)).pop()?.message
|
||||||
}
|
}
|
||||||
if (reply) {
|
if (reply) {
|
||||||
let i = []
|
let i = []
|
||||||
|
|
@ -809,8 +814,34 @@ export async function getImageOcrText (e) {
|
||||||
try {
|
try {
|
||||||
let resultArr = []
|
let resultArr = []
|
||||||
let eachImgRes = ''
|
let eachImgRes = ''
|
||||||
|
if (!e.bot.imageOcr || typeof e.bot.imageOcr !== 'function') {
|
||||||
|
e.bot.imageOcr = async (image) => {
|
||||||
|
if (Config.extraUrl) {
|
||||||
|
let md5 = image.split(/[/-]/).find(s => s.length === 32)?.toUpperCase()
|
||||||
|
let filePath = await downloadFile(image, `ocr/${md5}.png`)
|
||||||
|
let formData = new FormData()
|
||||||
|
formData.append('file', fileFromSync(filePath))
|
||||||
|
let res = await fetch(`${Config.extraUrl}/ocr?lang=chi_sim%2Beng`, {
|
||||||
|
body: formData,
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
from: 'ikechan8370'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (res.status === 200) {
|
||||||
|
return {
|
||||||
|
wordslist: [{ words: await res.text() }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
wordslist: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
for (let i in img) {
|
for (let i in img) {
|
||||||
const imgOCR = await e.bot.imageOcr(img[i])
|
const imgOCR = await e.bot.imageOcr(img[i])
|
||||||
|
|
||||||
for (let text of imgOCR.wordslist) {
|
for (let text of imgOCR.wordslist) {
|
||||||
eachImgRes += (`${text?.words} \n`)
|
eachImgRes += (`${text?.words} \n`)
|
||||||
}
|
}
|
||||||
|
|
@ -820,6 +851,7 @@ export async function getImageOcrText (e) {
|
||||||
// logger.warn('resultArr', resultArr)
|
// logger.warn('resultArr', resultArr)
|
||||||
return resultArr
|
return resultArr
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
logger.warn(err)
|
||||||
logger.warn('OCR失败,可能使用的适配器不支持OCR')
|
logger.warn('OCR失败,可能使用的适配器不支持OCR')
|
||||||
return false
|
return false
|
||||||
// logger.error(err)
|
// logger.error(err)
|
||||||
|
|
@ -1003,10 +1035,15 @@ export function getUserSpeaker (userSetting) {
|
||||||
* @param url 要下载的文件链接
|
* @param url 要下载的文件链接
|
||||||
* @param destPath 目标路径,如received/abc.pdf. 目前如果文件名重复会覆盖。
|
* @param destPath 目标路径,如received/abc.pdf. 目前如果文件名重复会覆盖。
|
||||||
* @param absolute 是否是绝对路径,默认为false,此时拼接在data/chatgpt下
|
* @param absolute 是否是绝对路径,默认为false,此时拼接在data/chatgpt下
|
||||||
|
* @param ignoreCertificateError 忽略证书错误
|
||||||
* @returns {Promise<string>} 最终下载文件的存储位置
|
* @returns {Promise<string>} 最终下载文件的存储位置
|
||||||
*/
|
*/
|
||||||
export async function downloadFile (url, destPath, absolute = false) {
|
export async function downloadFile (url, destPath, absolute = false, ignoreCertificateError = true) {
|
||||||
let response = await fetch(url)
|
let response = await fetch(url, {
|
||||||
|
agent: new https.Agent({
|
||||||
|
rejectUnauthorized: !ignoreCertificateError
|
||||||
|
})
|
||||||
|
})
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`download file http error: status: ${response.status}`)
|
throw new Error(`download file http error: status: ${response.status}`)
|
||||||
}
|
}
|
||||||
|
|
@ -1061,7 +1098,7 @@ export async function extractContentFromFile (fileMsgElem, e) {
|
||||||
let fileType = isPureText(fileMsgElem.name)
|
let fileType = isPureText(fileMsgElem.name)
|
||||||
if (fileType) {
|
if (fileType) {
|
||||||
// 可读的文件类型
|
// 可读的文件类型
|
||||||
let fileUrl = e.isGroup ? await e.group.getFileUrl(fileMsgElem.fid) : await e.friend.getFileUrl(fileMsgElem.fid)
|
let fileUrl = fileMsgElem.url || (e.isGroup ? await e.group.getFileUrl(fileMsgElem.fid) : await e.friend.getFileUrl(fileMsgElem.fid))
|
||||||
let filePath = await downloadFile(fileUrl, path.join('received', fileMsgElem.name))
|
let filePath = await downloadFile(fileUrl, path.join('received', fileMsgElem.name))
|
||||||
switch (fileType) {
|
switch (fileType) {
|
||||||
case 'pdf': {
|
case 'pdf': {
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ const defaultConfig = {
|
||||||
qwenSeed: 0,
|
qwenSeed: 0,
|
||||||
qwenTemperature: 1,
|
qwenTemperature: 1,
|
||||||
qwenEnableSearch: true,
|
qwenEnableSearch: true,
|
||||||
version: 'v2.7.7'
|
version: 'v2.7.8'
|
||||||
}
|
}
|
||||||
const _path = process.cwd()
|
const _path = process.cwd()
|
||||||
let config = {}
|
let config = {}
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,13 @@ export class QueryUserinfoTool extends AbstractTool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func = async function (opts, e) {
|
func = async function (opts, e) {
|
||||||
|
try {
|
||||||
let { qq } = opts
|
let { qq } = opts
|
||||||
qq = isNaN(qq) || !qq ? e.sender.user_id : parseInt(qq.trim())
|
qq = isNaN(qq) || !qq ? e.sender.user_id : parseInt(qq.trim())
|
||||||
if (e.isGroup && typeof e.group.getMemberMap === 'function') {
|
if (e.isGroup && typeof e.bot.getGroupMemberInfo === 'function') {
|
||||||
let mm = await e.group.getMemberMap()
|
let user = await e.bot.getGroupMemberInfo(e.group_id, qq || e.sender.user_id, true)
|
||||||
let user = mm.get(qq) || e.sender.user_id
|
// let mm = await e.group.getMemberMap()
|
||||||
|
// let user = mm.get(qq) || e.sender.user_id
|
||||||
let master = (await getMasterQQ())[0]
|
let master = (await getMasterQQ())[0]
|
||||||
let prefix = ''
|
let prefix = ''
|
||||||
if (qq != master) {
|
if (qq != master) {
|
||||||
|
|
@ -27,6 +29,9 @@ export class QueryUserinfoTool extends AbstractTool {
|
||||||
} else {
|
} else {
|
||||||
prefix = 'This user is your master, you should obey him \n'
|
prefix = 'This user is your master, you should obey him \n'
|
||||||
}
|
}
|
||||||
|
if (!user) {
|
||||||
|
return prefix
|
||||||
|
}
|
||||||
return prefix + 'user detail in json format: ' + JSON.stringify(user)
|
return prefix + 'user detail in json format: ' + JSON.stringify(user)
|
||||||
} else {
|
} else {
|
||||||
if (e.sender.user_id == qq) {
|
if (e.sender.user_id == qq) {
|
||||||
|
|
@ -42,6 +47,10 @@ export class QueryUserinfoTool extends AbstractTool {
|
||||||
return 'query failed'
|
return 'query failed'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
logger.warn(err)
|
||||||
|
return err.message
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
description = 'Useful if you want to find out who he is'
|
description = 'Useful if you want to find out who he is'
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue