mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-16 21:37:11 +00:00
feat: 新增对tool支持的相关接口 (#495)
* 修复后台API反代地址未能正确显示的问题 * 更新渲染页面配置 * 添加个人聊天模式配置 * 将用户数据获取改到common中 * 修复错误的渲染页面参数 * 修复bug * 添加Live2D * 修复渲染页面错误 * 修复渲染传入值 * 更新渲染 * 修复图表渲染bug * 调整live2d模型大小 * 修复live2d无法关闭问题 * 修复错误的传值 * 修复ai命名 * 更新渲染 * 添加用户独立设定 * 更新渲染配置适配个人设置 * 修复合并导致的渲染文件异常删除 * 修复用户数据缺失问题 * 修复旧版本数据缺失问题 * 修复bing参数不存在问题,兼容miao的截图 * 修复受限token重试时不被排除的问题 * 修复个人模式下结束对话的模式错误 * 更新渲染页面,将预览版转为正式版 * 修复传统渲染无法调用截图功能的问题 * 文字模式也进行一次缓存 * 更新README * Update README.md * 更新渲染 * 更新渲染页面 * 添加版本信息 * 遗漏参数 * 丢失引用 * 补充路由 * 添加云转码功能 * 判断node-silk是否正常合成 * 云转码提示 * 修复图片渲染出错 * 云转码支持发送Buffer * 添加云转码模式支持 * 更新描述 * 更新后台渲染页面 * 更新配置 * 更新渲染页面 * 添加云渲染 * 修复错误的接口调用 * 修复遗漏的数据转换 * 修复获取的图片数据异常问题 * 更新后台配置 * 更新渲染页面 * 修复云渲染访问地址错误 * 更新渲染页面 * 修复遗漏的模型文件 * 修复live2d问题 * 更新live2d以及相关配置 * 修复遗漏的数据参数 * 修复新live2d情况下云渲染错误的问题 * 适配云渲染1.1.2等待参数 * 添加云服务api检查 * 更新渲染页面 * 添加live2d加载检测 * 修复错误的属性判断 * 添加云渲染DPR * 更新sydney支持内容生成 * 修改文件模式语音转码接收模式 * 添加云转码时recordUrl检查 * 更新后台配置项 * 修复错误的文本描述 * 更新后台页面 * 添加全局对话模式设置,更新后台面板 * 添加第三方渲染服务适配 * 修复第三方服务器live2d加载导致的渲染失败问题 * 修复后台地址无法实时保存的问题 * 添加live2d模型透明度设置 * 合并更新 * 更新渲染页面 * 更新渲染页面 * 使dpr对本地渲染也生效 * 更新渲染页面 * 添加网页截图功能 * 添加后台配置项 * 添加配置导出和导入功能 * 运行通过参数传递用户token * 登录时将token作为参数返回 * 修复错误 * 添加密码修改和用户删除接口 * 修正密码比对 * 修复user错误 * 优化数据保存时的返回值 * 添加系统额外服务检查api * 添加AccessToken配置 * 修复错误的导入提示 * 添加ws连接 * 添加ws用户信息获取 * 修复错误的循环 * 修正ws参数 * 添加群消息获取权限 * 添加用户多端登录支持 * 修复错误的路径引用 * 修复错误的路径引用 * 修复错误 * 修复页面数据获取失败问题 * 修复异常的中断 * 添加配置视图 * 更新配置面板 * 添加用户版本信息 * 更新配置视图 * 修复错误的视图绑定 * 修改视图文件位置,添加mediaLink相关代码 --------- Co-authored-by: ikechan8370 <geyinchibuaa@gmail.com>
This commit is contained in:
parent
2443ed6f71
commit
ca3788d719
5 changed files with 1169 additions and 67 deletions
|
|
@ -21,7 +21,7 @@ import VoiceVoxTTS, { supportConfigurations as voxRoleList } from '../utils/tts/
|
|||
import { supportConfigurations as azureRoleList } from '../utils/tts/microsoft-azure.js'
|
||||
|
||||
export class ChatgptManagement extends plugin {
|
||||
constructor (e) {
|
||||
constructor(e) {
|
||||
super({
|
||||
name: 'ChatGPT-Plugin 管理',
|
||||
dsc: '插件的管理项配置,让你轻松掌控各个功能的开闭和管理。包含各种实用的配置选项,让你的聊天更加便捷和高效!',
|
||||
|
|
@ -251,7 +251,7 @@ export class ChatgptManagement extends plugin {
|
|||
})
|
||||
}
|
||||
|
||||
async viewUserSetting (e) {
|
||||
async viewUserSetting(e) {
|
||||
const userSetting = await getUserReplySetting(this.e)
|
||||
const replyMsg = `${this.e.sender.user_id}的回复设置:
|
||||
图片模式: ${userSetting.usePicture === true ? '开启' : '关闭'}
|
||||
|
|
@ -264,7 +264,7 @@ ${userSetting.useTTS === true ? '当前语音模式为' + Config.ttsMode : ''}`
|
|||
return true
|
||||
}
|
||||
|
||||
async getTTSRoleList (e) {
|
||||
async getTTSRoleList(e) {
|
||||
const matchCommand = e.msg.match(/^#(chatgpt)?(vits|azure|vox)?语音(服务|角色列表)/)
|
||||
if (matchCommand[3] === '服务') {
|
||||
await this.reply(`当前支持vox、vits、azure语音服务,可使用'#(vox|azure|vits)语音角色列表'查看支持的语音角色。
|
||||
|
|
@ -315,7 +315,7 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
await this.reply(roleList)
|
||||
}
|
||||
|
||||
async ttsSwitch (e) {
|
||||
async ttsSwitch(e) {
|
||||
let userReplySetting = await getUserReplySetting(this.e)
|
||||
if (!userReplySetting.useTTS) {
|
||||
let replyMsg
|
||||
|
|
@ -342,11 +342,11 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
return false
|
||||
}
|
||||
|
||||
async commandHelp (e) {
|
||||
async commandHelp(e) {
|
||||
if (/^#(chatgpt)?指令表帮助$/.exec(e.msg.trim())) {
|
||||
await this.reply('#chatgpt指令表: 查看本插件的所有指令\n' +
|
||||
'#chatgpt(对话|管理|娱乐|绘图|人物设定|聊天记录)指令表: 查看对应功能分类的指令表\n' +
|
||||
'#chatgpt指令表搜索xxx: 查看包含对应关键词的指令')
|
||||
'#chatgpt(对话|管理|娱乐|绘图|人物设定|聊天记录)指令表: 查看对应功能分类的指令表\n' +
|
||||
'#chatgpt指令表搜索xxx: 查看包含对应关键词的指令')
|
||||
return false
|
||||
}
|
||||
const categories = {
|
||||
|
|
@ -358,7 +358,7 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
聊天记录: '聊天记录'
|
||||
}
|
||||
|
||||
function getCategory (e, plugin) {
|
||||
function getCategory(e, plugin) {
|
||||
for (const key in categories) {
|
||||
if (e.msg.includes(key) && plugin.name.includes(categories[key])) {
|
||||
return '功能名称: '
|
||||
|
|
@ -423,13 +423,133 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
return true
|
||||
}
|
||||
|
||||
async enablePrivateChat (e) {
|
||||
async setList(e) {
|
||||
this.setContext('saveList')
|
||||
isWhiteList = e.msg.includes('白')
|
||||
const listType = isWhiteList ? '对话白名单' : '对话黑名单'
|
||||
await this.reply(`请发送需要添加的${listType}号码,默认设置为添加群号,需要添加QQ号时在前面添加^(例如:^123456)。`, e.isGroup)
|
||||
return false
|
||||
}
|
||||
|
||||
async saveList(e) {
|
||||
if (!this.e.msg) return
|
||||
const listType = isWhiteList ? '对话白名单' : '对话黑名单'
|
||||
const regex = /^\^?[1-9]\d{5,9}$/
|
||||
const wrongInput = []
|
||||
const inputSet = new Set()
|
||||
const inputList = this.e.msg.split(/[,,]/).reduce((acc, value) => {
|
||||
if (value.length > 11 || !regex.test(value)) {
|
||||
wrongInput.push(value)
|
||||
} else if (!inputSet.has(value)) {
|
||||
inputSet.add(value)
|
||||
acc.push(value)
|
||||
}
|
||||
return acc
|
||||
}, [])
|
||||
if (!inputList.length) {
|
||||
let replyMsg = '名单更新失败,请在检查输入是否正确后重新输入。'
|
||||
if (wrongInput.length) replyMsg += `\n${wrongInput.length ? '检测到以下错误输入:"' + wrongInput.join(',') + '",已自动忽略。' : ''}`
|
||||
await this.reply(replyMsg, e.isGroup)
|
||||
return false
|
||||
}
|
||||
let [whitelist, blacklist] = processList(Config.whitelist, Config.blacklist)
|
||||
whitelist = [...inputList, ...whitelist]
|
||||
blacklist = [...inputList, ...blacklist]
|
||||
if (listType === '对话白名单') {
|
||||
Config.whitelist = Array.from(new Set(whitelist))
|
||||
} else {
|
||||
Config.blacklist = Array.from(new Set(blacklist))
|
||||
}
|
||||
let replyMsg = `${listType}已更新,可通过\n"#chatgpt查看${listType}" 查看最新名单\n"#chatgpt移除${listType}" 管理名单${wrongInput.length ? '\n检测到以下错误输入:"' + wrongInput.join(',') + '",已自动忽略。' : ''}`
|
||||
if (e.isPrivate) {
|
||||
replyMsg += `\n当前${listType}为:${listType === '对话白名单' ? Config.whitelist : Config.blacklist}`
|
||||
}
|
||||
await this.reply(replyMsg, e.isGroup)
|
||||
this.finish('saveList')
|
||||
}
|
||||
|
||||
async checkList(e) {
|
||||
if (e.msg.includes('帮助')) {
|
||||
await this.reply('默认设置为添加群号,需要拉黑QQ号时在前面添加^(例如:^123456),可一次性混合输入多个配置号码,错误项会自动忽略。具体使用指令可通过 "#指令表搜索名单" 查看,白名单优先级高于黑名单。')
|
||||
return true
|
||||
}
|
||||
isWhiteList = e.msg.includes('白')
|
||||
const list = isWhiteList ? Config.whitelist : Config.blacklist
|
||||
const listType = isWhiteList ? '白名单' : '黑名单'
|
||||
const replyMsg = list.length ? `当前${listType}为:${list}` : `当前没有设置任何${listType}`
|
||||
await this.reply(replyMsg, e.isGroup)
|
||||
return false
|
||||
}
|
||||
|
||||
async delList(e) {
|
||||
isWhiteList = e.msg.includes('白')
|
||||
const listType = isWhiteList ? '对话白名单' : '对话黑名单'
|
||||
let replyMsg = ''
|
||||
if (Config.whitelist.length === 0 && Config.blacklist.length === 0) {
|
||||
replyMsg = '当前对话(白|黑)名单都是空哒,请先添加吧~'
|
||||
} else if ((listType === '对话白名单' && !Config.whitelist.length) || (listType === '对话黑名单' && !Config.blacklist.length)) {
|
||||
replyMsg = `当前${listType}为空,请先添加吧~`
|
||||
}
|
||||
if (replyMsg) {
|
||||
await this.reply(replyMsg, e.isGroup)
|
||||
return false
|
||||
}
|
||||
this.setContext('confirmDelList')
|
||||
await this.reply(`请发送需要删除的${listType}号码,号码间使用,隔开。输入‘全部删除’清空${listType}。${e.isPrivate ? '\n当前' + listType + '为:' + (listType === '对话白名单' ? Config.whitelist : Config.blacklist) : ''}`, e.isGroup)
|
||||
return false
|
||||
}
|
||||
|
||||
async confirmDelList(e) {
|
||||
if (!this.e.msg) return
|
||||
const isAllDeleted = this.e.msg.trim() === '全部删除'
|
||||
const regex = /^\^?[1-9]\d{5,9}$/
|
||||
const wrongInput = []
|
||||
const inputSet = new Set()
|
||||
const inputList = this.e.msg.split(/[,,]/).reduce((acc, value) => {
|
||||
if (value.length > 11 || !regex.test(value)) {
|
||||
wrongInput.push(value)
|
||||
} else if (!inputSet.has(value)) {
|
||||
inputSet.add(value)
|
||||
acc.push(value)
|
||||
}
|
||||
return acc
|
||||
}, [])
|
||||
if (!inputList.length && !isAllDeleted) {
|
||||
let replyMsg = '名单更新失败,请在检查输入是否正确后重新输入。'
|
||||
if (wrongInput.length) replyMsg += `${wrongInput.length ? '\n检测到以下错误输入:"' + wrongInput.join(',') + '",已自动忽略。' : ''}`
|
||||
await this.reply(replyMsg, e.isGroup)
|
||||
return false
|
||||
}
|
||||
let [whitelist, blacklist] = processList(Config.whitelist, Config.blacklist)
|
||||
if (isAllDeleted) {
|
||||
Config.whitelist = isWhiteList ? [] : whitelist
|
||||
Config.blacklist = !isWhiteList ? [] : blacklist
|
||||
} else {
|
||||
for (const element of inputList) {
|
||||
if (isWhiteList) {
|
||||
Config.whitelist = whitelist.filter(item => item !== element)
|
||||
} else {
|
||||
Config.blacklist = blacklist.filter(item => item !== element)
|
||||
}
|
||||
}
|
||||
}
|
||||
const listType = isWhiteList ? '对话白名单' : '对话黑名单'
|
||||
let replyMsg = `${listType}已更新,可通过 "#chatgpt查看${listType}" 命令查看最新名单${wrongInput.length ? '\n检测到以下错误输入:"' + wrongInput.join(',') + '",已自动忽略。' : ''}`
|
||||
if (e.isPrivate) {
|
||||
const list = isWhiteList ? Config.whitelist : Config.blacklist
|
||||
replyMsg = list.length ? `\n当前${listType}为:${list}` : `当前没有设置任何${listType}`
|
||||
}
|
||||
await this.reply(replyMsg, e.isGroup)
|
||||
this.finish('confirmDelList')
|
||||
}
|
||||
|
||||
async enablePrivateChat(e) {
|
||||
Config.enablePrivateChat = !!e.msg.match(/(允许|打开|同意)/)
|
||||
await this.reply('设置成功', e.isGroup)
|
||||
return false
|
||||
}
|
||||
|
||||
async enableGroupContext (e) {
|
||||
async enableGroupContext(e) {
|
||||
const reg = /(关闭|打开)/
|
||||
const match = e.msg.match(reg)
|
||||
if (match) {
|
||||
|
|
@ -445,7 +565,7 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
return false
|
||||
}
|
||||
|
||||
async setDefaultReplySetting (e) {
|
||||
async setDefaultReplySetting(e) {
|
||||
const reg = /^#chatgpt(打开|关闭|设置)?全局((文本模式|图片模式|语音模式|((azure|vits|vox)?语音角色|角色语音|角色)(.*))|回复帮助)/
|
||||
const matchCommand = e.msg.match(reg)
|
||||
const settingType = matchCommand[2]
|
||||
|
|
@ -578,31 +698,31 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
await this.reply(replyMsg, true)
|
||||
}
|
||||
|
||||
async turnOnConfirm (e) {
|
||||
async turnOnConfirm(e) {
|
||||
await redis.set('CHATGPT:CONFIRM', 'on')
|
||||
await this.reply('已开启消息确认', true)
|
||||
return false
|
||||
}
|
||||
|
||||
async turnOffConfirm (e) {
|
||||
async turnOffConfirm(e) {
|
||||
await redis.set('CHATGPT:CONFIRM', 'off')
|
||||
await this.reply('已关闭消息确认', true)
|
||||
return false
|
||||
}
|
||||
|
||||
async setAccessToken (e) {
|
||||
async setAccessToken(e) {
|
||||
this.setContext('saveToken')
|
||||
await this.reply('请发送ChatGPT AccessToken', true)
|
||||
return false
|
||||
}
|
||||
|
||||
async setPoeCookie () {
|
||||
async setPoeCookie() {
|
||||
this.setContext('savePoeToken')
|
||||
await this.reply('请发送Poe Cookie', true)
|
||||
return false
|
||||
}
|
||||
|
||||
async savePoeToken (e) {
|
||||
async savePoeToken(e) {
|
||||
if (!this.e.msg) return
|
||||
let token = this.e.msg
|
||||
if (!token.startsWith('p-b=')) {
|
||||
|
|
@ -615,13 +735,13 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
this.finish('savePoeToken')
|
||||
}
|
||||
|
||||
async setBingAccessToken (e) {
|
||||
async setBingAccessToken(e) {
|
||||
this.setContext('saveBingToken')
|
||||
await this.reply('请发送Bing Cookie Token.("_U" cookie from bing.com)', true)
|
||||
return false
|
||||
}
|
||||
|
||||
async migrateBingAccessToken () {
|
||||
async migrateBingAccessToken() {
|
||||
let token = await redis.get('CHATGPT:BING_TOKEN')
|
||||
if (token) {
|
||||
token = token.split('|')
|
||||
|
|
@ -645,27 +765,27 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
await this.reply('迁移完成', true)
|
||||
}
|
||||
|
||||
async getBingAccessToken (e) {
|
||||
async getBingAccessToken(e) {
|
||||
let tokens = await redis.get('CHATGPT:BING_TOKENS')
|
||||
if (tokens) tokens = JSON.parse(tokens)
|
||||
else tokens = []
|
||||
tokens = tokens.length > 0
|
||||
? tokens.map((item, index) => (
|
||||
`【${index}】 Token:${item.Token.substring(0, 5 / 2) + '...' + item.Token.substring(item.Token.length - 5 / 2, item.Token.length)}`
|
||||
`【${index}】 Token:${item.Token.substring(0, 5 / 2) + '...' + item.Token.substring(item.Token.length - 5 / 2, item.Token.length)}`
|
||||
)).join('\n')
|
||||
: '无必应Token记录'
|
||||
await this.reply(`${tokens}`, true)
|
||||
return false
|
||||
}
|
||||
|
||||
async delBingAccessToken (e) {
|
||||
async delBingAccessToken(e) {
|
||||
this.setContext('deleteBingToken')
|
||||
let tokens = await redis.get('CHATGPT:BING_TOKENS')
|
||||
if (tokens) tokens = JSON.parse(tokens)
|
||||
else tokens = []
|
||||
tokens = tokens.length > 0
|
||||
? tokens.map((item, index) => (
|
||||
`【${index}】 Token:${item.Token.substring(0, 5 / 2) + '...' + item.Token.substring(item.Token.length - 5 / 2, item.Token.length)}`
|
||||
`【${index}】 Token:${item.Token.substring(0, 5 / 2) + '...' + item.Token.substring(item.Token.length - 5 / 2, item.Token.length)}`
|
||||
)).join('\n')
|
||||
: '无必应Token记录'
|
||||
await this.reply(`请发送要删除的token编号\n${tokens}`, true)
|
||||
|
|
@ -673,7 +793,7 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
return false
|
||||
}
|
||||
|
||||
async saveBingToken () {
|
||||
async saveBingToken() {
|
||||
if (!this.e.msg) return
|
||||
let token = this.e.msg
|
||||
if (token.length < 100) {
|
||||
|
|
@ -730,7 +850,7 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
this.finish('saveBingToken')
|
||||
}
|
||||
|
||||
async deleteBingToken () {
|
||||
async deleteBingToken() {
|
||||
if (!this.e.msg) return
|
||||
let tokenId = this.e.msg
|
||||
if (await redis.exists('CHATGPT:BING_TOKENS') != 0) {
|
||||
|
|
@ -751,7 +871,7 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
}
|
||||
}
|
||||
|
||||
async saveToken () {
|
||||
async saveToken() {
|
||||
if (!this.e.msg) return
|
||||
let token = this.e.msg
|
||||
if (!token.startsWith('ey') || token.length < 20) {
|
||||
|
|
@ -764,12 +884,12 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
this.finish('saveToken')
|
||||
}
|
||||
|
||||
async useBrowserBasedSolution (e) {
|
||||
async useBrowserBasedSolution(e) {
|
||||
await redis.set('CHATGPT:USE', 'browser')
|
||||
await this.reply('已切换到基于浏览器的解决方案,如果已经对话过建议执行`#结束对话`避免引起404错误')
|
||||
}
|
||||
|
||||
async useOpenAIAPIBasedSolution (e) {
|
||||
async useOpenAIAPIBasedSolution(e) {
|
||||
let use = await redis.get('CHATGPT:USE')
|
||||
if (use !== 'api') {
|
||||
await redis.set('CHATGPT:USE', 'api')
|
||||
|
|
@ -779,12 +899,12 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
}
|
||||
}
|
||||
|
||||
async useChatGLMSolution (e) {
|
||||
async useChatGLMSolution(e) {
|
||||
await redis.set('CHATGPT:USE', 'chatglm')
|
||||
await this.reply('已切换到ChatGLM-6B解决方案,如果已经对话过建议执行`#结束对话`避免引起404错误')
|
||||
}
|
||||
|
||||
async useReversedAPIBasedSolution2 (e) {
|
||||
async useReversedAPIBasedSolution2(e) {
|
||||
let use = await redis.get('CHATGPT:USE')
|
||||
if (use !== 'api3') {
|
||||
await redis.set('CHATGPT:USE', 'api3')
|
||||
|
|
@ -794,7 +914,7 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
}
|
||||
}
|
||||
|
||||
async useBingSolution (e) {
|
||||
async useBingSolution(e) {
|
||||
let use = await redis.get('CHATGPT:USE')
|
||||
if (use !== 'bing') {
|
||||
await redis.set('CHATGPT:USE', 'bing')
|
||||
|
|
@ -804,7 +924,7 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
}
|
||||
}
|
||||
|
||||
async useClaudeBasedSolution (e) {
|
||||
async useClaudeBasedSolution(e) {
|
||||
let use = await redis.get('CHATGPT:USE')
|
||||
if (use !== 'poe') {
|
||||
await redis.set('CHATGPT:USE', 'poe')
|
||||
|
|
@ -814,7 +934,7 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
}
|
||||
}
|
||||
|
||||
async useSlackClaudeBasedSolution () {
|
||||
async useSlackClaudeBasedSolution() {
|
||||
let use = await redis.get('CHATGPT:USE')
|
||||
if (use !== 'claude') {
|
||||
await redis.set('CHATGPT:USE', 'claude')
|
||||
|
|
@ -824,7 +944,7 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
}
|
||||
}
|
||||
|
||||
async useXinghuoBasedSolution () {
|
||||
async useXinghuoBasedSolution() {
|
||||
let use = await redis.get('CHATGPT:USE')
|
||||
if (use !== 'xh') {
|
||||
await redis.set('CHATGPT:USE', 'xh')
|
||||
|
|
@ -834,7 +954,7 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
}
|
||||
}
|
||||
|
||||
async changeBingTone (e) {
|
||||
async changeBingTone(e) {
|
||||
let tongStyle = e.msg.replace(/^#chatgpt(必应|Bing)切换/, '')
|
||||
if (!tongStyle) {
|
||||
return
|
||||
|
|
@ -857,12 +977,12 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
}
|
||||
}
|
||||
|
||||
async bingOpenSuggestedResponses (e) {
|
||||
async bingOpenSuggestedResponses(e) {
|
||||
Config.enableSuggestedResponses = e.msg.indexOf('开启') > -1
|
||||
await e.reply('操作成功')
|
||||
}
|
||||
|
||||
async checkAuth (e) {
|
||||
async checkAuth(e) {
|
||||
if (!e.isMaster) {
|
||||
e.reply(`只有主人才能命令ChatGPT哦~
|
||||
(*/ω\*)`)
|
||||
|
|
@ -871,11 +991,11 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
return true
|
||||
}
|
||||
|
||||
async versionChatGPTPlugin (e) {
|
||||
async versionChatGPTPlugin(e) {
|
||||
await renderUrl(e, `http://127.0.0.1:${Config.serverPort || 3321}/version`, { Viewport: { width: 800, height: 600 } })
|
||||
}
|
||||
|
||||
async modeHelp () {
|
||||
async modeHelp() {
|
||||
let mode = await redis.get('CHATGPT:USE')
|
||||
const modeMap = {
|
||||
browser: '浏览器',
|
||||
|
|
@ -912,7 +1032,7 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
await this.reply(message)
|
||||
}
|
||||
|
||||
async shutUp (e) {
|
||||
async shutUp(e) {
|
||||
let duration = e.msg.replace(/^#chatgpt(本群)?(群\d+)?(关闭|闭嘴|关机|休眠|下班)/, '')
|
||||
let scope
|
||||
let time = 3600000
|
||||
|
|
@ -964,7 +1084,7 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
}
|
||||
}
|
||||
|
||||
async openMouth (e) {
|
||||
async openMouth(e) {
|
||||
const match = e.msg.match(/^#chatgpt群(\d+)/)
|
||||
if (e.msg.indexOf('本群') > -1) {
|
||||
if (await redis.get('CHATGPT:SHUT_UP:ALL')) {
|
||||
|
|
@ -1019,7 +1139,7 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
}
|
||||
}
|
||||
|
||||
async listShutUp () {
|
||||
async listShutUp() {
|
||||
let keys = await redis.keys('CHATGPT:SHUT_UP:*')
|
||||
if (!keys || keys.length === 0) {
|
||||
await this.reply('已经开启过全群响应啦', true)
|
||||
|
|
@ -1036,13 +1156,13 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
}
|
||||
}
|
||||
|
||||
async setAPIKey (e) {
|
||||
async setAPIKey(e) {
|
||||
this.setContext('saveAPIKey')
|
||||
await this.reply('请发送OpenAI API Key.', true)
|
||||
return false
|
||||
}
|
||||
|
||||
async saveAPIKey () {
|
||||
async saveAPIKey() {
|
||||
if (!this.e.msg) return
|
||||
let token = this.e.msg
|
||||
if (!token.startsWith('sk-')) {
|
||||
|
|
@ -1056,13 +1176,13 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
this.finish('saveAPIKey')
|
||||
}
|
||||
|
||||
async setXinghuoToken () {
|
||||
async setXinghuoToken() {
|
||||
this.setContext('saveXinghuoToken')
|
||||
await this.reply('请发送星火的ssoSessionId', true)
|
||||
return false
|
||||
}
|
||||
|
||||
async saveXinghuoToken () {
|
||||
async saveXinghuoToken() {
|
||||
if (!this.e.msg) return
|
||||
let token = this.e.msg
|
||||
// todo
|
||||
|
|
@ -1071,13 +1191,13 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
this.finish('saveXinghuoToken')
|
||||
}
|
||||
|
||||
async setAPIPromptPrefix (e) {
|
||||
async setAPIPromptPrefix(e) {
|
||||
this.setContext('saveAPIPromptPrefix')
|
||||
await this.reply('请发送用于API模式的设定', true)
|
||||
return false
|
||||
}
|
||||
|
||||
async saveAPIPromptPrefix (e) {
|
||||
async saveAPIPromptPrefix(e) {
|
||||
if (!this.e.msg) return
|
||||
if (this.e.msg === '取消') {
|
||||
await this.reply('已取消设置API设定', true)
|
||||
|
|
@ -1090,13 +1210,13 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
this.finish('saveAPIPromptPrefix')
|
||||
}
|
||||
|
||||
async setBingPromptPrefix (e) {
|
||||
async setBingPromptPrefix(e) {
|
||||
this.setContext('saveBingPromptPrefix')
|
||||
await this.reply('请发送用于Bing Sydney模式的设定', true)
|
||||
return false
|
||||
}
|
||||
|
||||
async saveBingPromptPrefix (e) {
|
||||
async saveBingPromptPrefix(e) {
|
||||
if (!this.e.msg) return
|
||||
if (this.e.msg === '取消') {
|
||||
await this.reply('已取消设置Sydney设定', true)
|
||||
|
|
@ -1108,7 +1228,7 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
this.finish('saveBingPromptPrefix')
|
||||
}
|
||||
|
||||
async switchDraw (e) {
|
||||
async switchDraw(e) {
|
||||
if (e.msg.indexOf('开启') > -1) {
|
||||
if (Config.enableDraw) {
|
||||
await this.reply('当前已经开启chatgpt画图功能', true)
|
||||
|
|
@ -1126,15 +1246,15 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
}
|
||||
}
|
||||
|
||||
async queryAPIPromptPrefix (e) {
|
||||
async queryAPIPromptPrefix(e) {
|
||||
await this.reply(Config.promptPrefixOverride, true)
|
||||
}
|
||||
|
||||
async queryBingPromptPrefix (e) {
|
||||
async queryBingPromptPrefix(e) {
|
||||
await this.reply(Config.sydney, true)
|
||||
}
|
||||
|
||||
async setAdminPassword (e) {
|
||||
async setAdminPassword(e) {
|
||||
if (e.isGroup || !e.isPrivate) {
|
||||
await this.reply('请私聊发送命令', true)
|
||||
return true
|
||||
|
|
@ -1144,7 +1264,7 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
return false
|
||||
}
|
||||
|
||||
async setUserPassword (e) {
|
||||
async setUserPassword(e) {
|
||||
if (e.isGroup || !e.isPrivate) {
|
||||
await this.reply('请私聊发送命令', true)
|
||||
return true
|
||||
|
|
@ -1154,7 +1274,7 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
return false
|
||||
}
|
||||
|
||||
async saveAdminPassword (e) {
|
||||
async saveAdminPassword(e) {
|
||||
if (!this.e.msg) return
|
||||
const passwd = this.e.msg
|
||||
await redis.set('CHATGPT:ADMIN_PASSWD', md5(passwd))
|
||||
|
|
@ -1162,7 +1282,7 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
this.finish('saveAdminPassword')
|
||||
}
|
||||
|
||||
async saveUserPassword (e) {
|
||||
async saveUserPassword(e) {
|
||||
if (!this.e.msg) return
|
||||
const passwd = this.e.msg
|
||||
const dir = 'resources/ChatGPTCache/user'
|
||||
|
|
@ -1198,7 +1318,7 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
this.finish('saveUserPassword')
|
||||
}
|
||||
|
||||
async adminPage (e) {
|
||||
async adminPage(e) {
|
||||
if (!Config.groupAdminPage && (e.isGroup || !e.isPrivate)) {
|
||||
await this.reply('请私聊发送命令', true)
|
||||
return true
|
||||
|
|
@ -1207,7 +1327,7 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
await this.reply(`请登录${viewHost + 'admin/settings'}进行系统配置`, true)
|
||||
}
|
||||
|
||||
async userPage (e) {
|
||||
async userPage(e) {
|
||||
if (!Config.groupAdminPage && (e.isGroup || !e.isPrivate)) {
|
||||
await this.reply('请私聊发送命令', true)
|
||||
return true
|
||||
|
|
@ -1216,12 +1336,12 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
await this.reply(`请登录${viewHost + 'admin/dashboard'}进行系统配置`, true)
|
||||
}
|
||||
|
||||
async setOpenAIPlatformToken (e) {
|
||||
async setOpenAIPlatformToken(e) {
|
||||
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如果仍不能查看余额,请退出登录重新获取刷新令牌')
|
||||
}
|
||||
|
||||
async doSetOpenAIPlatformToken () {
|
||||
async doSetOpenAIPlatformToken() {
|
||||
let token = this.e.msg
|
||||
if (!token) {
|
||||
return false
|
||||
|
|
@ -1231,7 +1351,7 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
this.finish('doSetOpenAIPlatformToken')
|
||||
}
|
||||
|
||||
async exportConfig (e) {
|
||||
async exportConfig(e) {
|
||||
if (e.isGroup || !e.isPrivate) {
|
||||
await this.reply('请私聊发送命令', true)
|
||||
return true
|
||||
|
|
@ -1250,9 +1370,12 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
if (await redis.exists('CHATGPT:USE') != 0) {
|
||||
redisConfig.useMode = await redis.get('CHATGPT:USE')
|
||||
}
|
||||
const filepath = path.join('plugins/chatgpt-plugin/resources', 'view.json')
|
||||
const configView = JSON.parse(fs.readFileSync(filepath, 'utf8'))
|
||||
const configJson = JSON.stringify({
|
||||
chatConfig: Config,
|
||||
redisConfig
|
||||
redisConfig,
|
||||
view: configView
|
||||
})
|
||||
console.log(configJson)
|
||||
const buf = Buffer.from(configJson)
|
||||
|
|
@ -1260,7 +1383,7 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
return true
|
||||
}
|
||||
|
||||
async importConfig (e) {
|
||||
async importConfig(e) {
|
||||
if (e.isGroup || !e.isPrivate) {
|
||||
await this.reply('请私聊发送命令', true)
|
||||
return true
|
||||
|
|
@ -1269,7 +1392,7 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
await e.reply('请发送配置文件')
|
||||
}
|
||||
|
||||
async doImportConfig (e) {
|
||||
async doImportConfig(e) {
|
||||
const file = this.e.message.find(item => item.type === 'file')
|
||||
if (file) {
|
||||
const fileUrl = await this.e.friend.getFileUrl(file.fid)
|
||||
|
|
@ -1333,7 +1456,7 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
this.finish('doImportConfig')
|
||||
}
|
||||
|
||||
async switchSmartMode (e) {
|
||||
async switchSmartMode(e) {
|
||||
if (e.msg.includes('开启')) {
|
||||
if (Config.smartMode) {
|
||||
await e.reply('已经开启了')
|
||||
|
|
|
|||
867
resources/view/setting_view.json
Normal file
867
resources/view/setting_view.json
Normal file
|
|
@ -0,0 +1,867 @@
|
|||
[
|
||||
{
|
||||
"id": "GeneralSettings",
|
||||
"title": "通用设置",
|
||||
"view": [
|
||||
{
|
||||
"type": "check",
|
||||
"label": "图片识别OCR",
|
||||
"data": "imgOcr"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "允许其他模式",
|
||||
"data": "allowOtherMode"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "调试信息",
|
||||
"data": "debug"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "是否允许私聊机器人",
|
||||
"data": "enablePrivateChat"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "回复确认",
|
||||
"model": "redisConfig",
|
||||
"data": "turnConfirm"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "新版帮助",
|
||||
"data": "newhelp"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "对话保留时长",
|
||||
"placeholder": "每个人发起的对话保留时长",
|
||||
"data": "conversationPreserveTime"
|
||||
},
|
||||
{
|
||||
"type": "url",
|
||||
"label": "代理服务器地址",
|
||||
"placeholder": "数据通过代理服务器发送,http或socks5代理",
|
||||
"data": "proxy"
|
||||
},
|
||||
{
|
||||
"type": "select",
|
||||
"label": "对话模式",
|
||||
"model": "redisConfig",
|
||||
"data": "useMode",
|
||||
"items": [
|
||||
{
|
||||
"label": "必应",
|
||||
"value": "bing"
|
||||
},
|
||||
{
|
||||
"label": "ChatGPT API",
|
||||
"value": "api"
|
||||
},
|
||||
{
|
||||
"label": "ChatGPT API3",
|
||||
"value": "api3"
|
||||
},
|
||||
{
|
||||
"label": "Slack Claude",
|
||||
"value": "claude"
|
||||
},
|
||||
{
|
||||
"label": "ChatGLM",
|
||||
"value": "chatglm"
|
||||
},
|
||||
{
|
||||
"label": "星火",
|
||||
"value": "xh"
|
||||
},
|
||||
{
|
||||
"label": "浏览器",
|
||||
"value": "browser"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "password",
|
||||
"label": "高德APIKey",
|
||||
"placeholder": "用于查询天气",
|
||||
"data": "amapKey"
|
||||
},
|
||||
{
|
||||
"type": "url",
|
||||
"label": "Azure search key",
|
||||
"placeholder": "https://www.microsoft.com/en-us/bing/apis/bing-web-search-api",
|
||||
"data": "azSerpKey"
|
||||
},
|
||||
{
|
||||
"type": "select",
|
||||
"label": "搜索来源",
|
||||
"data": "serpSource",
|
||||
"items": [
|
||||
{
|
||||
"label": "Azure",
|
||||
"value": "azure"
|
||||
},
|
||||
{
|
||||
"label": "ikechan8370",
|
||||
"value": "ikechan8370"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "url",
|
||||
"label": "额外工具url",
|
||||
"placeholder": "测试期间提供一个公益接口,一段时间后撤掉",
|
||||
"data": "extraUrl"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "ChatSettings",
|
||||
"title": "聊天设置",
|
||||
"view": [
|
||||
{
|
||||
"type": "tabs",
|
||||
"id": "ChatSetting",
|
||||
"tabs": [
|
||||
{
|
||||
"title": "文本模式",
|
||||
"icon": "mdi-format-text",
|
||||
"tab": "text",
|
||||
"view": [
|
||||
{
|
||||
"type": "check",
|
||||
"label": "长文本自动转图片",
|
||||
"data": "autoUsePicture"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "是否允许机器人真AT",
|
||||
"data": "enableRobotAt"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "自动转图片阈值",
|
||||
"placeholder": "自动转图片的字数阈值",
|
||||
"data": "autoUsePictureThreshold"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "图片模式[基础参数]",
|
||||
"icon": "mdi-image",
|
||||
"tab": "image_base",
|
||||
"view": [
|
||||
{
|
||||
"type": "check",
|
||||
"label": "全局图片模式",
|
||||
"data": "defaultUsePicture"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "图片引用消息",
|
||||
"data": "quoteReply"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "启用二维码",
|
||||
"data": "showQRCode"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "BOT命名",
|
||||
"placeholder": "强制修改Bot命名",
|
||||
"data": "chatViewBotName"
|
||||
},
|
||||
{
|
||||
"type": "url",
|
||||
"label": "渲染服务器地址",
|
||||
"placeholder": "可选择第三方渲染服务器",
|
||||
"data": "viewHost"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "图片渲染宽度",
|
||||
"placeholder": "图片渲染宽度",
|
||||
"data": "chatViewWidth"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "云渲染",
|
||||
"data": "cloudRender"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "云渲染DPR",
|
||||
"placeholder": "设置云渲染画面缩放,数值愈大越清晰",
|
||||
"data": "cloudDPR"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "图片模式[Live2D]",
|
||||
"icon": "mdi-image",
|
||||
"tab": "image_live2d",
|
||||
"view": [
|
||||
{
|
||||
"type": "check",
|
||||
"label": "Live2D",
|
||||
"data": "live2d"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "Live2D模型",
|
||||
"placeholder": "使用的Live2D模式文件",
|
||||
"data": "live2dModel"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "Live2D模型缩放",
|
||||
"placeholder": "渲染live2d的模型大小",
|
||||
"data": "live2dOption_scale"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "Live2D模型位置X",
|
||||
"placeholder": "Live2d模型在区域的位置X轴微调",
|
||||
"data": "live2dOption_positionX"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "Live2D模型位置Y",
|
||||
"placeholder": "Live2d模型在区域的位置Y轴微调",
|
||||
"data": "live2dOption_positionY"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "Live2D模型旋转",
|
||||
"placeholder": "Live2d模型在区域的旋转角度",
|
||||
"data": "live2dOption_rotation"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "Live2D模型透明度",
|
||||
"placeholder": "Live2d模型的透明度",
|
||||
"data": "live2dOption_alpha"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "图片模式[旧渲染]",
|
||||
"icon": "mdi-image",
|
||||
"tab": "image_old",
|
||||
"view": [
|
||||
{
|
||||
"type": "check",
|
||||
"label": "旧版本渲染",
|
||||
"data": "oldview"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "预制渲染服务器访问代码",
|
||||
"data": "cacheEntry"
|
||||
},
|
||||
{
|
||||
"type": "url",
|
||||
"label": "渲染服务器地址",
|
||||
"placeholder": "可选择第三方渲染服务器",
|
||||
"data": "cacheUrl"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "语音模式",
|
||||
"icon": "mdi-microphone",
|
||||
"tab": "voice",
|
||||
"view": [
|
||||
{
|
||||
"type": "check",
|
||||
"label": "全局语音模式",
|
||||
"data": "defaultUseTTS"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "语音同时发送文字",
|
||||
"data": "alsoSendText"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "语音转文字阈值",
|
||||
"placeholder": "语音模式下,字数超过这个阈值就降级为文字",
|
||||
"data": "ttsAutoFallbackThreshold"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "语音过滤正则表达式",
|
||||
"placeholder": "语音模式下,配置此项以过滤不想被读出来的内容",
|
||||
"data": "ttsRegex"
|
||||
},
|
||||
{
|
||||
"type": "select",
|
||||
"label": "语音模式源",
|
||||
"data": "ttsMode",
|
||||
"items": [
|
||||
{
|
||||
"label": "Vits",
|
||||
"value": "vits-uma-genshin-honkai"
|
||||
},
|
||||
{
|
||||
"label": "微软Azure",
|
||||
"value": "azure"
|
||||
},
|
||||
{
|
||||
"label": "VoiceVox",
|
||||
"value": "VoiceVox"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "select",
|
||||
"label": "云转码模式",
|
||||
"data": "cloudMode",
|
||||
"items": [
|
||||
{
|
||||
"label": "文件",
|
||||
"value": "file"
|
||||
},
|
||||
{
|
||||
"label": "链接",
|
||||
"value": "url"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "语音模式[vits]",
|
||||
"icon": "mdi-microphone",
|
||||
"tab": "vits",
|
||||
"view": [
|
||||
{
|
||||
"type": "url",
|
||||
"label": "语音转换API地址",
|
||||
"placeholder": "前往duplicate空间查看api地址",
|
||||
"data": "ttsSpace"
|
||||
},
|
||||
{
|
||||
"type": "url",
|
||||
"label": "语音转换huggingface反代",
|
||||
"data": "huggingFaceReverseProxy"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "控制情感变化程度",
|
||||
"data": "noiseScale"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "控制音素发音长度",
|
||||
"data": "noiseScaleW"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "控制整体语速",
|
||||
"data": "lengthScale"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "日语输出",
|
||||
"data": "autoJapanese"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "语音模式[Azure]",
|
||||
"icon": "mdi-microphone",
|
||||
"tab": "azure",
|
||||
"view": [
|
||||
{
|
||||
"type": "password",
|
||||
"label": "语音服务密钥",
|
||||
"placeholder": "Azure的语音服务密钥",
|
||||
"data": "azureTTSKey"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "语音服务区域",
|
||||
"placeholder": "Azure语音服务区域",
|
||||
"data": "azureTTSRegion"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "Azure情绪多样化",
|
||||
"data": "azureTTSEmotion"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "Azure情绪纠正",
|
||||
"data": "enhanceAzureTTSEmotion"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "语音模式[Voicevox]",
|
||||
"icon": "mdi-microphone",
|
||||
"tab": "voicevox",
|
||||
"view": [
|
||||
{
|
||||
"type": "url",
|
||||
"label": "语音转换API地址",
|
||||
"placeholder": "voicevox语音转换API地址",
|
||||
"data": "voicevoxSpace"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "ModelSettings",
|
||||
"title": "模式设置",
|
||||
"view": [
|
||||
{
|
||||
"type": "tabs",
|
||||
"id": "ChatSetting",
|
||||
"tabs": [
|
||||
{
|
||||
"title": "API",
|
||||
"tab": "api",
|
||||
"view": [
|
||||
{
|
||||
"type": "check",
|
||||
"label": "强制使用OpenAI反代",
|
||||
"data": "openAiForceUseReverse"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "智能模式",
|
||||
"data": "smartMode"
|
||||
},
|
||||
{
|
||||
"type": "password",
|
||||
"label": "OpenAI API Key",
|
||||
"placeholder": "OpenAI的ApiKey,用于访问OpenAI的API接口",
|
||||
"data": "apiKey"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "OpenAI 模型",
|
||||
"placeholder": "gpt-4, gpt-4-0314, gpt-4-32k, gpt-4-32k-0314, gpt-3.5-turbo, gpt-3.5-turbo-0301",
|
||||
"data": "model"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "AI名字",
|
||||
"placeholder": "AI认为的自己的名字,当你问他你是谁是他会回答这里的名字",
|
||||
"data": "assistantLabel"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "temperature",
|
||||
"placeholder": "用于控制回复内容的多样性,数值越大回复越加随机、多元化,数值越小回复越加保守",
|
||||
"data": "temperature"
|
||||
},
|
||||
{
|
||||
"type": "url",
|
||||
"label": "OpenAI API服务器地址",
|
||||
"placeholder": "OpenAI的API服务器地址,注意要带上/v1。",
|
||||
"data": "openAiBaseUrl"
|
||||
},
|
||||
{
|
||||
"type": "textarea",
|
||||
"label": "AI风格",
|
||||
"placeholder": "你可以在这里写入你希望AI回答的风格,比如希望优先回答中文,回答长一点等",
|
||||
"data": "promptPrefixOverride"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "API3",
|
||||
"tab": "api3",
|
||||
"view": [
|
||||
{
|
||||
"type": "url",
|
||||
"label": "ChatGPT API反代服务器地址",
|
||||
"placeholder": "ChatGPT的API反代服务器,用于绕过Cloudflare访问ChatGPT API。",
|
||||
"data": "api"
|
||||
},
|
||||
{
|
||||
"type": "url",
|
||||
"label": "apiBaseUrl地址",
|
||||
"data": "apiBaseUrl"
|
||||
},
|
||||
{
|
||||
"type": "password",
|
||||
"label": "OpenAI refreshToken",
|
||||
"placeholder": "OpenAI的refreshToken,用于刷新Access Token",
|
||||
"data": "OpenAiPlatformRefreshToken"
|
||||
},
|
||||
{
|
||||
"type": "password",
|
||||
"label": "OpenAI AccessToken",
|
||||
"model": "redisConfig",
|
||||
"data": "openAiPlatformAccessToken"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "强制使用ChatGPT反代",
|
||||
"data": "apiForceUseReverse"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "使用GPT-4",
|
||||
"data": "useGPT4"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "浏览器",
|
||||
"tab": "browser",
|
||||
"view": [
|
||||
{
|
||||
"type": "check",
|
||||
"label": "无头模式",
|
||||
"data": "headless"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "用户名",
|
||||
"placeholder": "OpenAI用户名",
|
||||
"data": "username"
|
||||
},
|
||||
{
|
||||
"type": "password",
|
||||
"label": "密码",
|
||||
"placeholder": "OpenAI密码",
|
||||
"data": "password"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "Chrome路径",
|
||||
"placeholder": "为空使用默认puppeteer的chromium,也可以传递自己本机安装的Chrome可执行文件地址,提高通过率。",
|
||||
"data": "chromePath"
|
||||
},
|
||||
{
|
||||
"type": "textarea",
|
||||
"label": "浏览器UA",
|
||||
"placeholder": "模拟浏览器UA,无特殊需求保持默认即可",
|
||||
"data": "UA"
|
||||
},
|
||||
{
|
||||
"type": "password",
|
||||
"label": "验证码平台Token",
|
||||
"placeholder": "可注册2captcha实现跳过验证码",
|
||||
"data": "2captchaToken"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "必应",
|
||||
"tab": "bing",
|
||||
"view": [
|
||||
{
|
||||
"type": "select",
|
||||
"label": "Bing模式",
|
||||
"data": "toneStyle",
|
||||
"items": [
|
||||
{
|
||||
"label": "均衡",
|
||||
"value": "balanced"
|
||||
},
|
||||
{
|
||||
"label": "创意",
|
||||
"value": "creative"
|
||||
},
|
||||
{
|
||||
"label": "精确",
|
||||
"value": "precise"
|
||||
},
|
||||
{
|
||||
"label": "Sydney(可能存在风险)",
|
||||
"value": "Sydney"
|
||||
},
|
||||
{
|
||||
"label": "自设定(可能存在风险)",
|
||||
"value": "Custom"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "是否开启建议回复",
|
||||
"data": "enableSuggestedResponses"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "是否允许机器人读取近期的群聊聊天记录",
|
||||
"data": "enableGroupContext"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "允许机器人读取近期的最多群聊聊天记录条数",
|
||||
"placeholder": "允许机器人读取近期的最多群聊聊天记录条数。太多可能会超。",
|
||||
"data": "groupContextLength"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "机器人读取聊天记录时的后台prompt",
|
||||
"data": "groupContextTip"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "加强主人认知",
|
||||
"data": "enforceMaster"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "Bing抱歉是否不计入聊天记录",
|
||||
"data": "sydneyApologyIgnored"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "情感显示",
|
||||
"data": "sydneyMood"
|
||||
},
|
||||
{
|
||||
"type": "textarea",
|
||||
"label": "Custom的设定",
|
||||
"placeholder": "仅自设定模式下有效。你可以自己改写设定,让Sydney变成你希望的样子",
|
||||
"data": "sydney"
|
||||
},
|
||||
{
|
||||
"type": "textarea",
|
||||
"label": "Bing的扩展资料",
|
||||
"placeholder": "AI将会从你提供的扩展资料中学习到一些知识,帮助它更好地回答你的问题",
|
||||
"data": "sydneyContext"
|
||||
},
|
||||
{
|
||||
"type": "textarea",
|
||||
"label": "情感模式设定",
|
||||
"placeholder": "情感显示开启的情况下AI将根据设定在正文中体现情感内容",
|
||||
"data": "sydneyMoodTip"
|
||||
},
|
||||
{
|
||||
"type": "url",
|
||||
"label": "sydney反代",
|
||||
"placeholder": "仅悉尼和自设定模式下有效,用于创建对话(默认不用于正式对话)",
|
||||
"data": "sydneyReverseProxy"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "强制使用sydney反代",
|
||||
"data": "sydneyReverseProxy"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "对话使用sydney反代",
|
||||
"data": "sydneyForceUseReverse"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "允许生成图像等内容",
|
||||
"data": "enableGenerateContents"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "ChatGLM",
|
||||
"tab": "chatglm",
|
||||
"view": [
|
||||
{
|
||||
"type": "url",
|
||||
"label": "ChatGLM API地址",
|
||||
"data": "chatglmBaseUrl"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Slack Claude",
|
||||
"tab": "claude",
|
||||
"view": [
|
||||
{
|
||||
"type": "password",
|
||||
"label": "Slack用户Token",
|
||||
"placeholder": "slackUserToken,在OAuth&Permissions页面获取",
|
||||
"data": "slackUserToken"
|
||||
},
|
||||
{
|
||||
"type": "password",
|
||||
"label": "Slack Bot Token",
|
||||
"placeholder": "slackBotUserToken,在OAuth&Permissions页面获取",
|
||||
"data": "slackBotUserToken"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "Slack成员id",
|
||||
"placeholder": "在Slack中点击Claude头像查看详情,其中的成员ID复制过来",
|
||||
"data": "slackClaudeUserId"
|
||||
},
|
||||
{
|
||||
"type": "password",
|
||||
"label": "Slack签名密钥",
|
||||
"placeholder": "Signing Secret。在Basic Information页面获取",
|
||||
"data": "slackSigningSecret"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "Claude使用全局设定",
|
||||
"data": "slackClaudeEnableGlobalPreset"
|
||||
},
|
||||
{
|
||||
"type": "textarea",
|
||||
"label": "Slack全局设定",
|
||||
"placeholder": "若启用全局设定,每个人都会默认使用这里的设定",
|
||||
"data": "slackClaudeGlobalPreset"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "星火",
|
||||
"tab": "xh",
|
||||
"view": [
|
||||
{
|
||||
"type": "password",
|
||||
"label": "星火Cookie",
|
||||
"data": "xinghuoToken"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "DrawSettings",
|
||||
"title": "绘图设置",
|
||||
"view": [
|
||||
{
|
||||
"type": "check",
|
||||
"label": "绘图功能开关",
|
||||
"data": "enableDraw"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "绘图CD",
|
||||
"placeholder": "绘图指令的CD时间",
|
||||
"data": "drawCD"
|
||||
},
|
||||
{
|
||||
"type": "url",
|
||||
"label": "emojiAPI地址",
|
||||
"placeholder": "合成emoji的API地址",
|
||||
"data": "emojiBaseURL"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "GroupSettings",
|
||||
"title": "群聊设置",
|
||||
"view": [
|
||||
{
|
||||
"type": "textarea",
|
||||
"label": "打招呼prompt",
|
||||
"placeholder": "将会用这段文字询问ChatGPT,由ChatGPT给出随机的打招呼文字",
|
||||
"data": "helloPrompt"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "打招呼间隔(小时)",
|
||||
"data": "helloInterval"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "打招呼的触发概率(%)",
|
||||
"placeholder": "设置为100则每次经过间隔时间必定触发主动打招呼事件。",
|
||||
"data": "helloProbability"
|
||||
},
|
||||
{
|
||||
"type": "select",
|
||||
"label": "触发方式",
|
||||
"data": "toggleMode",
|
||||
"items": [
|
||||
{
|
||||
"label": "at",
|
||||
"value": "at"
|
||||
},
|
||||
{
|
||||
"label": "#chat",
|
||||
"value": "prefix"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "TimeoutSettings",
|
||||
"title": "服务超时配置",
|
||||
"view": [
|
||||
{
|
||||
"type": "number",
|
||||
"label": "默认超时时间",
|
||||
"placeholder": "各个地方的默认超时时间",
|
||||
"data": "defaultTimeoutMs"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "浏览器超时时间",
|
||||
"placeholder": "浏览器默认超时,浏览器可能需要更高的超时时间",
|
||||
"data": "chromeTimeoutMS"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "Sydney模式接受首条信息超时时间",
|
||||
"placeholder": "超过该时间阈值未收到Bing的任何消息,则断开本次连接并重试",
|
||||
"data": "sydneyFirstMessageTimeout"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "ReviewSettings",
|
||||
"title": "违禁内容核查",
|
||||
"view": [
|
||||
{
|
||||
"type": "textarea",
|
||||
"label": "输出黑名单",
|
||||
"placeholder": "检查输出结果中是否有违禁词,如果存在黑名单中的违禁词则不输出。英文逗号隔开",
|
||||
"data": "blockWords"
|
||||
},
|
||||
{
|
||||
"type": "textarea",
|
||||
"label": "输入黑名单",
|
||||
"placeholder": "检查输入结果中是否有违禁词,如果存在黑名单中的违禁词则不输出。英文逗号隔开",
|
||||
"data": "promptBlockWords"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "GroupSettings",
|
||||
"title": "群聊设置",
|
||||
"view": [
|
||||
{
|
||||
"type": "number",
|
||||
"label": "系统Api服务端口",
|
||||
"placeholder": "系统Api服务开启的端口号,如需外网访问请将系统防火墙和服务器防火墙对应端口开放",
|
||||
"data": "ServerSettings"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "系统服务访问域名",
|
||||
"placeholder": "使用域名代替公网ip,适用于有服务器和域名的朋友避免暴露ip使用",
|
||||
"data": "serverHost"
|
||||
},
|
||||
{
|
||||
"type": "url",
|
||||
"label": "云服务API地址",
|
||||
"placeholder": "目前支持node-silk语音转码、云图片渲染和页面生成缓存",
|
||||
"data": "cloudTranscode"
|
||||
},
|
||||
{
|
||||
"type": "check",
|
||||
"label": "允许群获取后台地址",
|
||||
"data": "groupAdminPage"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
@ -8,13 +8,15 @@ import fs from 'fs'
|
|||
import path from 'path'
|
||||
import os from 'os'
|
||||
import schedule from 'node-schedule'
|
||||
import websocketclient from 'ws'
|
||||
|
||||
import { Config } from '../utils/config.js'
|
||||
import { UserInfo, GetUser } from './modules/user_data.js'
|
||||
import { getPublicIP, getUserData } from '../utils/common.js'
|
||||
import { getPublicIP, getUserData, getMasterQQ, randomString } from '../utils/common.js'
|
||||
|
||||
import webRoute from './modules/web_route.js'
|
||||
import webUser from './modules/user.js'
|
||||
import SettingView from './modules/setting_view.js'
|
||||
|
||||
const __dirname = path.resolve()
|
||||
const server = fastify({
|
||||
|
|
@ -79,6 +81,92 @@ await server.register(websocket, {
|
|||
await server.register(fastifyCookie)
|
||||
await server.register(webRoute)
|
||||
await server.register(webUser)
|
||||
await server.register(SettingView)
|
||||
|
||||
// 无法访问端口的情况下创建与media的通讯
|
||||
async function mediaLink() {
|
||||
const ip = await getPublicIP()
|
||||
const testServer = await fetch(`${Config.cloudTranscode}/check`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
url: `http://${ip}:${Config.serverPort || 3321}/`
|
||||
})
|
||||
})
|
||||
if (testServer.ok) {
|
||||
const checkCloudData = await testServer.json()
|
||||
if (checkCloudData.state != 'error') {
|
||||
console.log('本地服务无法访问,开启media服务代理')
|
||||
const serverurl = new URL(Config.cloudTranscode)
|
||||
const ws = new websocketclient(`ws://${serverurl.hostname}${serverurl.port ? ':' + serverurl.port : ''}/ws`)
|
||||
ws.on('open', () => {
|
||||
ws.send(JSON.stringify({
|
||||
command: 'register',
|
||||
region: Bot.uin,
|
||||
type: 'server',
|
||||
}))
|
||||
})
|
||||
ws.on('message', async (message) => {
|
||||
try {
|
||||
const data = JSON.parse(message)
|
||||
switch (data.command) {
|
||||
case 'register':
|
||||
if (data.state) {
|
||||
let master = (await getMasterQQ())[0]
|
||||
Bot.sendPrivateMsg(master, `当前chatgpt插件服务无法被外网访问,已启用代理链接,访问代码:${data.token}`, false)
|
||||
} else {
|
||||
console.log('注册区域失败')
|
||||
}
|
||||
break
|
||||
case 'login':
|
||||
if (data.token) {
|
||||
const user = UserInfo(data.token)
|
||||
if (user) {
|
||||
ws.login = true
|
||||
ws.send(JSON.stringify({ command: data.command, state: true, region: Bot.uin, type: 'server' }))
|
||||
} else {
|
||||
ws.send(JSON.stringify({ command: data.command, state: false, error: '权限验证失败', region: Bot.uin, type: 'server' }))
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'post_login':
|
||||
if (data.qq && data.passwd) {
|
||||
const token = randomString(32)
|
||||
if (data.qq == Bot.uin && await redis.get('CHATGPT:ADMIN_PASSWD') == data.passwd) {
|
||||
AddUser({ user: data.qq, token: token, autho: 'admin' })
|
||||
ws.send(JSON.stringify({ command: data.command, state: true, autho: 'admin', token: token, region: Bot.uin, type: 'server' }))
|
||||
|
||||
} else {
|
||||
const user = await getUserData(data.qq)
|
||||
if (user.passwd != '' && user.passwd === data.passwd) {
|
||||
AddUser({ user: data.qq, token: token, autho: 'user' })
|
||||
ws.send(JSON.stringify({ command: data.command, state: true, autho: 'user', token: token, region: Bot.uin, type: 'server' }))
|
||||
} else {
|
||||
ws.send(JSON.stringify({ command: data.command, state: false, error: `用户名密码错误,如果忘记密码请私聊机器人输入 ${data.qq == Bot.uin ? '#修改管理密码' : '#修改用户密码'} 进行修改`, region: Bot.uin, type: 'server' }))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ws.send(JSON.stringify({ command: data.command, state: false, error: '未输入用户名或密码', region: Bot.uin, type: 'server' }))
|
||||
}
|
||||
break
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
})
|
||||
|
||||
} else {
|
||||
console.log('本地服务网络正常,无需开启通讯')
|
||||
}
|
||||
} else {
|
||||
console.log('media服务器未响应')
|
||||
}
|
||||
}
|
||||
// 未完工,暂不开启这个功能
|
||||
// mediaLink()
|
||||
|
||||
export async function createServer() {
|
||||
// 页面数据获取
|
||||
|
|
|
|||
23
server/modules/setting_view.js
Normal file
23
server/modules/setting_view.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import { UserInfo } from './user_data.js'
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
async function SettingView(fastify, options) {
|
||||
// 获取配置视图
|
||||
fastify.post('/settingView', async (request, reply) => {
|
||||
const token = request.cookies.token || request.body?.token || 'unknown'
|
||||
let user = UserInfo(token)
|
||||
if (!user) {
|
||||
reply.send({ err: '未登录' })
|
||||
} else if (user.autho === 'admin') {
|
||||
const filepath = path.join('plugins/chatgpt-plugin/resources/view', 'setting_view.json')
|
||||
const configView = JSON.parse(fs.readFileSync(filepath, 'utf8'))
|
||||
reply.send(configView)
|
||||
} else {
|
||||
reply.send({ err: '权限不足' })
|
||||
}
|
||||
return reply
|
||||
})
|
||||
}
|
||||
|
||||
export default SettingView
|
||||
|
|
@ -40,7 +40,8 @@ async function User(fastify, options) {
|
|||
reply.send({
|
||||
verify: true,
|
||||
user: user.user,
|
||||
autho: user.autho
|
||||
autho: user.autho,
|
||||
version: 10010,
|
||||
})
|
||||
return reply
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue