mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-17 13:57:10 +00:00
Merge branch 'ikechan8370:v2' into v2
This commit is contained in:
commit
9723e6db17
92 changed files with 4289 additions and 1073 deletions
471
apps/chat.js
471
apps/chat.js
|
|
@ -1,76 +1,83 @@
|
|||
import plugin from '../../../lib/plugins/plugin.js'
|
||||
import _ from 'lodash'
|
||||
import { Config, defaultOpenAIAPI } from '../utils/config.js'
|
||||
import { v4 as uuid } from 'uuid'
|
||||
import {Config, defaultOpenAIAPI} from '../utils/config.js'
|
||||
import {v4 as uuid} from 'uuid'
|
||||
import delay from 'delay'
|
||||
import { ChatGPTAPI } from '../utils/openai/chatgpt-api.js'
|
||||
import { BingAIClient } from '@waylaidwanderer/chatgpt-api'
|
||||
import {ChatGPTAPI} from '../utils/openai/chatgpt-api.js'
|
||||
import {BingAIClient} from '@waylaidwanderer/chatgpt-api'
|
||||
import SydneyAIClient from '../utils/SydneyAIClient.js'
|
||||
import { PoeClient } from '../utils/poe/index.js'
|
||||
import {PoeClient} from '../utils/poe/index.js'
|
||||
import AzureTTS from '../utils/tts/microsoft-azure.js'
|
||||
import VoiceVoxTTS from '../utils/tts/voicevox.js'
|
||||
import Version from '../utils/version.js'
|
||||
import {
|
||||
render,
|
||||
renderUrl,
|
||||
getMessageById,
|
||||
makeForwardMsg,
|
||||
upsertMessage,
|
||||
randomString,
|
||||
completeJSON,
|
||||
isImage,
|
||||
getUserData,
|
||||
extractContentFromFile,
|
||||
formatDate,
|
||||
formatDate2,
|
||||
generateAudio,
|
||||
getDefaultReplySetting,
|
||||
isCN,
|
||||
getMasterQQ,
|
||||
getUserReplySetting,
|
||||
getImageOcrText,
|
||||
getImg,
|
||||
getMaxModelTokens, formatDate, generateAudio, formatDate2, mkdirs
|
||||
getMasterQQ,
|
||||
getMaxModelTokens,
|
||||
getMessageById,
|
||||
getUin,
|
||||
getUserData,
|
||||
getUserReplySetting,
|
||||
isCN,
|
||||
isImage,
|
||||
makeForwardMsg,
|
||||
randomString,
|
||||
render,
|
||||
renderUrl,
|
||||
upsertMessage
|
||||
} from '../utils/common.js'
|
||||
import { ChatGPTPuppeteer } from '../utils/browser.js'
|
||||
import { KeyvFile } from 'keyv-file'
|
||||
import { OfficialChatGPTClient } from '../utils/message.js'
|
||||
import {ChatGPTPuppeteer} from '../utils/browser.js'
|
||||
import {KeyvFile} from 'keyv-file'
|
||||
import {OfficialChatGPTClient} from '../utils/message.js'
|
||||
import fetch from 'node-fetch'
|
||||
import { deleteConversation, getConversations, getLatestMessageIdByConversationId } from '../utils/conversation.js'
|
||||
import { convertSpeaker, speakers } from '../utils/tts.js'
|
||||
import {deleteConversation, getConversations, getLatestMessageIdByConversationId} from '../utils/conversation.js'
|
||||
import {convertSpeaker, speakers} from '../utils/tts.js'
|
||||
import ChatGLMClient from '../utils/chatglm.js'
|
||||
import { convertFaces } from '../utils/face.js'
|
||||
import { SlackClaudeClient } from '../utils/slack/slackClient.js'
|
||||
import { getPromptByName } from '../utils/prompts.js'
|
||||
import {convertFaces} from '../utils/face.js'
|
||||
import {SlackClaudeClient} from '../utils/slack/slackClient.js'
|
||||
import {getPromptByName} from '../utils/prompts.js'
|
||||
import BingDrawClient from '../utils/BingDraw.js'
|
||||
import XinghuoClient from '../utils/xinghuo/xinghuo.js'
|
||||
import Bard from '../utils/bard.js'
|
||||
import { JinyanTool } from '../utils/tools/JinyanTool.js'
|
||||
import { SendVideoTool } from '../utils/tools/SendBilibiliTool.js'
|
||||
import { KickOutTool } from '../utils/tools/KickOutTool.js'
|
||||
import { EditCardTool } from '../utils/tools/EditCardTool.js'
|
||||
import { SearchVideoTool } from '../utils/tools/SearchBilibiliTool.js'
|
||||
import { SearchMusicTool } from '../utils/tools/SearchMusicTool.js'
|
||||
import { QueryStarRailTool } from '../utils/tools/QueryStarRailTool.js'
|
||||
import { WebsiteTool } from '../utils/tools/WebsiteTool.js'
|
||||
import { WeatherTool } from '../utils/tools/WeatherTool.js'
|
||||
import { SerpTool } from '../utils/tools/SerpTool.js'
|
||||
import { SerpIkechan8370Tool } from '../utils/tools/SerpIkechan8370Tool.js'
|
||||
import { SendPictureTool } from '../utils/tools/SendPictureTool.js'
|
||||
import { SerpImageTool } from '../utils/tools/SearchImageTool.js'
|
||||
import { ImageCaptionTool } from '../utils/tools/ImageCaptionTool.js'
|
||||
import { SendAudioMessageTool } from '../utils/tools/SendAudioMessageTool.js'
|
||||
import { ProcessPictureTool } from '../utils/tools/ProcessPictureTool.js'
|
||||
import { APTool } from '../utils/tools/APTool.js'
|
||||
import { QueryGenshinTool } from '../utils/tools/QueryGenshinTool.js'
|
||||
import { HandleMessageMsgTool } from '../utils/tools/HandleMessageMsgTool.js'
|
||||
import { QueryUserinfoTool } from '../utils/tools/QueryUserinfoTool.js'
|
||||
import { EliMovieTool } from '../utils/tools/EliMovieTool.js'
|
||||
import { EliMusicTool } from '../utils/tools/EliMusicTool.js'
|
||||
import { SendMusicTool } from '../utils/tools/SendMusicTool.js'
|
||||
import { SendDiceTool } from '../utils/tools/SendDiceTool.js'
|
||||
import { SendAvatarTool } from '../utils/tools/SendAvatarTool.js'
|
||||
import { SendMessageToSpecificGroupOrUserTool } from '../utils/tools/SendMessageToSpecificGroupOrUserTool.js'
|
||||
import { SetTitleTool } from '../utils/tools/SetTitleTool.js'
|
||||
import { solveCaptchaOneShot } from '../utils/bingCaptcha.js'
|
||||
import { ClaudeAIClient } from '../utils/claude.ai/index.js'
|
||||
import fs from 'fs'
|
||||
import { getProxy } from '../utils/proxy.js'
|
||||
import {JinyanTool} from '../utils/tools/JinyanTool.js'
|
||||
import {SendVideoTool} from '../utils/tools/SendBilibiliTool.js'
|
||||
import {KickOutTool} from '../utils/tools/KickOutTool.js'
|
||||
import {EditCardTool} from '../utils/tools/EditCardTool.js'
|
||||
import {SearchVideoTool} from '../utils/tools/SearchBilibiliTool.js'
|
||||
import {SearchMusicTool} from '../utils/tools/SearchMusicTool.js'
|
||||
import {QueryStarRailTool} from '../utils/tools/QueryStarRailTool.js'
|
||||
import {WebsiteTool} from '../utils/tools/WebsiteTool.js'
|
||||
import {WeatherTool} from '../utils/tools/WeatherTool.js'
|
||||
import {SerpTool} from '../utils/tools/SerpTool.js'
|
||||
import {SerpIkechan8370Tool} from '../utils/tools/SerpIkechan8370Tool.js'
|
||||
import {SendPictureTool} from '../utils/tools/SendPictureTool.js'
|
||||
import {SerpImageTool} from '../utils/tools/SearchImageTool.js'
|
||||
import {ImageCaptionTool} from '../utils/tools/ImageCaptionTool.js'
|
||||
import {SendAudioMessageTool} from '../utils/tools/SendAudioMessageTool.js'
|
||||
import {ProcessPictureTool} from '../utils/tools/ProcessPictureTool.js'
|
||||
import {APTool} from '../utils/tools/APTool.js'
|
||||
import {QueryGenshinTool} from '../utils/tools/QueryGenshinTool.js'
|
||||
import {HandleMessageMsgTool} from '../utils/tools/HandleMessageMsgTool.js'
|
||||
import {QueryUserinfoTool} from '../utils/tools/QueryUserinfoTool.js'
|
||||
import {EliMovieTool} from '../utils/tools/EliMovieTool.js'
|
||||
import {EliMusicTool} from '../utils/tools/EliMusicTool.js'
|
||||
import {SendMusicTool} from '../utils/tools/SendMusicTool.js'
|
||||
import {SendDiceTool} from '../utils/tools/SendDiceTool.js'
|
||||
import {SendAvatarTool} from '../utils/tools/SendAvatarTool.js'
|
||||
import {SendMessageToSpecificGroupOrUserTool} from '../utils/tools/SendMessageToSpecificGroupOrUserTool.js'
|
||||
import {SetTitleTool} from '../utils/tools/SetTitleTool.js'
|
||||
import {solveCaptchaOneShot} from '../utils/bingCaptcha.js'
|
||||
import {ClaudeAIClient} from '../utils/claude.ai/index.js'
|
||||
import {getProxy} from '../utils/proxy.js'
|
||||
import {QwenApi} from '../utils/alibaba/qwen-api.js'
|
||||
import {getChatHistoryGroup} from '../utils/chat.js'
|
||||
|
||||
try {
|
||||
await import('@azure/openai')
|
||||
|
|
@ -178,6 +185,12 @@ export class chatgpt extends plugin {
|
|||
reg: '^#星火(搜索|查找)助手',
|
||||
fnc: 'searchxhBot'
|
||||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#qwen[sS]*',
|
||||
/** 执行方法 */
|
||||
fnc: 'qwen'
|
||||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: toggleMode === 'at' ? '^[^#][sS]*' : '^#chat[^gpt][sS]*',
|
||||
|
|
@ -315,7 +328,7 @@ export class chatgpt extends plugin {
|
|||
}
|
||||
let ats = e.message.filter(m => m.type === 'at')
|
||||
const isAtMode = Config.toggleMode === 'at'
|
||||
if (isAtMode) ats = ats.filter(item => item.qq !== Bot.uin)
|
||||
if (isAtMode) ats = ats.filter(item => item.qq !== getUin(e))
|
||||
if (ats.length === 0) {
|
||||
if (use === 'api3') {
|
||||
await redis.del(`CHATGPT:QQ_CONVERSATION:${(e.isGroup && Config.groupMerge) ? e.group_id.toString() : e.sender.user_id}`)
|
||||
|
|
@ -365,6 +378,14 @@ export class chatgpt extends plugin {
|
|||
await redis.del(`CHATGPT:CONVERSATIONS:${e.sender.user_id}`)
|
||||
await this.reply('已结束当前对话,请@我进行聊天以开启新的对话', true)
|
||||
}
|
||||
} else if (use === 'qwen') {
|
||||
let c = await redis.get(`CHATGPT:CONVERSATIONS_QWEN:${e.sender.user_id}`)
|
||||
if (!c) {
|
||||
await this.reply('当前没有开启对话', true)
|
||||
} else {
|
||||
await redis.del(`CHATGPT:CONVERSATIONS_QWEN:${e.sender.user_id}`)
|
||||
await this.reply('已结束当前对话,请@我进行聊天以开启新的对话', true)
|
||||
}
|
||||
} else if (use === 'bing') {
|
||||
let c = await redis.get(`CHATGPT:CONVERSATIONS_BING:${e.sender.user_id}`)
|
||||
if (!c) {
|
||||
|
|
@ -426,6 +447,14 @@ export class chatgpt extends plugin {
|
|||
await redis.del(`CHATGPT:CONVERSATIONS:${qq}`)
|
||||
await this.reply(`已结束${atUser}的对话,TA仍可以@我进行聊天以开启新的对话`, true)
|
||||
}
|
||||
} else if (use === 'qwen') {
|
||||
let c = await redis.get(`CHATGPT:CONVERSATIONS_QWEN:${qq}`)
|
||||
if (!c) {
|
||||
await this.reply(`当前${atUser}没有开启对话`, true)
|
||||
} else {
|
||||
await redis.del(`CHATGPT:CONVERSATIONS_QWEN:${qq}`)
|
||||
await this.reply(`已结束${atUser}的对话,TA仍可以@我进行聊天以开启新的对话`, true)
|
||||
}
|
||||
} else if (use === 'bing') {
|
||||
let c = await redis.get(`CHATGPT:CONVERSATIONS_BING:${qq}`)
|
||||
if (!c) {
|
||||
|
|
@ -537,6 +566,18 @@ export class chatgpt extends plugin {
|
|||
}
|
||||
break
|
||||
}
|
||||
case 'qwen': {
|
||||
let qcs = await redis.keys('CHATGPT:CONVERSATIONS_QWEN:*')
|
||||
for (let i = 0; i < qcs.length; i++) {
|
||||
await redis.del(qcs[i])
|
||||
// todo clean last message id
|
||||
if (Config.debug) {
|
||||
logger.info('delete qwen conversation bind: ' + qcs[i])
|
||||
}
|
||||
deleted++
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
await this.reply(`结束了${deleted}个用户的对话。`, true)
|
||||
}
|
||||
|
|
@ -548,7 +589,7 @@ export class chatgpt extends plugin {
|
|||
await this.reply('本功能当前仅支持API3模式', true)
|
||||
return false
|
||||
}
|
||||
if (ats.length === 0 || (ats.length === 1 && e.atme)) {
|
||||
if (ats.length === 0 || (ats.length === 1 && (e.atme || e.atBot))) {
|
||||
let conversationId = _.trimStart(e.msg, '#chatgpt删除对话').trim()
|
||||
if (!conversationId) {
|
||||
await this.reply('指令格式错误,请同时加上对话id或@某人以删除他当前进行的对话', true)
|
||||
|
|
@ -756,48 +797,53 @@ export class chatgpt extends plugin {
|
|||
* #chatgpt
|
||||
*/
|
||||
async chatgpt (e) {
|
||||
let msg = Version.isTrss ? e.msg : e.raw_message
|
||||
let prompt
|
||||
if (this.toggleMode === 'at') {
|
||||
if (!e.raw_message || e.msg?.startsWith('#')) {
|
||||
if (!msg || e.msg?.startsWith('#')) {
|
||||
return false
|
||||
}
|
||||
if (e.isGroup && !e.atme) {
|
||||
if ((e.isGroup || e.group_id) && !(e.atme || e.atBot)) {
|
||||
return false
|
||||
}
|
||||
if (e.user_id == Bot.uin) return false
|
||||
prompt = e.raw_message.trim()
|
||||
if (e.isGroup && typeof this.e.group.getMemberMap === 'function') {
|
||||
let mm = await this.e.group.getMemberMap()
|
||||
let me = mm.get(Bot.uin)
|
||||
let card = me.card
|
||||
let nickname = me.nickname
|
||||
if (nickname && card) {
|
||||
if (nickname.startsWith(card)) {
|
||||
// 例如nickname是"滚筒洗衣机",card是"滚筒"
|
||||
prompt = prompt.replace(`@${nickname}`, '').trim()
|
||||
} else if (card.startsWith(nickname)) {
|
||||
// 例如nickname是"十二",card是"十二|本月已发送1000条消息"
|
||||
prompt = prompt.replace(`@${card}`, '').trim()
|
||||
// 如果是好友,显示的还是昵称
|
||||
prompt = prompt.replace(`@${nickname}`, '').trim()
|
||||
} else {
|
||||
// 互不包含,分别替换
|
||||
if (nickname) {
|
||||
if (e.user_id == getUin(e)) return false
|
||||
prompt = msg.trim()
|
||||
try {
|
||||
if (e.isGroup && typeof this.e.group.getMemberMap === 'function') {
|
||||
let mm = await this.e.group.getMemberMap()
|
||||
let me = mm.get(getUin(e)) || {}
|
||||
let card = me.card
|
||||
let nickname = me.nickname
|
||||
if (nickname && card) {
|
||||
if (nickname.startsWith(card)) {
|
||||
// 例如nickname是"滚筒洗衣机",card是"滚筒"
|
||||
prompt = prompt.replace(`@${nickname}`, '').trim()
|
||||
}
|
||||
if (card) {
|
||||
} else if (card.startsWith(nickname)) {
|
||||
// 例如nickname是"十二",card是"十二|本月已发送1000条消息"
|
||||
prompt = prompt.replace(`@${card}`, '').trim()
|
||||
// 如果是好友,显示的还是昵称
|
||||
prompt = prompt.replace(`@${nickname}`, '').trim()
|
||||
} else {
|
||||
// 互不包含,分别替换
|
||||
if (nickname) {
|
||||
prompt = prompt.replace(`@${nickname}`, '').trim()
|
||||
}
|
||||
if (card) {
|
||||
prompt = prompt.replace(`@${card}`, '').trim()
|
||||
}
|
||||
}
|
||||
} else if (nickname) {
|
||||
prompt = prompt.replace(`@${nickname}`, '').trim()
|
||||
} else if (card) {
|
||||
prompt = prompt.replace(`@${card}`, '').trim()
|
||||
}
|
||||
} else if (nickname) {
|
||||
prompt = prompt.replace(`@${nickname}`, '').trim()
|
||||
} else if (card) {
|
||||
prompt = prompt.replace(`@${card}`, '').trim()
|
||||
}
|
||||
} catch (err) {
|
||||
logger.warn(err)
|
||||
}
|
||||
} else {
|
||||
let ats = e.message.filter(m => m.type === 'at')
|
||||
if (!e.atme && ats.length > 0) {
|
||||
if (!(e.atme || e.atBot) && ats.length > 0) {
|
||||
if (Config.debug) {
|
||||
logger.mark('艾特别人了,没艾特我,忽略#chat')
|
||||
}
|
||||
|
|
@ -1023,6 +1069,10 @@ export class chatgpt extends plugin {
|
|||
key = `CHATGPT:CONVERSATIONS_AZURE:${e.sender.user_id}`
|
||||
break
|
||||
}
|
||||
case 'qwen': {
|
||||
key = `CHATGPT:CONVERSATIONS_QWEN:${(e.isGroup && Config.groupMerge) ? e.group_id.toString() : e.sender.user_id}`
|
||||
break
|
||||
}
|
||||
}
|
||||
let ctime = new Date()
|
||||
previousConversation = (key ? await redis.get(key) : null) || JSON.stringify({
|
||||
|
|
@ -1053,9 +1103,7 @@ export class chatgpt extends plugin {
|
|||
logger.mark({ conversation })
|
||||
}
|
||||
let chatMessage = await this.sendMessage(prompt, conversation, use, e)
|
||||
if (chatMessage.image) {
|
||||
this.setContext('solveBingCaptcha', false, 60)
|
||||
await e.reply([chatMessage.text, segment.image(`base64://${chatMessage.image}`)])
|
||||
if (chatMessage?.noMsg) {
|
||||
return false
|
||||
}
|
||||
// 处理星火和bard图片
|
||||
|
|
@ -1311,7 +1359,7 @@ export class chatgpt extends plugin {
|
|||
return false
|
||||
}
|
||||
let ats = e.message.filter(m => m.type === 'at')
|
||||
if (!e.atme && ats.length > 0) {
|
||||
if (!(e.atme || e.atBot) && ats.length > 0) {
|
||||
if (Config.debug) {
|
||||
logger.mark('艾特别人了,没艾特我,忽略#chat1')
|
||||
}
|
||||
|
|
@ -1330,7 +1378,7 @@ export class chatgpt extends plugin {
|
|||
return false
|
||||
}
|
||||
let ats = e.message.filter(m => m.type === 'at')
|
||||
if (!e.atme && ats.length > 0) {
|
||||
if (!(e.atme || e.atBot) && ats.length > 0) {
|
||||
if (Config.debug) {
|
||||
logger.mark('艾特别人了,没艾特我,忽略#chat3')
|
||||
}
|
||||
|
|
@ -1349,7 +1397,7 @@ export class chatgpt extends plugin {
|
|||
return false
|
||||
}
|
||||
let ats = e.message.filter(m => m.type === 'at')
|
||||
if (!e.atme && ats.length > 0) {
|
||||
if (!(e.atme || e.atBot) && ats.length > 0) {
|
||||
if (Config.debug) {
|
||||
logger.mark('艾特别人了,没艾特我,忽略#chatglm')
|
||||
}
|
||||
|
|
@ -1368,7 +1416,7 @@ export class chatgpt extends plugin {
|
|||
return false
|
||||
}
|
||||
let ats = e.message.filter(m => m.type === 'at')
|
||||
if (!e.atme && ats.length > 0) {
|
||||
if (!(e.atme || e.atBot) && ats.length > 0) {
|
||||
if (Config.debug) {
|
||||
logger.mark('艾特别人了,没艾特我,忽略#bing')
|
||||
}
|
||||
|
|
@ -1387,7 +1435,7 @@ export class chatgpt extends plugin {
|
|||
return false
|
||||
}
|
||||
let ats = e.message.filter(m => m.type === 'at')
|
||||
if (!e.atme && ats.length > 0) {
|
||||
if (!(e.atme || e.atBot) && ats.length > 0) {
|
||||
if (Config.debug) {
|
||||
logger.mark('艾特别人了,没艾特我,忽略#claude2')
|
||||
}
|
||||
|
|
@ -1406,7 +1454,7 @@ export class chatgpt extends plugin {
|
|||
return false
|
||||
}
|
||||
let ats = e.message.filter(m => m.type === 'at')
|
||||
if (!e.atme && ats.length > 0) {
|
||||
if (!(e.atme || e.atBot) && ats.length > 0) {
|
||||
if (Config.debug) {
|
||||
logger.mark('艾特别人了,没艾特我,忽略#claude')
|
||||
}
|
||||
|
|
@ -1420,12 +1468,31 @@ export class chatgpt extends plugin {
|
|||
return true
|
||||
}
|
||||
|
||||
async qwen (e) {
|
||||
if (!Config.allowOtherMode) {
|
||||
return false
|
||||
}
|
||||
let ats = e.message.filter(m => m.type === 'at')
|
||||
if (!(e.atme || e.atBot) && ats.length > 0) {
|
||||
if (Config.debug) {
|
||||
logger.mark('艾特别人了,没艾特我,忽略#xh')
|
||||
}
|
||||
return false
|
||||
}
|
||||
let prompt = _.replace(e.raw_message.trimStart(), '#qwen', '').trim()
|
||||
if (prompt.length === 0) {
|
||||
return false
|
||||
}
|
||||
await this.abstractChat(e, prompt, 'qwen')
|
||||
return true
|
||||
}
|
||||
|
||||
async xh (e) {
|
||||
if (!Config.allowOtherMode) {
|
||||
return false
|
||||
}
|
||||
let ats = e.message.filter(m => m.type === 'at')
|
||||
if (!e.atme && ats.length > 0) {
|
||||
if (!(e.atme || e.atBot) && ats.length > 0) {
|
||||
if (Config.debug) {
|
||||
logger.mark('艾特别人了,没艾特我,忽略#xh')
|
||||
}
|
||||
|
|
@ -1464,7 +1531,7 @@ export class chatgpt extends plugin {
|
|||
chatViewBotName: Config.chatViewBotName || '',
|
||||
entry: cacheData.file,
|
||||
userImg: `https://q1.qlogo.cn/g?b=qq&s=0&nk=${e.sender.user_id}`,
|
||||
botImg: `https://q1.qlogo.cn/g?b=qq&s=0&nk=${Bot.uin}`,
|
||||
botImg: `https://q1.qlogo.cn/g?b=qq&s=0&nk=${getUin(e)}`,
|
||||
cacheHost: Config.serverHost,
|
||||
qq: e.sender.user_id
|
||||
})
|
||||
|
|
@ -1573,33 +1640,33 @@ export class chatgpt extends plugin {
|
|||
opt.qq = e.sender.user_id
|
||||
opt.nickname = e.sender.card
|
||||
opt.groupName = e.group.name
|
||||
opt.botName = e.isGroup ? (e.group.pickMember(Bot.uin).card || e.group.pickMember(Bot.uin).nickname) : Bot.nickname
|
||||
opt.botName = e.isGroup ? (e.group.pickMember(getUin(e)).card || e.group.pickMember(getUin(e)).nickname) : e.bot.nickname
|
||||
let master = (await getMasterQQ())[0]
|
||||
if (master && e.group) {
|
||||
opt.masterName = e.group.pickMember(parseInt(master)).card || e.group.pickMember(parseInt(master)).nickname
|
||||
}
|
||||
if (master && !e.group) {
|
||||
opt.masterName = Bot.getFriendList().get(parseInt(master))?.nickname
|
||||
opt.masterName = e.bot.getFriendList().get(parseInt(master))?.nickname
|
||||
}
|
||||
let latestChat = await e.group.getChatHistory(0, 1)
|
||||
let seq = latestChat[0].seq
|
||||
let chats = []
|
||||
while (chats.length < Config.groupContextLength) {
|
||||
let chatHistory = await e.group.getChatHistory(seq, 20)
|
||||
chats.push(...chatHistory)
|
||||
}
|
||||
chats = chats.slice(0, Config.groupContextLength)
|
||||
let mm = await e.group.getMemberMap()
|
||||
chats.forEach(chat => {
|
||||
let sender = mm.get(chat.sender.user_id)
|
||||
chat.sender = sender
|
||||
})
|
||||
// console.log(chats)
|
||||
opt.chats = chats
|
||||
opt.chats = await getChatHistoryGroup(e, Config.groupContextLength)
|
||||
} catch (err) {
|
||||
logger.warn('获取群聊聊天记录失败,本次对话不携带聊天记录', err)
|
||||
}
|
||||
}
|
||||
let toSummaryFileContent
|
||||
try {
|
||||
if (e.source) {
|
||||
let msgs = e.isGroup ? await e.group.getChatHistory(e.source.seq, 1) : await e.friend.getChatHistory(e.source.time, 1)
|
||||
let sourceMsg = msgs[0]
|
||||
let fileMsgElem = sourceMsg.message.find(msg => msg.type === 'file')
|
||||
if (fileMsgElem) {
|
||||
toSummaryFileContent = await extractContentFromFile(fileMsgElem, e)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.warn('读取文件内容出错, 忽略文件内容', err)
|
||||
}
|
||||
opt.toSummaryFileContent = toSummaryFileContent
|
||||
} else {
|
||||
// 重新创建client,因为token可能换到别的了
|
||||
if (bingToken?.indexOf('=') > -1) {
|
||||
|
|
@ -1652,16 +1719,24 @@ export class chatgpt extends plugin {
|
|||
if (Config.debug) {
|
||||
logger.mark(`开始生成内容:${response.details.imageTag}`)
|
||||
}
|
||||
let client = new BingDrawClient({
|
||||
baseUrl: Config.sydneyReverseProxy,
|
||||
userToken: bingToken
|
||||
})
|
||||
await redis.set(`CHATGPT:DRAW:${e.sender.user_id}`, 'c', { EX: 30 })
|
||||
try {
|
||||
await client.getImages(response.details.imageTag, e)
|
||||
} catch (err) {
|
||||
await redis.del(`CHATGPT:DRAW:${e.sender.user_id}`)
|
||||
await e.reply('绘图失败:' + err)
|
||||
if (Config.bingAPDraw) {
|
||||
// 调用第三方API进行绘图
|
||||
let apDraw = new APTool()
|
||||
apDraw.func({
|
||||
prompt: response.details.imageTag
|
||||
}, e)
|
||||
} else {
|
||||
let client = new BingDrawClient({
|
||||
baseUrl: Config.sydneyReverseProxy,
|
||||
userToken: bingToken
|
||||
})
|
||||
await redis.set(`CHATGPT:DRAW:${e.sender.user_id}`, 'c', { EX: 30 })
|
||||
try {
|
||||
await client.getImages(response.details.imageTag, e)
|
||||
} catch (err) {
|
||||
await redis.del(`CHATGPT:DRAW:${e.sender.user_id}`)
|
||||
await e.reply('绘图失败:' + err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1680,7 +1755,7 @@ export class chatgpt extends plugin {
|
|||
const { maxConv } = error
|
||||
if (message && typeof message === 'string' && message.indexOf('CaptchaChallenge') > -1) {
|
||||
if (bingToken) {
|
||||
if (maxConv > 20) {
|
||||
if (maxConv >= 20) {
|
||||
// maxConv为30说明token有效,可以通过解验证码码服务过码
|
||||
await e.reply('出现必应验证码,尝试解决中')
|
||||
try {
|
||||
|
|
@ -1699,8 +1774,11 @@ export class chatgpt extends plugin {
|
|||
}
|
||||
} else {
|
||||
// 未登录用户maxConv目前为5或10,出验证码没救
|
||||
logger.warn(`token [${bingToken}] 无效或已过期`)
|
||||
logger.warn(`token [${bingToken}] 无效或已过期,如确认token无误,请前往网页版必应对话一次`)
|
||||
retry = 0
|
||||
}
|
||||
} else {
|
||||
retry = 0
|
||||
}
|
||||
} else
|
||||
if (message && typeof message === 'string' && message.indexOf('限流') > -1) {
|
||||
|
|
@ -1756,10 +1834,10 @@ export class chatgpt extends plugin {
|
|||
text: errorMessage,
|
||||
error: true
|
||||
}
|
||||
} else {
|
||||
} else if (response?.response) {
|
||||
return {
|
||||
text: response?.response,
|
||||
quote: response.quote,
|
||||
quote: response?.quote,
|
||||
suggestedResponses: response.suggestedResponses,
|
||||
conversationId: response.conversationId,
|
||||
clientId: response.clientId,
|
||||
|
|
@ -1768,6 +1846,11 @@ export class chatgpt extends plugin {
|
|||
parentMessageId: response.apology ? conversation.parentMessageId : response.messageId,
|
||||
bingToken
|
||||
}
|
||||
} else {
|
||||
logger.debug('no message')
|
||||
return {
|
||||
noMsg: true
|
||||
}
|
||||
}
|
||||
}
|
||||
case 'api3': {
|
||||
|
|
@ -1856,40 +1939,30 @@ export class chatgpt extends plugin {
|
|||
debug: Config.debug,
|
||||
proxy: Config.proxy
|
||||
})
|
||||
let fileUrl, filename, attachments
|
||||
if (e.source && e.source.message === '[文件]') {
|
||||
if (e.isGroup) {
|
||||
let source = (await e.group.getChatHistory(e.source.seq, 1))[0]
|
||||
let file = source.message.find(m => m.type === 'file')
|
||||
if (file) {
|
||||
filename = file.name
|
||||
fileUrl = await e.group.getFileUrl(file.fid)
|
||||
}
|
||||
} else {
|
||||
let source = (await e.friend.getChatHistory(e.source.time, 1))[0]
|
||||
let file = source.message.find(m => m.type === 'file')
|
||||
if (file) {
|
||||
filename = file.name
|
||||
fileUrl = await e.group.getFileUrl(file.fid)
|
||||
let toSummaryFileContent
|
||||
try {
|
||||
if (e.source) {
|
||||
let msgs = e.isGroup ? await e.group.getChatHistory(e.source.seq, 1) : await e.friend.getChatHistory(e.source.time, 1)
|
||||
let sourceMsg = msgs[0]
|
||||
let fileMsgElem = sourceMsg.message.find(msg => msg.type === 'file')
|
||||
if (fileMsgElem) {
|
||||
toSummaryFileContent = await extractContentFromFile(fileMsgElem, e)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.warn('读取文件内容出错, 忽略文件内容', err)
|
||||
}
|
||||
if (fileUrl) {
|
||||
logger.info('文件地址:' + fileUrl)
|
||||
mkdirs('data/chatgpt/files')
|
||||
let destinationPath = 'data/chatgpt/files/' + filename
|
||||
const response = await fetch(fileUrl)
|
||||
const fileStream = fs.createWriteStream(destinationPath)
|
||||
await new Promise((resolve, reject) => {
|
||||
response.body.pipe(fileStream)
|
||||
response.body.on('error', (err) => {
|
||||
reject(err)
|
||||
})
|
||||
fileStream.on('finish', () => {
|
||||
resolve()
|
||||
})
|
||||
|
||||
let attachments = []
|
||||
if (toSummaryFileContent?.content) {
|
||||
attachments.push({
|
||||
extracted_content: toSummaryFileContent.content,
|
||||
file_name: toSummaryFileContent.name,
|
||||
file_type: 'pdf',
|
||||
file_size: 200312,
|
||||
totalPages: 20
|
||||
})
|
||||
attachments = [await client.convertDocument(destinationPath, filename)]
|
||||
logger.info(toSummaryFileContent.content)
|
||||
}
|
||||
if (conversationId) {
|
||||
return await client.sendMessage(prompt, conversationId, attachments)
|
||||
|
|
@ -1939,6 +2012,57 @@ export class chatgpt extends plugin {
|
|||
let completion = choices[0].message
|
||||
return { text: completion.content, message: completion }
|
||||
}
|
||||
case 'qwen': {
|
||||
let completionParams = {
|
||||
parameters: {
|
||||
top_p: Config.qwenTopP || 0.5,
|
||||
top_k: Config.qwenTopK || 50,
|
||||
seed: Config.qwenSeed > 0 ? Config.qwenSeed : Math.floor(Math.random() * 114514),
|
||||
temperature: Config.qwenTemperature || 1,
|
||||
enable_search: !!Config.qwenEnableSearch
|
||||
}
|
||||
}
|
||||
if (Config.qwenModel) {
|
||||
completionParams.model = Config.qwenModel
|
||||
}
|
||||
const currentDate = new Date().toISOString().split('T')[0]
|
||||
async function um (message) {
|
||||
return await upsertMessage(message, 'QWEN')
|
||||
}
|
||||
async function gm (id) {
|
||||
return await getMessageById(id, 'QWEN')
|
||||
}
|
||||
let opts = {
|
||||
apiKey: Config.qwenApiKey,
|
||||
debug: false,
|
||||
upsertMessage: um,
|
||||
getMessageById: gm,
|
||||
systemMessage: `You are ${Config.assistantLabel} ${useCast?.api || Config.promptPrefixOverride || defaultPropmtPrefix}
|
||||
Current date: ${currentDate}`,
|
||||
completionParams,
|
||||
assistantLabel: Config.assistantLabel,
|
||||
fetch: newFetch
|
||||
}
|
||||
this.qwenApi = new QwenApi(opts)
|
||||
let option = {
|
||||
timeoutMs: 600000,
|
||||
completionParams
|
||||
}
|
||||
if (conversation) {
|
||||
if (!conversation.conversationId) {
|
||||
conversation.conversationId = uuid()
|
||||
}
|
||||
option = Object.assign(option, conversation)
|
||||
}
|
||||
let msg
|
||||
try {
|
||||
msg = await this.qwenApi.sendMessage(prompt, option)
|
||||
} catch (err) {
|
||||
logger.error(err)
|
||||
throw new Error(err)
|
||||
}
|
||||
return msg
|
||||
}
|
||||
case 'bard': {
|
||||
// 处理cookie
|
||||
const matchesPSID = /__Secure-1PSID=([^;]+)/.exec(Config.bardPsid)
|
||||
|
|
@ -2005,30 +2129,16 @@ export class chatgpt extends plugin {
|
|||
opt.groupId = e.group_id
|
||||
opt.qq = e.sender.user_id
|
||||
opt.nickname = e.sender.card
|
||||
opt.groupName = e.group.name
|
||||
opt.botName = e.isGroup ? (e.group.pickMember(Bot.uin).card || e.group.pickMember(Bot.uin).nickname) : Bot.nickname
|
||||
opt.groupName = e.group.name || e.group_name
|
||||
opt.botName = e.isGroup ? (e.group.pickMember(getUin(e)).card || e.group.pickMember(getUin(e)).nickname) : e.bot.nickname
|
||||
let master = (await getMasterQQ())[0]
|
||||
if (master && e.group) {
|
||||
opt.masterName = e.group.pickMember(parseInt(master)).card || e.group.pickMember(parseInt(master)).nickname
|
||||
}
|
||||
if (master && !e.group) {
|
||||
opt.masterName = Bot.getFriendList().get(parseInt(master))?.nickname
|
||||
opt.masterName = e.bot.getFriendList().get(parseInt(master))?.nickname
|
||||
}
|
||||
let latestChat = await e.group.getChatHistory(0, 1)
|
||||
let seq = latestChat[0].seq
|
||||
let chats = []
|
||||
while (chats.length < Config.groupContextLength) {
|
||||
let chatHistory = await e.group.getChatHistory(seq, 20)
|
||||
chats.push(...chatHistory.reverse())
|
||||
}
|
||||
chats = chats.slice(0, Config.groupContextLength)
|
||||
// 太多可能会干扰AI对自身qq号和用户qq的判断,感觉gpt3.5也处理不了那么多信息
|
||||
chats = chats > 50 ? 50 : chats
|
||||
let mm = await e.group.getMemberMap()
|
||||
chats.forEach(chat => {
|
||||
let sender = mm.get(chat.sender.user_id)
|
||||
chat.sender = sender
|
||||
})
|
||||
let chats = await getChatHistoryGroup(e, Config.groupContextLength)
|
||||
opt.chats = chats
|
||||
const namePlaceholder = '[name]'
|
||||
const defaultBotName = 'ChatGPT'
|
||||
|
|
@ -2050,7 +2160,7 @@ export class chatgpt extends plugin {
|
|||
system += chats
|
||||
.map(chat => {
|
||||
let sender = chat.sender || {}
|
||||
// if (sender.user_id === Bot.uin && chat.raw_message.startsWith('建议的回复')) {
|
||||
// if (sender.user_id === e.bot.uin && chat.raw_message.startsWith('建议的回复')) {
|
||||
if (chat.raw_message.startsWith('建议的回复')) {
|
||||
// 建议的回复太容易污染设定导致对话太固定跑偏了
|
||||
return ''
|
||||
|
|
@ -2097,6 +2207,9 @@ export class chatgpt extends plugin {
|
|||
}
|
||||
option.systemMessage = system
|
||||
if (conversation) {
|
||||
if (!conversation.conversationId) {
|
||||
conversation.conversationId = uuid()
|
||||
}
|
||||
option = Object.assign(option, conversation)
|
||||
}
|
||||
if (Config.smartMode) {
|
||||
|
|
@ -2178,7 +2291,7 @@ export class chatgpt extends plugin {
|
|||
logger.mark(logger.green('【ChatGPT-Plugin】插件avocado-plugin未安装') + ',安装后可查看最近热映电影与体验可玩性更高的点歌工具。\n可前往 https://github.com/Qz-Sean/avocado-plugin 获取')
|
||||
}
|
||||
if (e.isGroup) {
|
||||
let botInfo = await Bot.getGroupMemberInfo(e.group_id, Bot.uin, true)
|
||||
let botInfo = await e.bot.getGroupMemberInfo(e.group_id, getUin(e), true)
|
||||
if (botInfo.role !== 'member') {
|
||||
// 管理员才给这些工具
|
||||
tools.push(...[new EditCardTool(), new JinyanTool(), new KickOutTool(), new HandleMessageMsgTool(), new SetTitleTool()])
|
||||
|
|
@ -2430,7 +2543,7 @@ export class chatgpt extends plugin {
|
|||
}
|
||||
if (bots.code === 0) {
|
||||
if (bots.data.pageList.length > 0) {
|
||||
this.reply(await makeForwardMsg(this.e, bots.data.pageList.map(msg => `${msg.bot.botId} - ${msg.bot.botName}`)))
|
||||
this.reply(await makeForwardMsg(this.e, bots.data.pageList.map(msg => `${msg.e.bot.botId} - ${msg.e.bot.botName}`)))
|
||||
} else {
|
||||
await e.reply('未查到相关助手', true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,10 @@ export class Entertainment extends plugin {
|
|||
reg: '^#(|最新)词云(\\d{1,2}h{0,1}|)$',
|
||||
fnc: 'wordcloud_latest'
|
||||
},
|
||||
{
|
||||
reg: '^#(我的)?(本月|本周|今日)?词云$',
|
||||
fnc: 'wordcloud_new'
|
||||
},
|
||||
{
|
||||
reg: '^#((寄批踢|gpt|GPT)?翻.*|chatgpt翻译帮助)',
|
||||
fnc: 'translate'
|
||||
|
|
@ -215,10 +219,10 @@ ${translateLangLabels}
|
|||
|
||||
const regExp = /词云(\d{0,2})(|h)/
|
||||
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) {
|
||||
await e.reply('最多只能统计24小时内的记录哦')
|
||||
await e.reply('最多只能统计24小时内的记录哦,你可以使用#本周词云和#本月词云获取更长时间的统计~')
|
||||
return false
|
||||
}
|
||||
await e.reply('在统计啦,请稍等...')
|
||||
|
|
@ -236,6 +240,56 @@ ${translateLangLabels}
|
|||
}
|
||||
}
|
||||
|
||||
async wordcloud_new (e) {
|
||||
if (e.isGroup) {
|
||||
let groupId = e.group_id
|
||||
let userId
|
||||
if (e.msg.includes('我的')) {
|
||||
userId = e.sender.user_id
|
||||
}
|
||||
let at = e.message.find(m => m.type === 'at')
|
||||
if (at) {
|
||||
userId = at.qq
|
||||
}
|
||||
let lock = await redis.get(`CHATGPT:WORDCLOUD_NEW:${groupId}_${userId}`)
|
||||
if (lock) {
|
||||
await e.reply('别着急,上次统计还没完呢')
|
||||
return true
|
||||
}
|
||||
await e.reply('在统计啦,请稍等...')
|
||||
let duration = 24
|
||||
if (e.msg.includes('本周')) {
|
||||
const now = new Date() // Get the current date and time
|
||||
let day = now.getDay()
|
||||
let diff = now.getDate() - day + (day === 0 ? -6 : 1)
|
||||
const startOfWeek = new Date(new Date().setDate(diff))
|
||||
startOfWeek.setHours(0, 0, 0, 0) // Set the time to midnight (start of the day)
|
||||
duration = (now - startOfWeek) / 1000 / 60 / 60
|
||||
} else if (e.msg.includes('本月')) {
|
||||
const now = new Date() // Get the current date and time
|
||||
const startOfMonth = new Date(new Date().setDate(0))
|
||||
startOfMonth.setHours(0, 0, 0, 0) // Set the time to midnight (start of the day)
|
||||
duration = (now - startOfMonth) / 1000 / 60 / 60
|
||||
} else {
|
||||
// 默认今天
|
||||
const now = new Date()
|
||||
const startOfToday = new Date() // Get the current date and time
|
||||
startOfToday.setHours(0, 0, 0, 0) // Set the time to midnight (start of the day)
|
||||
duration = (now - startOfToday) / 1000 / 60 / 60
|
||||
}
|
||||
await redis.set(`CHATGPT:WORDCLOUD_NEW:${groupId}_${userId}`, '1', { EX: 600 })
|
||||
try {
|
||||
await makeWordcloud(e, e.group_id, duration, userId)
|
||||
} catch (err) {
|
||||
logger.error(err)
|
||||
await e.reply(err)
|
||||
}
|
||||
await redis.del(`CHATGPT:WORDCLOUD_NEW:${groupId}_${userId}`)
|
||||
} else {
|
||||
await e.reply('请在群里发送此命令')
|
||||
}
|
||||
}
|
||||
|
||||
async combineEmoj (e) {
|
||||
let left = e.msg.codePointAt(0).toString(16).toLowerCase()
|
||||
let right = e.msg.codePointAt(2).toString(16).toLowerCase()
|
||||
|
|
@ -296,7 +350,7 @@ ${translateLangLabels}
|
|||
let groupId = e.msg.replace(/^#chatgpt打招呼/, '')
|
||||
logger.info(groupId)
|
||||
groupId = parseInt(groupId)
|
||||
if (groupId && !Bot.getGroupList().get(groupId)) {
|
||||
if (groupId && !e.bot.getGroupList().get(groupId)) {
|
||||
await e.reply('机器人不在这个群里!')
|
||||
return
|
||||
}
|
||||
|
|
@ -310,7 +364,7 @@ ${translateLangLabels}
|
|||
if (!groupId) {
|
||||
await e.reply(sendable)
|
||||
} else {
|
||||
await Bot.sendGroupMsg(groupId, sendable)
|
||||
await e.bot.sendGroupMsg(groupId, sendable)
|
||||
await e.reply('发送成功!')
|
||||
}
|
||||
}
|
||||
|
|
@ -325,7 +379,7 @@ ${translateLangLabels}
|
|||
continue
|
||||
}
|
||||
let groupId = parseInt(element)
|
||||
if (Bot.getGroupList().get(groupId)) {
|
||||
if (this.e.bot.getGroupList().get(groupId)) {
|
||||
// 打招呼概率
|
||||
if (Math.floor(Math.random() * 100) < Config.helloProbability) {
|
||||
let message = await generateHello()
|
||||
|
|
@ -381,12 +435,12 @@ ${translateLangLabels}
|
|||
}
|
||||
}
|
||||
if (useSilk) {
|
||||
await Bot.sendGroupMsg(groupId, await uploadRecord(audio))
|
||||
await this.e.bot.sendGroupMsg(groupId, await uploadRecord(audio))
|
||||
} else {
|
||||
await Bot.sendGroupMsg(groupId, segment.record(audio))
|
||||
await this.e.bot.sendGroupMsg(groupId, segment.record(audio))
|
||||
}
|
||||
} else {
|
||||
await Bot.sendGroupMsg(groupId, message)
|
||||
await this.e.bot.sendGroupMsg(groupId, message)
|
||||
}
|
||||
} else {
|
||||
logger.info(`时机未到,这次就不打招呼给群聊${groupId}了`)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import plugin from '../../../lib/plugins/plugin.js'
|
||||
import { render } from '../utils/common.js'
|
||||
import { render, getUin } from '../utils/common.js'
|
||||
import { Config } from '../utils/config.js'
|
||||
import { KeyvFile } from 'keyv-file'
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ export class history extends plugin {
|
|||
async history (e) {
|
||||
let use = await redis.get('CHATGPT:USE') || 'api'
|
||||
let chat = []
|
||||
let filtered = e.message.filter(m => m.type === 'at').filter(m => m.qq !== Bot.uin)
|
||||
let filtered = e.message.filter(m => m.type === 'at').filter(m => m.qq !== getUin(e))
|
||||
let queryUser = e.sender.user_id
|
||||
let user = e.sender
|
||||
if (filtered.length > 0) {
|
||||
|
|
@ -66,12 +66,12 @@ export class history extends plugin {
|
|||
let parentMessageId = previousConversation.parentMessageId
|
||||
let tmp = {}
|
||||
const previousCachedMessages = getMessagesForConversation(conversation.messages, parentMessageId)
|
||||
.map((message) => {
|
||||
return {
|
||||
text: message.message,
|
||||
author: message.role === 'User' ? 'user' : 'bot'
|
||||
}
|
||||
})
|
||||
.map((message) => {
|
||||
return {
|
||||
text: message.message,
|
||||
author: message.role === 'User' ? 'user' : 'bot'
|
||||
}
|
||||
})
|
||||
previousCachedMessages.forEach(m => {
|
||||
if (m.author === 'user') {
|
||||
tmp.prompt = m.text
|
||||
|
|
@ -99,8 +99,8 @@ export class history extends plugin {
|
|||
name: user.card || user.nickname || user.user_id
|
||||
},
|
||||
bot: {
|
||||
qq: Bot.uin,
|
||||
name: Bot.nickname
|
||||
qq: getUin(e),
|
||||
name: e.bot.nickname
|
||||
},
|
||||
chat
|
||||
}, {})
|
||||
|
|
|
|||
|
|
@ -124,6 +124,11 @@ export class ChatgptManagement extends plugin {
|
|||
fnc: 'useBardBasedSolution',
|
||||
permission: 'master'
|
||||
},
|
||||
{
|
||||
reg: '^#chatgpt切换(通义千问|qwen|千问)$',
|
||||
fnc: 'useQwenSolution',
|
||||
permission: 'master'
|
||||
},
|
||||
{
|
||||
reg: '^#chatgpt(必应|Bing)切换',
|
||||
fnc: 'changeBingTone',
|
||||
|
|
@ -294,9 +299,9 @@ ${userSetting.useTTS === true ? '当前语音模式为' + Config.ttsMode : ''}`
|
|||
const matchCommand = e.msg.match(/^#(chatgpt)?(vits|azure|vox)?语音(服务|角色列表)/)
|
||||
if (matchCommand[3] === '服务') {
|
||||
await this.reply(`当前支持vox、vits、azure语音服务,可使用'#(vox|azure|vits)语音角色列表'查看支持的语音角色。
|
||||
|
||||
|
||||
vits语音:主要有赛马娘,原神中文,原神日语,崩坏 3 的音色、结果有随机性,语调可能很奇怪。
|
||||
|
||||
|
||||
vox语音:Voicevox 是一款由日本 DeNA 开发的语音合成软件,它可以将文本转换为自然流畅的语音。Voicevox 支持多种语言和声音,可以用于制作各种语音内容,如动画、游戏、广告等。Voicevox 还提供了丰富的调整选项,可以调整声音的音调、速度、音量等参数,以满足不同需求。除了桌面版软件外,Voicevox 还提供了 Web 版本和 API 接口,方便开发者在各种平台上使用。
|
||||
|
||||
azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,它可以帮助开发者将语音转换为文本、将文本转换为语音、实现自然语言理解和对话等功能。Azure 语音支持多种语言和声音,可以用于构建各种语音应用程序,如智能客服、语音助手、自动化电话系统等。Azure 语音还提供了丰富的 API 和 SDK,方便开发者在各种平台上集成使用。
|
||||
|
|
@ -876,6 +881,7 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
await this.reply('当前已经是星火模式了')
|
||||
}
|
||||
}
|
||||
|
||||
async useAzureBasedSolution () {
|
||||
let use = await redis.get('CHATGPT:USE')
|
||||
if (use !== 'azure') {
|
||||
|
|
@ -896,6 +902,16 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
}
|
||||
}
|
||||
|
||||
async useQwenSolution () {
|
||||
let use = await redis.get('CHATGPT:USE')
|
||||
if (use !== 'qwen') {
|
||||
await redis.set('CHATGPT:USE', 'qwen')
|
||||
await this.reply('已切换到基于通义千问的解决方案')
|
||||
} else {
|
||||
await this.reply('当前已经是通义千问模式了')
|
||||
}
|
||||
}
|
||||
|
||||
async changeBingTone (e) {
|
||||
let tongStyle = e.msg.replace(/^#chatgpt(必应|Bing)切换/, '')
|
||||
if (!tongStyle) {
|
||||
|
|
@ -1002,7 +1018,7 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
}
|
||||
} else if (match) {
|
||||
const groupId = parseInt(match[1], 10)
|
||||
if (Bot.getGroupList().get(groupId)) {
|
||||
if (e.bot.getGroupList().get(groupId)) {
|
||||
if (await redis.get(`CHATGPT:SHUT_UP:${groupId}`)) {
|
||||
await redis.del(`CHATGPT:SHUT_UP:${groupId}`)
|
||||
await redis.set(`CHATGPT:SHUT_UP:${groupId}`, '1', { EX: time })
|
||||
|
|
@ -1052,7 +1068,7 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
return false
|
||||
}
|
||||
const groupId = parseInt(match[1], 10)
|
||||
if (Bot.getGroupList().get(groupId)) {
|
||||
if (e.bot.getGroupList().get(groupId)) {
|
||||
if (await redis.get(`CHATGPT:SHUT_UP:${groupId}`)) {
|
||||
await redis.del(`CHATGPT:SHUT_UP:${groupId}`)
|
||||
await e.reply(`好的主人,我终于又可以在群${groupId}和大家聊天了`)
|
||||
|
|
@ -1287,9 +1303,9 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie
|
|||
const viewHost = Config.serverHost ? `http://${Config.serverHost}/` : `http://${await getPublicIP()}:${Config.serverPort || 3321}/`
|
||||
const otp = randomString(6)
|
||||
await redis.set(
|
||||
`CHATGPT:SERVER_QUICK`,
|
||||
otp,
|
||||
{ EX: 60000 }
|
||||
'CHATGPT:SERVER_QUICK',
|
||||
otp,
|
||||
{ EX: 60000 }
|
||||
)
|
||||
await this.reply(`请登录http://tools.alcedogroup.com/login?server=${viewHost}&otp=${otp}`, true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import plugin from '../../../lib/plugins/plugin.js'
|
|||
import fs from 'fs'
|
||||
import _ from 'lodash'
|
||||
import { Config } from '../utils/config.js'
|
||||
import { getMasterQQ, limitString, makeForwardMsg, maskQQ } from '../utils/common.js'
|
||||
import { getMasterQQ, limitString, makeForwardMsg, maskQQ, getUin } from '../utils/common.js'
|
||||
import { deleteOnePrompt, getPromptByName, readPrompts, saveOnePrompt } from '../utils/prompts.js'
|
||||
import AzureTTS from "../utils/tts/microsoft-azure.js";
|
||||
export class help extends plugin {
|
||||
|
|
@ -157,7 +157,8 @@ export class help extends plugin {
|
|||
const keyMap = {
|
||||
api: 'promptPrefixOverride',
|
||||
Custom: 'sydney',
|
||||
claude: 'slackClaudeGlobalPreset'
|
||||
claude: 'slackClaudeGlobalPreset',
|
||||
qwen: 'promptPrefixOverride'
|
||||
}
|
||||
|
||||
if (keyMap[use]) {
|
||||
|
|
@ -246,7 +247,7 @@ export class help extends plugin {
|
|||
async removeSharePrompt (e) {
|
||||
let master = (await getMasterQQ())[0]
|
||||
let name = e.msg.replace(/^#(chatgpt|ChatGPT)(删除|取消|撤销)共享设定/, '')
|
||||
let response = await fetch(`https://chatgpt.roki.best/prompt?name=${name}&qq=${master || (Bot.uin + '')}`, {
|
||||
let response = await fetch(`https://chatgpt.roki.best/prompt?name=${name}&qq=${master || (getUin(e) + '')}`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'FROM-CHATGPT': 'ikechan8370'
|
||||
|
|
@ -354,7 +355,7 @@ export class help extends plugin {
|
|||
let toUploadBody = {
|
||||
title: currentUse,
|
||||
prompt: content,
|
||||
qq: master || (Bot.uin + ''), // 上传者设定为主人qq或机器人qq
|
||||
qq: master || (getUin(this.e) + ''), // 上传者设定为主人qq或机器人qq
|
||||
use: extraData.use === 'Custom' ? 'Sydney' : 'ChatGPT',
|
||||
r18,
|
||||
description
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue