mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-16 05:17:10 +00:00
feat: experimental markdown support (#658)
* feat: test button * fix: enter * fix: bing suggested * fix: bing suggested * fix: bing suggested * fix: button under icqq * fix: 删除suno心跳 * fix: add default md handler * fix: duplicate this * fix: add a button * Update md.js * Update md.js * fix: api stream * fix: claude.ai * fix: md enhancement * fix: optional buttons * fix: mode name * fix: ignore md while not enable md
This commit is contained in:
parent
58e6201e6e
commit
cb3e57bea3
11 changed files with 610 additions and 126 deletions
352
apps/button.js
Normal file
352
apps/button.js
Normal file
|
|
@ -0,0 +1,352 @@
|
|||
import plugin from '../../../lib/plugins/plugin.js'
|
||||
import {Config} from "../utils/config.js";
|
||||
|
||||
const PLUGIN_CHAT = 'ChatGpt 对话'
|
||||
const PLUGIN_MANAGEMENT = 'ChatGPT-Plugin 管理'
|
||||
const PLUGIN_ENTERTAINMENT = 'ChatGPT-Plugin 娱乐小功能'
|
||||
const FUNCTION_CHAT = 'chatgpt'
|
||||
const FUNCTION_CHAT3 = 'chatgpt3'
|
||||
const FUNCTION_CHAT1 = 'chatgpt1'
|
||||
const FUNCTION_BING = 'bing'
|
||||
const FUNCTION_GEMINI = 'gemini'
|
||||
const FUNCTION_XH = 'xh'
|
||||
const FUNCTION_QWEN = 'qwen'
|
||||
const FUNCTION_GLM4 = 'glm4'
|
||||
const FUNCTION_CLAUDE2 = 'claude2'
|
||||
|
||||
const FUNCTION_END = 'destroyConversations'
|
||||
const FUNCTION_END_ALL = 'endAllConversations'
|
||||
|
||||
const FUNCTION_PIC = 'switch2Picture'
|
||||
const FUNCTION_TEXT = 'switch2Text'
|
||||
const FUNCTION_AUDIO = 'switch2Audio'
|
||||
|
||||
const FUNCTION_CONFIRM_ON = 'turnOnConfirm'
|
||||
const FUNCTION_CONFIRM_OFF = 'turnOffConfirm'
|
||||
const FUNCTION_VERSION = 'versionChatGPTPlugin'
|
||||
const FUNCTION_SHUTUP = 'shutUp'
|
||||
const FUNCTION_OPEN_MOUTH = 'openMouth'
|
||||
const FUNCTION_QUERY_CONFIG = 'queryConfig'
|
||||
const FUNCTION_ENABLE_CONTEXT = 'enableGroupContext'
|
||||
const FUNCTION_MODELS = 'viewAPIModel'
|
||||
|
||||
const FUNCTION_SWITCH_BING = 'useBingSolution'
|
||||
|
||||
const FUNCTION_WORDCLOUD = 'wordcloud'
|
||||
const FUNCTION_WORDCLOUD_LATEST = 'wordcloud_latest'
|
||||
const FUNCTION_WORDCLOUD_NEW = 'wordcloud_new'
|
||||
const FUNCTION_TRANSLATE = 'translate'
|
||||
const FUNCTION_TRANSLATE_SOURCE = 'translateSource'
|
||||
const FUNCTION_TRANSLATE_OCR = 'ocr'
|
||||
const FUNCTION_TRANSLATE_SCREENSHOT = 'screenshotUrl'
|
||||
export class ChatGPTButtonHandler extends plugin {
|
||||
constructor () {
|
||||
super({
|
||||
name: 'chatgpt按钮处理器',
|
||||
priority: -100,
|
||||
namespace: 'chatgpt-plugin',
|
||||
handler: [{
|
||||
key: 'chatgpt.button.post',
|
||||
fn: 'btnHandler'
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
async btnHandler (e, options, reject) {
|
||||
// logger.mark('[chatgpt按钮处理器]')
|
||||
if (!Config.enableMd || (e.adapter !== 'shamrock' && (!segment.button || segment.button(1)?.content !== 1))) {
|
||||
return null
|
||||
}
|
||||
const fnc = e.logFnc
|
||||
switch (fnc) {
|
||||
case `[${PLUGIN_CHAT}][${FUNCTION_CHAT3}]`:
|
||||
case `[${PLUGIN_CHAT}][${FUNCTION_CHAT1}]`:
|
||||
case `[${PLUGIN_CHAT}][${FUNCTION_BING}]`:
|
||||
case `[${PLUGIN_CHAT}][${FUNCTION_GEMINI}]`:
|
||||
case `[${PLUGIN_CHAT}][${FUNCTION_XH}]`:
|
||||
case `[${PLUGIN_CHAT}][${FUNCTION_QWEN}]`:
|
||||
case `[${PLUGIN_CHAT}][${FUNCTION_CLAUDE2}]`:
|
||||
case `[${PLUGIN_CHAT}][${FUNCTION_GLM4}]`:
|
||||
case `[${PLUGIN_CHAT}][${FUNCTION_CHAT}]`: {
|
||||
return this.makeButtonChat(options?.btnData)
|
||||
}
|
||||
case `[${PLUGIN_CHAT}][${FUNCTION_END}]`:
|
||||
case `[${PLUGIN_CHAT}][${FUNCTION_END_ALL}]`: {
|
||||
return this.makeButtonEnd(options?.btnData)
|
||||
}
|
||||
case `[${PLUGIN_CHAT}][${FUNCTION_PIC}]`:
|
||||
case `[${PLUGIN_CHAT}][${FUNCTION_AUDIO}]`:
|
||||
case `[${PLUGIN_CHAT}][${FUNCTION_TEXT}]`: {
|
||||
return this.makeButtonMode(options?.btnData)
|
||||
}
|
||||
case `[${PLUGIN_MANAGEMENT}][${FUNCTION_VERSION}]`:
|
||||
case `[${PLUGIN_MANAGEMENT}][${FUNCTION_SHUTUP}]`:
|
||||
case `[${PLUGIN_MANAGEMENT}][${FUNCTION_OPEN_MOUTH}]`:
|
||||
case `[${PLUGIN_MANAGEMENT}][${FUNCTION_MODELS}]`:
|
||||
case `[${PLUGIN_MANAGEMENT}][${FUNCTION_QUERY_CONFIG}]`:
|
||||
case `[${PLUGIN_MANAGEMENT}][${FUNCTION_ENABLE_CONTEXT}]`:
|
||||
case `[${PLUGIN_MANAGEMENT}][${FUNCTION_CONFIRM_OFF}]`:
|
||||
case `[${PLUGIN_MANAGEMENT}][${FUNCTION_CONFIRM_ON}]`: {
|
||||
return this.makeButtonConfirm(options?.btnData)
|
||||
}
|
||||
case `[${PLUGIN_MANAGEMENT}][${FUNCTION_SWITCH_BING}]`: {
|
||||
return this.makeButtonBingMode(options?.btnData)
|
||||
}
|
||||
case `[${PLUGIN_ENTERTAINMENT}][${FUNCTION_WORDCLOUD}]`:
|
||||
case `[${PLUGIN_ENTERTAINMENT}][${FUNCTION_WORDCLOUD_LATEST}]`:
|
||||
case `[${PLUGIN_ENTERTAINMENT}][${FUNCTION_WORDCLOUD_NEW}]`:
|
||||
case `[${PLUGIN_ENTERTAINMENT}][${FUNCTION_TRANSLATE}]`:
|
||||
case `[${PLUGIN_ENTERTAINMENT}][${FUNCTION_TRANSLATE_SOURCE}]`:
|
||||
case `[${PLUGIN_ENTERTAINMENT}][${FUNCTION_TRANSLATE_OCR}]`:
|
||||
case `[${PLUGIN_ENTERTAINMENT}][${FUNCTION_TRANSLATE_SCREENSHOT}]`: {
|
||||
return this.makeButtonEntertainment(options?.btnData)
|
||||
}
|
||||
default:
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {{suggested: string?, use: string}?} options
|
||||
*/
|
||||
async makeButtonChat (options) {
|
||||
let endCommand = '#摧毁对话'
|
||||
switch (options?.use) {
|
||||
case 'api': {
|
||||
endCommand = '#api结束对话'
|
||||
break
|
||||
}
|
||||
case 'api3': {
|
||||
endCommand = '#api3结束对话'
|
||||
break
|
||||
}
|
||||
case 'bing': {
|
||||
endCommand = '#必应结束对话'
|
||||
break
|
||||
}
|
||||
case 'claude2': {
|
||||
endCommand = '#克劳德结束对话'
|
||||
break
|
||||
}
|
||||
case 'gemini': {
|
||||
endCommand = '#双子星结束对话'
|
||||
break
|
||||
}
|
||||
case 'xh': {
|
||||
endCommand = '#星火结束对话'
|
||||
break
|
||||
}
|
||||
case 'qwen': {
|
||||
endCommand = '#通义千问结束对话'
|
||||
break
|
||||
}
|
||||
case 'chatglm4': {
|
||||
endCommand = '#智谱结束对话'
|
||||
break
|
||||
}
|
||||
}
|
||||
let rows = [
|
||||
{
|
||||
buttons: [
|
||||
createButtonBase('结束对话', '#毁灭对话'),
|
||||
createButtonBase('结束当前对话', endCommand),
|
||||
createButtonBase('at我对话', '', false)
|
||||
]
|
||||
}
|
||||
]
|
||||
let buttons = [[], []]
|
||||
if (Config.apiKey) {
|
||||
buttons[0].push(createButtonBase('OpenAPI', '#chat1', false))
|
||||
}
|
||||
if (await redis.get('CHATGPT:TOKEN')) {
|
||||
buttons[0].push(createButtonBase('ChatGPT', '#chat3', false))
|
||||
}
|
||||
if (await redis.get('CHATGPT:BING_TOKENS')) {
|
||||
buttons[0].push(createButtonBase('Copilot', '#bing', false))
|
||||
}
|
||||
if (Config.geminiKey) {
|
||||
buttons[0].push(createButtonBase('Gemini', '#gemini', false))
|
||||
}
|
||||
if (Config.xhAPIKey) {
|
||||
buttons[buttons[0].length >= 4 ? 1 : 0].push(createButtonBase('讯飞星火', '#xh', false))
|
||||
}
|
||||
if (Config.qwenApiKey) {
|
||||
buttons[buttons[0].length >= 4 ? 1 : 0].push(createButtonBase('通义千问', '#qwen', false))
|
||||
}
|
||||
if (Config.chatglmRefreshToken) {
|
||||
buttons[buttons[0].length >= 4 ? 1 : 0].push(createButtonBase('ChatGLM4', '#glm4', false))
|
||||
}
|
||||
if (Config.claudeAISessionKey) {
|
||||
buttons[buttons[0].length >= 4 ? 1 : 0].push(createButtonBase('Claude', '#claude.ai', false))
|
||||
}
|
||||
rows.push({
|
||||
buttons: buttons[0]
|
||||
})
|
||||
if (buttons[1].length > 0) {
|
||||
rows.push({
|
||||
buttons: buttons[1]
|
||||
})
|
||||
}
|
||||
if (options?.suggested) {
|
||||
rows.unshift({
|
||||
buttons: options.suggested.split('\n').map(s => {
|
||||
return createButtonBase(s, s)
|
||||
})
|
||||
})
|
||||
}
|
||||
return {
|
||||
appid: 1,
|
||||
rows
|
||||
}
|
||||
}
|
||||
|
||||
makeButtonEnd (options) {
|
||||
return {
|
||||
appid: 1,
|
||||
rows: [
|
||||
{
|
||||
buttons: [
|
||||
createButtonBase('重新开始', '#摧毁对话'),
|
||||
createButtonBase('全部结束', '#摧毁全部对话'),
|
||||
createButtonBase('切换模式', '#chatgpt切换', false)
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
makeButtonMode (options) {
|
||||
return {
|
||||
appid: 1,
|
||||
rows: [
|
||||
{
|
||||
buttons: [
|
||||
createButtonBase('以文字回复', '#chatgpt文本模式'),
|
||||
createButtonBase('以图片回复', '#chatgpt图片模式'),
|
||||
createButtonBase('以语音回复', '#chatgpt语音模式')
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
makeButtonConfirm (options) {
|
||||
return {
|
||||
appid: 1,
|
||||
rows: [
|
||||
{
|
||||
buttons: [
|
||||
createButtonBase('开启确认', '#chatgpt开启确认'),
|
||||
createButtonBase('关闭确认', '#chatgpt关闭确认'),
|
||||
createButtonBase('暂停本群回复', '#chatgpt本群闭嘴', false)
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
buttons: [
|
||||
createButtonBase('恢复本群回复', '#chatgpt本群张嘴', false),
|
||||
createButtonBase('开启上下文', '#打开群聊上下文'),
|
||||
createButtonBase('关闭上下文 ', '#关闭群聊上下文')
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
buttons: [
|
||||
createButtonBase('查看指令表', '#chatgpt指令表', false),
|
||||
createButtonBase('查看帮助', '#chatgpt帮助'),
|
||||
createButtonBase('查看配置', '#chatgpt查看当前配置')
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
buttons: [
|
||||
createButtonBase('查看配置', '#chatgpt查看当前配置'),
|
||||
createButtonBase('查看模型列表', '#chatgpt模型列表'),
|
||||
createButtonBase('版本信息', '#chatgpt版本信息')
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
makeButtonBingMode (options) {
|
||||
return {
|
||||
appid: 1,
|
||||
rows: [
|
||||
{
|
||||
buttons: [
|
||||
createButtonBase('创意模式', '#chatgpt必应切换创意'),
|
||||
createButtonBase('精准模式', '#chatgpt必应切换精准'),
|
||||
createButtonBase('使用设定', '#chatgpt使用设定', false)
|
||||
]
|
||||
},
|
||||
{
|
||||
buttons: [
|
||||
createButtonBase('禁用搜索', '#chatgpt必应禁用搜索'),
|
||||
createButtonBase('开启搜索', '#chatgpt必应开启搜索'),
|
||||
createButtonBase('设定列表', '#chatgpt浏览设定', false)
|
||||
]
|
||||
},
|
||||
{
|
||||
buttons: [
|
||||
createButtonBase('切换到API', '#chatgpt切换API'),
|
||||
createButtonBase('切换到Gemini', '#chatgpt切换gemini'),
|
||||
createButtonBase('切换到星火', '#chatgpt切换xh')
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
makeButtonEntertainment (options) {
|
||||
return {
|
||||
appid: 1,
|
||||
rows: [
|
||||
{
|
||||
buttons: [
|
||||
createButtonBase('今日词云', '#今日词云'),
|
||||
createButtonBase('最新词云', '#最新词云', false),
|
||||
createButtonBase('我的词云', '#我的今日词云')
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
buttons: [
|
||||
createButtonBase('翻译', '#翻译', false),
|
||||
createButtonBase('OCR', '#ocr', false),
|
||||
createButtonBase('截图', '#url', false)
|
||||
]
|
||||
},
|
||||
{
|
||||
buttons: [
|
||||
createButtonBase('设置OPENAI翻译源', '#chatgpt设置翻译来源openai'),
|
||||
createButtonBase('设置gemini翻译源', '#chatgpt设置翻译来源gemini'),
|
||||
createButtonBase('设置星火翻译源', '#chatgpt设置翻译来源xh'),
|
||||
createButtonBase('设置通义千问翻译源', '#chatgpt设置翻译来源qwen')
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createButtonBase (label, data, enter = true, style = 1) {
|
||||
return {
|
||||
id: '',
|
||||
render_data: {
|
||||
label,
|
||||
style,
|
||||
visited_label: label
|
||||
},
|
||||
action: {
|
||||
type: 2,
|
||||
permission: {
|
||||
type: 2
|
||||
},
|
||||
data,
|
||||
enter,
|
||||
unsupport_tips: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
131
apps/chat.js
131
apps/chat.js
|
|
@ -132,9 +132,8 @@ const newFetch = (url, options = {}) => {
|
|||
return fetch(url, mergedOptions)
|
||||
}
|
||||
export class chatgpt extends plugin {
|
||||
constructor () {
|
||||
constructor (e) {
|
||||
let toggleMode = Config.toggleMode
|
||||
let apiStream = Config.apiStream
|
||||
super({
|
||||
/** 功能名称 */
|
||||
name: 'ChatGpt 对话',
|
||||
|
|
@ -174,7 +173,7 @@ export class chatgpt extends plugin {
|
|||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#claude2[sS]*',
|
||||
reg: '^#claude(2|3|.ai)[sS]*',
|
||||
/** 执行方法 */
|
||||
fnc: 'claude2'
|
||||
},
|
||||
|
|
@ -292,7 +291,23 @@ export class chatgpt extends plugin {
|
|||
]
|
||||
})
|
||||
this.toggleMode = toggleMode
|
||||
this.apiStream = apiStream
|
||||
this.reply = async (msg, quote, data) => {
|
||||
if (!Config.enableMd) {
|
||||
return e.reply(msg, quote, data)
|
||||
}
|
||||
let handler = e.runtime?.handler || {}
|
||||
const btns = await handler.call('chatgpt.button.post', this.e, data)
|
||||
const btnElement = {
|
||||
type: 'button',
|
||||
content: btns
|
||||
}
|
||||
if (Array.isArray(msg)) {
|
||||
msg.push(btnElement)
|
||||
} else {
|
||||
msg = [msg, btnElement]
|
||||
}
|
||||
return e.reply(msg, quote, data)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -342,22 +357,22 @@ export class chatgpt extends plugin {
|
|||
// })
|
||||
// await client.endConversation()
|
||||
await redis.del(`CHATGPT:SLACK_CONVERSATION:${(e.isGroup && Config.groupMerge) ? e.group_id.toString() : e.sender.user_id}`)
|
||||
await e.reply('claude对话已结束')
|
||||
await this.reply('claude对话已结束')
|
||||
return
|
||||
}
|
||||
if (use === 'claude2') {
|
||||
await redis.del(`CHATGPT:CLAUDE2_CONVERSATION:${e.sender.user_id}`)
|
||||
await e.reply('claude2对话已结束')
|
||||
await this.reply('claude2对话已结束')
|
||||
return
|
||||
}
|
||||
if (use === 'xh') {
|
||||
await redis.del(`CHATGPT:CONVERSATIONS_XH:${(e.isGroup && Config.groupMerge) ? e.group_id.toString() : e.sender.user_id}`)
|
||||
await e.reply('星火对话已结束')
|
||||
await this.reply('星火对话已结束')
|
||||
return
|
||||
}
|
||||
if (use === 'bard') {
|
||||
await redis.del(`CHATGPT:CONVERSATIONS_BARD:${(e.isGroup && Config.groupMerge) ? e.group_id.toString() : e.sender.user_id}`)
|
||||
await e.reply('Bard对话已结束')
|
||||
await this.reply('Bard对话已结束')
|
||||
return
|
||||
}
|
||||
let ats = e.message.filter(m => m.type === 'at')
|
||||
|
|
@ -803,11 +818,11 @@ export class chatgpt extends plugin {
|
|||
break
|
||||
}
|
||||
default: {
|
||||
await e.reply('请使用#chatgpt语音换源+数字进行换源。1为vits-uma-genshin-honkai,2为微软Azure,3为voicevox')
|
||||
await this.reply('请使用#chatgpt语音换源+数字进行换源。1为vits-uma-genshin-honkai,2为微软Azure,3为voicevox')
|
||||
return
|
||||
}
|
||||
}
|
||||
await e.reply('语音转换源已切换为' + Config.ttsMode)
|
||||
await this.reply('语音转换源已切换为' + Config.ttsMode)
|
||||
}
|
||||
|
||||
async setDefaultRole (e) {
|
||||
|
|
@ -895,7 +910,7 @@ export class chatgpt extends plugin {
|
|||
* #chatgpt
|
||||
*/
|
||||
async chatgpt (e) {
|
||||
let msg = (Version.isTrss || e.adapter === 'shamrock') ? e.msg : e.raw_message
|
||||
let msg = e.msg
|
||||
let prompt
|
||||
if (this.toggleMode === 'at') {
|
||||
if (!msg || e.msg?.startsWith('#')) {
|
||||
|
|
@ -947,7 +962,7 @@ export class chatgpt extends plugin {
|
|||
}
|
||||
return false
|
||||
}
|
||||
prompt = _.replace(e.raw_message.trimStart(), '#chat', '').trim()
|
||||
prompt = _.replace(e.msg.trimStart(), '#chat', '').trim()
|
||||
if (prompt.length === 0) {
|
||||
return false
|
||||
}
|
||||
|
|
@ -1187,7 +1202,7 @@ export class chatgpt extends plugin {
|
|||
bingToken: previousConversation.bingToken
|
||||
}
|
||||
}
|
||||
|
||||
let handler = this.e.runtime?.handler || {}
|
||||
try {
|
||||
if (Config.debug) {
|
||||
logger.mark({ conversation })
|
||||
|
|
@ -1199,7 +1214,7 @@ export class chatgpt extends plugin {
|
|||
// 处理星火和bard图片
|
||||
if ((use === 'bard' || use === 'xh') && chatMessage?.images) {
|
||||
chatMessage.images.forEach(async element => {
|
||||
await e.reply([element.tag, segment.image(element.url)])
|
||||
await this.reply([element.tag, segment.image(element.url)])
|
||||
})
|
||||
}
|
||||
// chatglm4图片,调整至sendMessage中处理
|
||||
|
|
@ -1244,7 +1259,7 @@ export class chatgpt extends plugin {
|
|||
if (use === 'claude') response = response.replace(/:[a-zA-Z_]+:/g, '')
|
||||
let mood = 'blandness'
|
||||
if (!response) {
|
||||
await e.reply('没有任何回复', true)
|
||||
await this.reply('没有任何回复', true)
|
||||
return
|
||||
}
|
||||
let emotion, emotionDegree
|
||||
|
|
@ -1382,7 +1397,15 @@ export class chatgpt extends plugin {
|
|||
if (Config.ttsMode === 'vits-uma-genshin-honkai' && ttsResponse.length > parseInt(Config.ttsAutoFallbackThreshold)) {
|
||||
await this.reply('回复的内容过长,已转为文本模式')
|
||||
}
|
||||
await this.reply(await convertFaces(response, Config.enableRobotAt, e), e.isGroup)
|
||||
let responseText = await convertFaces(response, Config.enableRobotAt, e)
|
||||
if (handler.has('chatgpt.markdown.convert')) {
|
||||
responseText = await handler.call('chatgpt.markdown.convert', this.e, {
|
||||
content: responseText,
|
||||
use,
|
||||
prompt
|
||||
})
|
||||
}
|
||||
await this.reply(finalResponse, e.isGroup)
|
||||
if (quotemessage.length > 0) {
|
||||
this.reply(await makeForwardMsg(this.e, quotemessage.map(msg => `${msg.text} - ${msg.url}`)))
|
||||
}
|
||||
|
|
@ -1422,10 +1445,25 @@ export class chatgpt extends plugin {
|
|||
this.reply('今日对话已达上限')
|
||||
return false
|
||||
}
|
||||
await this.reply(await convertFaces(response, Config.enableRobotAt, e), e.isGroup)
|
||||
let responseText = await convertFaces(response, Config.enableRobotAt, e)
|
||||
if (handler.has('chatgpt.markdown.convert')) {
|
||||
responseText = await handler.call('chatgpt.markdown.convert', this.e, {
|
||||
content: responseText,
|
||||
use,
|
||||
prompt
|
||||
})
|
||||
}
|
||||
// await this.reply(responseText, e.isGroup)
|
||||
if (quotemessage.length > 0) {
|
||||
this.reply(await makeForwardMsg(this.e, quotemessage.map(msg => `${msg.text} - ${msg.url}`)))
|
||||
}
|
||||
|
||||
this.reply(responseText, e.isGroup, {
|
||||
btnData: {
|
||||
use,
|
||||
suggested: chatMessage.suggestedResponses
|
||||
}
|
||||
})
|
||||
if (Config.enableSuggestedResponses && chatMessage.suggestedResponses) {
|
||||
this.reply(`建议的回复:\n${chatMessage.suggestedResponses}`)
|
||||
}
|
||||
|
|
@ -1471,7 +1509,7 @@ export class chatgpt extends plugin {
|
|||
}
|
||||
|
||||
async claude2 (e) {
|
||||
return await this.otherMode(e, 'claude2')
|
||||
return await this.otherMode(e, 'claude2', /^#claude(2|3|.ai)/)
|
||||
}
|
||||
|
||||
async claude (e) {
|
||||
|
|
@ -1537,7 +1575,7 @@ export class chatgpt extends plugin {
|
|||
async renderImage (e, use, content, prompt, quote = [], mood = '', suggest = '', imgUrls = []) {
|
||||
let cacheData = await this.cacheContent(e, use, content, prompt, quote, mood, suggest, imgUrls)
|
||||
const template = use !== 'bing' ? 'content/ChatGPT/index' : 'content/Bing/index'
|
||||
if (cacheData.error || cacheData.status != 200) { await this.reply(`出现错误:${cacheData.error || 'server error ' + cacheData.status}`, true) } else { await e.reply(await renderUrl(e, (Config.viewHost ? `${Config.viewHost}/` : `http://127.0.0.1:${Config.serverPort || 3321}/`) + `page/${cacheData.file}?qr=${Config.showQRCode ? 'true' : 'false'}`, { retType: Config.quoteReply ? 'base64' : '', Viewport: { width: parseInt(Config.chatViewWidth), height: parseInt(parseInt(Config.chatViewWidth) * 0.56) }, func: (parseFloat(Config.live2d) && !Config.viewHost) ? 'window.Live2d == true' : '', deviceScaleFactor: parseFloat(Config.cloudDPR) }), e.isGroup && Config.quoteReply) }
|
||||
if (cacheData.error || cacheData.status != 200) { await this.reply(`出现错误:${cacheData.error || 'server error ' + cacheData.status}`, true) } else { await this.reply(await renderUrl(e, (Config.viewHost ? `${Config.viewHost}/` : `http://127.0.0.1:${Config.serverPort || 3321}/`) + `page/${cacheData.file}?qr=${Config.showQRCode ? 'true' : 'false'}`, { retType: Config.quoteReply ? 'base64' : '', Viewport: { width: parseInt(Config.chatViewWidth), height: parseInt(parseInt(Config.chatViewWidth) * 0.56) }, func: (parseFloat(Config.live2d) && !Config.viewHost) ? 'window.Live2d == true' : '', deviceScaleFactor: parseFloat(Config.cloudDPR) }), e.isGroup && Config.quoteReply) }
|
||||
}
|
||||
|
||||
async sendMessage (prompt, conversation = {}, use, e) {
|
||||
|
|
@ -1667,7 +1705,7 @@ export class chatgpt extends plugin {
|
|||
client.getImages(prompt, e)
|
||||
} catch (err) {
|
||||
redis.del(`CHATGPT:DRAW:${e.sender.user_id}`)
|
||||
e.reply('绘图失败:' + err)
|
||||
this.reply('绘图失败:' + err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -1715,20 +1753,20 @@ export class chatgpt extends plugin {
|
|||
if (bingToken) {
|
||||
if (maxConv >= 20 && Config.bingCaptchaOneShotUrl) {
|
||||
// maxConv为30说明token有效,可以通过解验证码码服务过码
|
||||
await e.reply('出现必应验证码,尝试解决中')
|
||||
await this.reply('出现必应验证码,尝试解决中')
|
||||
try {
|
||||
let captchaResolveResult = await solveCaptchaOneShot(bingToken)
|
||||
if (captchaResolveResult?.success) {
|
||||
await e.reply('验证码已解决')
|
||||
await this.reply('验证码已解决')
|
||||
} else {
|
||||
logger.error(captchaResolveResult)
|
||||
errorMessage = message
|
||||
await e.reply('验证码解决失败: ' + captchaResolveResult.error)
|
||||
await this.reply('验证码解决失败: ' + captchaResolveResult.error)
|
||||
retry = 0
|
||||
}
|
||||
} catch (err) {
|
||||
logger.error(err)
|
||||
await e.reply('验证码解决失败: ' + err)
|
||||
await this.reply('验证码解决失败: ' + err)
|
||||
retry = 0
|
||||
}
|
||||
} else {
|
||||
|
|
@ -2192,7 +2230,7 @@ export class chatgpt extends plugin {
|
|||
})
|
||||
let resp = await client.sendMessage(prompt, conversation)
|
||||
if (resp.image) {
|
||||
e.reply(segment.image(resp.image), true)
|
||||
this.reply(segment.image(resp.image), true)
|
||||
}
|
||||
return resp
|
||||
} else {
|
||||
|
|
@ -2275,7 +2313,7 @@ export class chatgpt extends plugin {
|
|||
let option = {
|
||||
timeoutMs: 600000,
|
||||
completionParams,
|
||||
stream: this.apiStream,
|
||||
stream: Config.apiStream,
|
||||
onProgress: (data) => {
|
||||
if (Config.debug) {
|
||||
logger.info(data?.text || data.functionCall || data)
|
||||
|
|
@ -2416,7 +2454,7 @@ export class chatgpt extends plugin {
|
|||
logger.info(msg)
|
||||
while (msg.functionCall) {
|
||||
if (msg.text) {
|
||||
await e.reply(msg.text.replace('\n\n\n', '\n'))
|
||||
await this.reply(msg.text.replace('\n\n\n', '\n'))
|
||||
}
|
||||
let {
|
||||
name,
|
||||
|
|
@ -2449,7 +2487,7 @@ export class chatgpt extends plugin {
|
|||
logger.warn(err)
|
||||
await redis.del(`CHATGPT:CONVERSATIONS:${e.sender.user_id}`)
|
||||
await redis.del(`CHATGPT:WRONG_EMOTION:${e.sender.user_id}`)
|
||||
await e.reply('字数超限啦,将为您自动结束本次对话。')
|
||||
await this.reply('字数超限啦,将为您自动结束本次对话。')
|
||||
return null
|
||||
} else {
|
||||
logger.error(err)
|
||||
|
|
@ -2466,7 +2504,7 @@ export class chatgpt extends plugin {
|
|||
logger.warn(err)
|
||||
await redis.del(`CHATGPT:CONVERSATIONS:${e.sender.user_id}`)
|
||||
await redis.del(`CHATGPT:WRONG_EMOTION:${e.sender.user_id}`)
|
||||
await e.reply('字数超限啦,将为您自动结束本次对话。')
|
||||
await this.reply('字数超限啦,将为您自动结束本次对话。')
|
||||
return null
|
||||
} else {
|
||||
logger.error(err)
|
||||
|
|
@ -2494,11 +2532,11 @@ export class chatgpt extends plugin {
|
|||
await redis.del(`CHATGPT:WRONG_EMOTION:${e.sender.user_id}`)
|
||||
}
|
||||
response = await client.sendMessage('', e)
|
||||
await e.reply(response, true)
|
||||
await this.reply(response, true)
|
||||
} else {
|
||||
let preset = getPromptByName(presetName)
|
||||
if (!preset) {
|
||||
await e.reply('没有这个设定', true)
|
||||
await this.reply('没有这个设定', true)
|
||||
} else {
|
||||
let conversationId = await redis.get(`CHATGPT:SLACK_CONVERSATION:${e.sender.user_id}`)
|
||||
if (conversationId) {
|
||||
|
|
@ -2510,7 +2548,7 @@ export class chatgpt extends plugin {
|
|||
logger.info('send preset: ' + preset.content)
|
||||
response = await client.sendMessage(preset.content, e) +
|
||||
await client.sendMessage(await AzureTTS.getEmotionPrompt(e), e)
|
||||
await e.reply(response, true)
|
||||
await this.reply(response, true)
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
|
@ -2519,15 +2557,15 @@ export class chatgpt extends plugin {
|
|||
async newxhBotConversation (e) {
|
||||
let botId = e.msg.replace(/^#星火助手/, '').trim()
|
||||
if (Config.xhmode != 'web') {
|
||||
await e.reply('星火助手仅支持体验版使用', true)
|
||||
await this.reply('星火助手仅支持体验版使用', true)
|
||||
return true
|
||||
}
|
||||
if (!botId) {
|
||||
await e.reply('无效助手id', true)
|
||||
await this.reply('无效助手id', true)
|
||||
} else {
|
||||
const ssoSessionId = Config.xinghuoToken
|
||||
if (!ssoSessionId) {
|
||||
await e.reply('未绑定星火token,请使用#chatgpt设置星火token命令绑定token', true)
|
||||
await this.reply('未绑定星火token,请使用#chatgpt设置星火token命令绑定token', true)
|
||||
return true
|
||||
}
|
||||
let client = new XinghuoClient({
|
||||
|
|
@ -2564,15 +2602,15 @@ export class chatgpt extends plugin {
|
|||
}),
|
||||
Config.conversationPreserveTime > 0 ? { EX: Config.conversationPreserveTime } : {}
|
||||
)
|
||||
await e.reply(`成功创建助手对话\n助手名称:${botInfo.data.bot_name}\n助手描述:${botInfo.data.bot_desc}`, true)
|
||||
await this.reply(`成功创建助手对话\n助手名称:${botInfo.data.bot_name}\n助手描述:${botInfo.data.bot_desc}`, true)
|
||||
} else {
|
||||
await e.reply(`创建助手对话失败,${botInfo.desc}`, true)
|
||||
await this.reply(`创建助手对话失败,${botInfo.desc}`, true)
|
||||
}
|
||||
} else {
|
||||
await e.reply('创建助手对话失败,服务器异常', true)
|
||||
await this.reply('创建助手对话失败,服务器异常', true)
|
||||
}
|
||||
} catch (error) {
|
||||
await e.reply(`创建助手对话失败 ${error}`, true)
|
||||
await this.reply(`创建助手对话失败 ${error}`, true)
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
|
@ -2582,7 +2620,7 @@ export class chatgpt extends plugin {
|
|||
let searchBot = e.msg.replace(/^#星火(搜索|查找)助手/, '').trim()
|
||||
const ssoSessionId = Config.xinghuoToken
|
||||
if (!ssoSessionId) {
|
||||
await e.reply('未绑定星火token,请使用#chatgpt设置星火token命令绑定token', true)
|
||||
await this.reply('未绑定星火token,请使用#chatgpt设置星火token命令绑定token', true)
|
||||
return true
|
||||
}
|
||||
const cacheresOption = {
|
||||
|
|
@ -2608,10 +2646,10 @@ export class chatgpt extends plugin {
|
|||
if (bots.data.pageList.length > 0) {
|
||||
this.reply(await makeForwardMsg(this.e, bots.data.pageList.map(msg => `${msg.e.bot.botId} - ${msg.e.bot.botName}`)))
|
||||
} else {
|
||||
await e.reply('未查到相关助手', true)
|
||||
await this.reply('未查到相关助手', true)
|
||||
}
|
||||
} else {
|
||||
await e.reply('搜索助手失败', true)
|
||||
await this.reply('搜索助手失败', true)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2763,6 +2801,13 @@ export class chatgpt extends plugin {
|
|||
return await this.chatGPTApi.sendMessage(prompt, sendMessageOption)
|
||||
}
|
||||
|
||||
/**
|
||||
* 其他模式
|
||||
* @param e
|
||||
* @param mode
|
||||
* @param {string|RegExp} pattern
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async otherMode (e, mode, pattern = `#${mode}`) {
|
||||
if (!Config.allowOtherMode) {
|
||||
return false
|
||||
|
|
@ -2774,7 +2819,7 @@ export class chatgpt extends plugin {
|
|||
}
|
||||
return false
|
||||
}
|
||||
let prompt = _.replace(e.raw_message.trimStart(), pattern, '').trim()
|
||||
let prompt = _.replace(e.msg.trimStart(), pattern, '').trim()
|
||||
if (prompt.length === 0) {
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,23 @@ export class Entertainment extends plugin {
|
|||
fnc: this.sendRandomMessage.bind(this)
|
||||
}
|
||||
]
|
||||
this.reply = async (msg, quote, data) => {
|
||||
if (!Config.enableMd) {
|
||||
return e.reply(msg, quote, data)
|
||||
}
|
||||
let handler = e.runtime?.handler || {}
|
||||
const btns = await handler.call('chatgpt.button.post', this.e)
|
||||
const btnElement = {
|
||||
type: 'button',
|
||||
content: btns
|
||||
}
|
||||
if (Array.isArray(msg)) {
|
||||
msg.push(btnElement)
|
||||
} else {
|
||||
msg = [msg, btnElement]
|
||||
}
|
||||
return e.reply(msg, quote, data)
|
||||
}
|
||||
}
|
||||
|
||||
async ocr (e) {
|
||||
|
|
@ -116,7 +133,7 @@ ${translateLangLabels}
|
|||
let result = []
|
||||
let multiText = false
|
||||
if (languageCode !== 'auto' && !translateLangLabelAbbrS.includes(languageCode)) {
|
||||
e.reply(`输入格式有误或暂不支持该语言,\n当前支持${translateLangLabels}`, e.isGroup)
|
||||
this.reply(`输入格式有误或暂不支持该语言,\n当前支持${translateLangLabels}`, e.isGroup)
|
||||
return false
|
||||
}
|
||||
// 引用回复
|
||||
|
|
@ -206,9 +223,9 @@ ${translateLangLabels}
|
|||
} else if (command.includes('qwen')) {
|
||||
Config.translateSource = 'qwen'
|
||||
} else {
|
||||
e.reply('暂不支持该翻译源')
|
||||
this.reply('暂不支持该翻译源')
|
||||
}
|
||||
e.reply('√成功设置翻译源为' + Config.translateSource)
|
||||
this.reply('√成功设置翻译源为' + Config.translateSource)
|
||||
}
|
||||
|
||||
async wordcloud (e) {
|
||||
|
|
@ -216,20 +233,21 @@ ${translateLangLabels}
|
|||
let groupId = e.group_id
|
||||
let lock = await redis.get(`CHATGPT:WORDCLOUD:${groupId}`)
|
||||
if (lock) {
|
||||
await e.reply('别着急,上次统计还没完呢')
|
||||
await this.reply('别着急,上次统计还没完呢')
|
||||
return true
|
||||
}
|
||||
await e.reply('在统计啦,请稍等...')
|
||||
await this.reply('在统计啦,请稍等...')
|
||||
await redis.set(`CHATGPT:WORDCLOUD:${groupId}`, '1', { EX: 600 })
|
||||
try {
|
||||
await makeWordcloud(e, e.group_id)
|
||||
let img = await makeWordcloud(e, e.group_id)
|
||||
this.reply(img, true)
|
||||
} catch (err) {
|
||||
logger.error(err)
|
||||
await e.reply(err)
|
||||
await this.reply(err)
|
||||
}
|
||||
await redis.del(`CHATGPT:WORDCLOUD:${groupId}`)
|
||||
} else {
|
||||
await e.reply('请在群里发送此命令')
|
||||
await this.reply('请在群里发送此命令')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -238,7 +256,7 @@ ${translateLangLabels}
|
|||
let groupId = e.group_id
|
||||
let lock = await redis.get(`CHATGPT:WORDCLOUD:${groupId}`)
|
||||
if (lock) {
|
||||
await e.reply('别着急,上次统计还没完呢')
|
||||
await this.reply('别着急,上次统计还没完呢')
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
@ -247,21 +265,21 @@ ${translateLangLabels}
|
|||
const duration = !match[1] ? 12 : parseInt(match[1]) // default 12h
|
||||
|
||||
if (duration > 24) {
|
||||
await e.reply('最多只能统计24小时内的记录哦,你可以使用#本周词云和#本月词云获取更长时间的统计~')
|
||||
await this.reply('最多只能统计24小时内的记录哦,你可以使用#本周词云和#本月词云获取更长时间的统计~')
|
||||
return false
|
||||
}
|
||||
await e.reply('在统计啦,请稍等...')
|
||||
await this.reply('在统计啦,请稍等...')
|
||||
|
||||
await redis.set(`CHATGPT:WORDCLOUD:${groupId}`, '1', { EX: 600 })
|
||||
try {
|
||||
await makeWordcloud(e, e.group_id, duration)
|
||||
} catch (err) {
|
||||
logger.error(err)
|
||||
await e.reply(err)
|
||||
await this.reply(err)
|
||||
}
|
||||
await redis.del(`CHATGPT:WORDCLOUD:${groupId}`)
|
||||
} else {
|
||||
await e.reply('请在群里发送此命令')
|
||||
await this.reply('请在群里发送此命令')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -278,10 +296,10 @@ ${translateLangLabels}
|
|||
}
|
||||
let lock = await redis.get(`CHATGPT:WORDCLOUD_NEW:${groupId}_${userId}`)
|
||||
if (lock) {
|
||||
await e.reply('别着急,上次统计还没完呢')
|
||||
await this.reply('别着急,上次统计还没完呢')
|
||||
return true
|
||||
}
|
||||
await e.reply('在统计啦,请稍等...')
|
||||
await this.reply('在统计啦,请稍等...')
|
||||
let duration = 24
|
||||
if (e.msg.includes('本周')) {
|
||||
const now = new Date() // Get the current date and time
|
||||
|
|
@ -307,11 +325,11 @@ ${translateLangLabels}
|
|||
await makeWordcloud(e, e.group_id, duration, userId)
|
||||
} catch (err) {
|
||||
logger.error(err)
|
||||
await e.reply(err)
|
||||
await this.reply(err)
|
||||
}
|
||||
await redis.del(`CHATGPT:WORDCLOUD_NEW:${groupId}_${userId}`)
|
||||
} else {
|
||||
await e.reply('请在群里发送此命令')
|
||||
await this.reply('请在群里发送此命令')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -327,7 +345,7 @@ ${translateLangLabels}
|
|||
if (fs.existsSync(resultFileLoc)) {
|
||||
let image = segment.image(fs.createReadStream(resultFileLoc))
|
||||
image.asface = true
|
||||
await e.reply(image, true)
|
||||
await this.reply(image, true)
|
||||
return true
|
||||
}
|
||||
const _path = process.cwd()
|
||||
|
|
@ -349,7 +367,7 @@ ${translateLangLabels}
|
|||
}
|
||||
}
|
||||
if (!url) {
|
||||
await e.reply('不支持合成', true)
|
||||
await this.reply('不支持合成', true)
|
||||
return false
|
||||
}
|
||||
let response = await fetch(url)
|
||||
|
|
@ -359,7 +377,7 @@ ${translateLangLabels}
|
|||
await fs.writeFileSync(resultFileLoc, resultBuffer)
|
||||
let image = segment.image(fs.createReadStream(resultFileLoc))
|
||||
image.asface = true
|
||||
await e.reply(image, true)
|
||||
await this.reply(image, true)
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
@ -376,7 +394,7 @@ ${translateLangLabels}
|
|||
logger.info(groupId)
|
||||
groupId = parseInt(groupId)
|
||||
if (groupId && !e.bot.gl.get(groupId)) {
|
||||
await e.reply('机器人不在这个群里!')
|
||||
await this.reply('机器人不在这个群里!')
|
||||
return
|
||||
}
|
||||
let message = await generateHello()
|
||||
|
|
@ -387,10 +405,10 @@ ${translateLangLabels}
|
|||
sendable = segment.record(audio)
|
||||
}
|
||||
if (!groupId) {
|
||||
await e.reply(sendable)
|
||||
await this.reply(sendable)
|
||||
} else {
|
||||
await e.bot.sendGroupMsg(groupId, sendable)
|
||||
await e.reply('发送成功!')
|
||||
await this.reply('发送成功!')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -563,7 +581,7 @@ ${translateLangLabels}
|
|||
url = 'http://' + url
|
||||
}
|
||||
let urlLink = new URL(url)
|
||||
await e.reply(
|
||||
await this.reply(
|
||||
await renderUrl(
|
||||
e, urlLink.href,
|
||||
{
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ export class ChatgptManagement extends plugin {
|
|||
permission: 'master'
|
||||
},
|
||||
{
|
||||
reg: '^#chatgpt切换(必应|Bing)$',
|
||||
reg: '^#chatgpt切换(必应|Bing|Copilot|copilot)$',
|
||||
fnc: 'useBingSolution',
|
||||
permission: 'master'
|
||||
},
|
||||
|
|
@ -333,6 +333,25 @@ export class ChatgptManagement extends plugin {
|
|||
}
|
||||
]
|
||||
})
|
||||
this.reply = async (msg, quote, data) => {
|
||||
if (!Config.enableMd) {
|
||||
return e.reply(msg, quote, data)
|
||||
}
|
||||
let handler = e.runtime?.handler || {}
|
||||
const btns = await handler.call('chatgpt.button.post', this.e)
|
||||
if (btns) {
|
||||
const btnElement = {
|
||||
type: 'button',
|
||||
content: btns
|
||||
}
|
||||
if (Array.isArray(msg)) {
|
||||
msg.push(btnElement)
|
||||
} else {
|
||||
msg = [msg, btnElement]
|
||||
}
|
||||
}
|
||||
return e.reply(msg, quote, data)
|
||||
}
|
||||
}
|
||||
|
||||
async viewUserSetting (e) {
|
||||
|
|
@ -1001,9 +1020,9 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
logger.error(error)
|
||||
logger.error(stderr)
|
||||
logger.info(stdout)
|
||||
this.e.reply('失败,请查看日志手动操作')
|
||||
this.reply('失败,请查看日志手动操作')
|
||||
} else {
|
||||
this.e.reply('修补完成,请手动重启')
|
||||
this.reply('修补完成,请手动重启')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -1047,20 +1066,20 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
}
|
||||
if (map[tongStyle]) {
|
||||
Config.toneStyle = map[tongStyle]
|
||||
await e.reply('切换成功')
|
||||
await this.reply('切换成功')
|
||||
} else {
|
||||
await e.reply('没有这种风格。支持的风格:`精准`和`创意`,均支持设定')
|
||||
await this.reply('没有这种风格。支持的风格:`精准`和`创意`,均支持设定')
|
||||
}
|
||||
}
|
||||
|
||||
async bingOpenSuggestedResponses (e) {
|
||||
Config.enableSuggestedResponses = e.msg.indexOf('开启') > -1
|
||||
await e.reply('操作成功')
|
||||
await this.reply('操作成功')
|
||||
}
|
||||
|
||||
async checkAuth (e) {
|
||||
if (!e.isMaster) {
|
||||
e.reply(`只有主人才能命令ChatGPT哦~
|
||||
this.reply(`只有主人才能命令ChatGPT哦~
|
||||
(*/ω\*)`)
|
||||
return false
|
||||
}
|
||||
|
|
@ -1068,7 +1087,8 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
}
|
||||
|
||||
async versionChatGPTPlugin (e) {
|
||||
await renderUrl(e, `http://127.0.0.1:${Config.serverPort || 3321}/version`, { Viewport: { width: 800, height: 600 } })
|
||||
let img = await renderUrl(e, `http://127.0.0.1:${Config.serverPort || 3321}/version`, { Viewport: { width: 800, height: 600 }, retType: 'base64' })
|
||||
this.reply(img)
|
||||
}
|
||||
|
||||
async modeHelp () {
|
||||
|
|
@ -1107,13 +1127,13 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
if (await redis.get(`CHATGPT:SHUT_UP:${scope}`)) {
|
||||
await redis.del(`CHATGPT:SHUT_UP:${scope}`)
|
||||
await redis.set(`CHATGPT:SHUT_UP:${scope}`, '1', { EX: time })
|
||||
await e.reply(`好的,已切换休眠状态:倒计时${formatDuration(time)}`)
|
||||
await this.reply(`好的,已切换休眠状态:倒计时${formatDuration(time)}`)
|
||||
} else {
|
||||
await redis.set(`CHATGPT:SHUT_UP:${scope}`, '1', { EX: time })
|
||||
await e.reply(`好的,已切换休眠状态:倒计时${formatDuration(time)}`)
|
||||
await this.reply(`好的,已切换休眠状态:倒计时${formatDuration(time)}`)
|
||||
}
|
||||
} else {
|
||||
await e.reply('主人,这里好像不是群哦')
|
||||
await this.reply('主人,这里好像不是群哦')
|
||||
return false
|
||||
}
|
||||
} else if (match) {
|
||||
|
|
@ -1122,23 +1142,23 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
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 })
|
||||
await e.reply(`好的,即将在群${groupId}中休眠${formatDuration(time)}`)
|
||||
await this.reply(`好的,即将在群${groupId}中休眠${formatDuration(time)}`)
|
||||
} else {
|
||||
await redis.set(`CHATGPT:SHUT_UP:${groupId}`, '1', { EX: time })
|
||||
await e.reply(`好的,即将在群${groupId}中休眠${formatDuration(time)}`)
|
||||
await this.reply(`好的,即将在群${groupId}中休眠${formatDuration(time)}`)
|
||||
}
|
||||
} else {
|
||||
await e.reply('主人还没告诉我群号呢')
|
||||
await this.reply('主人还没告诉我群号呢')
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
if (await redis.get('CHATGPT:SHUT_UP:ALL')) {
|
||||
await redis.del('CHATGPT:SHUT_UP:ALL')
|
||||
await redis.set('CHATGPT:SHUT_UP:ALL', '1', { EX: time })
|
||||
await e.reply(`好的,我会延长休眠时间${formatDuration(time)}`)
|
||||
await this.reply(`好的,我会延长休眠时间${formatDuration(time)}`)
|
||||
} else {
|
||||
await redis.set('CHATGPT:SHUT_UP:ALL', '1', { EX: time })
|
||||
await e.reply(`好的,我会延长休眠时间${formatDuration(time)}`)
|
||||
await this.reply(`好的,我会延长休眠时间${formatDuration(time)}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1147,36 +1167,36 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
const match = e.msg.match(/^#chatgpt群(\d+)/)
|
||||
if (e.msg.indexOf('本群') > -1) {
|
||||
if (await redis.get('CHATGPT:SHUT_UP:ALL')) {
|
||||
await e.reply('当前为休眠模式,没办法做出回应呢')
|
||||
await this.reply('当前为休眠模式,没办法做出回应呢')
|
||||
return false
|
||||
}
|
||||
if (e.isGroup) {
|
||||
let scope = e.group.group_id
|
||||
if (await redis.get(`CHATGPT:SHUT_UP:${scope}`)) {
|
||||
await redis.del(`CHATGPT:SHUT_UP:${scope}`)
|
||||
await e.reply('好的主人,我又可以和大家聊天啦')
|
||||
await this.reply('好的主人,我又可以和大家聊天啦')
|
||||
} else {
|
||||
await e.reply('主人,我已经启动过了哦')
|
||||
await this.reply('主人,我已经启动过了哦')
|
||||
}
|
||||
} else {
|
||||
await e.reply('主人,这里好像不是群哦')
|
||||
await this.reply('主人,这里好像不是群哦')
|
||||
return false
|
||||
}
|
||||
} else if (match) {
|
||||
if (await redis.get('CHATGPT:SHUT_UP:ALL')) {
|
||||
await e.reply('当前为休眠模式,没办法做出回应呢')
|
||||
await this.reply('当前为休眠模式,没办法做出回应呢')
|
||||
return false
|
||||
}
|
||||
const groupId = parseInt(match[1], 10)
|
||||
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}和大家聊天了`)
|
||||
await this.reply(`好的主人,我终于又可以在群${groupId}和大家聊天了`)
|
||||
} else {
|
||||
await e.reply(`主人,我在群${groupId}中已经是启动状态了哦`)
|
||||
await this.reply(`主人,我在群${groupId}中已经是启动状态了哦`)
|
||||
}
|
||||
} else {
|
||||
await e.reply('主人还没告诉我群号呢')
|
||||
await this.reply('主人还没告诉我群号呢')
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1186,14 +1206,14 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
for (let i = 0; i < keys.length; i++) {
|
||||
await redis.del(keys[i])
|
||||
}
|
||||
await e.reply('好的,我会开启所有群聊响应')
|
||||
await this.reply('好的,我会开启所有群聊响应')
|
||||
} else if (keys || keys.length > 0) {
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
await redis.del(keys[i])
|
||||
}
|
||||
await e.reply('已经开启过全群响应啦')
|
||||
await this.reply('已经开启过全群响应啦')
|
||||
} else {
|
||||
await e.reply('我没有在任何群休眠哦')
|
||||
await this.reply('我没有在任何群休眠哦')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1427,7 +1447,7 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
|
||||
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如果仍不能查看余额,请退出登录重新获取刷新令牌.设置后可以发送#chatgpt设置sessKey来将sessKey作为API Key使用')
|
||||
await this.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) {
|
||||
|
|
@ -1455,9 +1475,9 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
let errMsg = await refreshRes.json()
|
||||
logger.error(JSON.stringify(errMsg))
|
||||
if (errMsg.error === 'access_denied') {
|
||||
await e.reply('刷新令牌失效,请重新发送【#chatgpt设置后台刷新token】进行配置。建议退出platform.openai.com重新登录后再获取和配置')
|
||||
await this.reply('刷新令牌失效,请重新发送【#chatgpt设置后台刷新token】进行配置。建议退出platform.openai.com重新登录后再获取和配置')
|
||||
} else {
|
||||
await e.reply('获取失败')
|
||||
await this.reply('获取失败')
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
@ -1480,9 +1500,9 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
let sess = authRes.user.session.sensitive_id
|
||||
if (sess) {
|
||||
Config.apiKey = sess
|
||||
await e.reply('已成功将sessKey设置为apiKey,您可以发送#openai余额来查看该账号余额')
|
||||
await this.reply('已成功将sessKey设置为apiKey,您可以发送#openai余额来查看该账号余额')
|
||||
} else {
|
||||
await e.reply('设置失败!')
|
||||
await this.reply('设置失败!')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1493,7 +1513,7 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
return false
|
||||
}
|
||||
Config.OpenAiPlatformRefreshToken = token.replaceAll('\'', '')
|
||||
await this.e.reply('设置成功')
|
||||
await this.reply('设置成功')
|
||||
this.finish('doSetOpenAIPlatformToken')
|
||||
}
|
||||
|
||||
|
|
@ -1535,7 +1555,7 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
return true
|
||||
}
|
||||
this.setContext('doImportConfig')
|
||||
await e.reply('请发送配置文件')
|
||||
await this.reply('请发送配置文件')
|
||||
}
|
||||
|
||||
async doImportConfig (e) {
|
||||
|
|
@ -1591,7 +1611,7 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
await this.reply(await makeForwardMsg(this.e, changeConfig.map(msg => `修改项:${msg.item}\n旧数据\n\n${msg.old}\n\n新数据\n ${msg.value}`)))
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
await e.reply('配置文件错误')
|
||||
await this.reply('配置文件错误')
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1605,18 +1625,18 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
async switchSmartMode (e) {
|
||||
if (e.msg.includes('开启')) {
|
||||
if (Config.smartMode) {
|
||||
await e.reply('已经开启了')
|
||||
await this.reply('已经开启了')
|
||||
return
|
||||
}
|
||||
Config.smartMode = true
|
||||
await e.reply('好的,已经打开智能模式,注意API额度哦。配合开启读取群聊上下文效果更佳!')
|
||||
await this.reply('好的,已经打开智能模式,注意API额度哦。配合开启读取群聊上下文效果更佳!')
|
||||
} else {
|
||||
if (!Config.smartMode) {
|
||||
await e.reply('已经是关闭得了')
|
||||
await this.reply('已经是关闭得了')
|
||||
return
|
||||
}
|
||||
Config.smartMode = false
|
||||
await e.reply('好的,已经关闭智能模式')
|
||||
await this.reply('好的,已经关闭智能模式')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1638,7 +1658,7 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
// console.log(value)
|
||||
modelList.push(value)
|
||||
})
|
||||
await this.e.reply(makeForwardMsg(e, modelList, '模型列表'))
|
||||
await this.reply(makeForwardMsg(e, modelList, '模型列表'))
|
||||
}
|
||||
|
||||
async setAPIModel (e) {
|
||||
|
|
@ -1717,10 +1737,10 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
async switchBingSearch (e) {
|
||||
if (e.msg.includes('启用') || e.msg.includes('开启')) {
|
||||
Config.sydneyEnableSearch = true
|
||||
await e.reply('已开启必应搜索')
|
||||
await this.reply('已开启必应搜索')
|
||||
} else {
|
||||
Config.sydneyEnableSearch = false
|
||||
await e.reply('已禁用必应搜索')
|
||||
await this.reply('已禁用必应搜索')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1735,24 +1755,24 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务,
|
|||
config.push(`\n当前必应反代:${Config.sydneyReverseProxy}`)
|
||||
}
|
||||
config.push(`\n当前星火模型:${Config.xhmode}`)
|
||||
e.reply(config)
|
||||
this.reply(config)
|
||||
}
|
||||
|
||||
async switchStream (e) {
|
||||
if (e.msg.includes('开启')) {
|
||||
if (Config.apiStream) {
|
||||
await e.reply('已经开启了')
|
||||
await this.reply('已经开启了')
|
||||
return
|
||||
}
|
||||
Config.apiStream = true
|
||||
await e.reply('好的,已经打开API流式输出')
|
||||
await this.reply('好的,已经打开API流式输出')
|
||||
} else {
|
||||
if (!Config.apiStream) {
|
||||
await e.reply('已经是关闭得了')
|
||||
await this.reply('已经是关闭得了')
|
||||
return
|
||||
}
|
||||
Config.apiStream = false
|
||||
await e.reply('好的,已经关闭API流式输出')
|
||||
await this.reply('好的,已经关闭API流式输出')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
40
apps/md.js
Normal file
40
apps/md.js
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import plugin from '../../../lib/plugins/plugin.js'
|
||||
import {Config} from '../utils/config.js'
|
||||
|
||||
export class ChatGPTMarkdownHandler extends plugin {
|
||||
constructor () {
|
||||
super({
|
||||
name: 'chatgptmd处理器',
|
||||
priority: -100,
|
||||
namespace: 'chatgpt-plugin',
|
||||
handler: [{
|
||||
key: 'chatgpt.markdown.convert',
|
||||
fn: 'mdHandler'
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
async mdHandler (e, options, reject) {
|
||||
const { content, prompt, use } = options
|
||||
if (Config.enableMd) {
|
||||
let mode = transUse(use)
|
||||
return `> ${prompt}\n\n---\n${content}\n\n---\n*当前模式:${mode}*`
|
||||
} else {
|
||||
return content
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function transUse (use) {
|
||||
let useMap = {
|
||||
api: Config.model,
|
||||
bing: '必应(Copilot)' + Config.toneStyle,
|
||||
gemini: Config.geminiModel,
|
||||
xh: '讯飞星火 ' + Config.xhmode,
|
||||
qwen: '通义千问 ' + Config.qwenModel,
|
||||
claude2: 'Claude 3 Sonnet',
|
||||
glm4: 'ChatGLM4',
|
||||
chat3: 'ChatGPT官网'
|
||||
}
|
||||
return useMap[use] || use
|
||||
}
|
||||
|
|
@ -20,15 +20,15 @@ export class Vocal extends plugin {
|
|||
}
|
||||
]
|
||||
})
|
||||
this.task = [
|
||||
{
|
||||
// 设置十分钟左右的浮动
|
||||
cron: '0/1 * * * ?',
|
||||
// cron: '*/2 * * * *',
|
||||
name: '保持suno心跳',
|
||||
fnc: this.heartbeat.bind(this)
|
||||
}
|
||||
]
|
||||
// this.task = [
|
||||
// {
|
||||
// // 设置十分钟左右的浮动
|
||||
// cron: '0/1 * * * ?',
|
||||
// // cron: '*/2 * * * *',
|
||||
// name: '保持suno心跳',
|
||||
// fnc: this.heartbeat.bind(this)
|
||||
// }
|
||||
// ]
|
||||
}
|
||||
|
||||
async heartbeat (e) {
|
||||
|
|
|
|||
|
|
@ -57,6 +57,12 @@ export function supportGuoba () {
|
|||
bottomHelpMessage: '将输出更多调试信息,如果不希望控制台刷屏的话,可以关闭',
|
||||
component: 'Switch'
|
||||
},
|
||||
{
|
||||
field: 'enableMd',
|
||||
label: 'QQ开启markdown',
|
||||
bottomHelpMessage: 'qq的第三方md,非QQBot。需要适配器实现segment.markdown和segment.button方可使用,否则不建议开启,会造成各种错误。默认关闭',
|
||||
component: 'Switch'
|
||||
},
|
||||
{
|
||||
field: 'translateSource',
|
||||
label: '翻译来源',
|
||||
|
|
|
|||
|
|
@ -132,7 +132,8 @@ export class ClaudeAIClient {
|
|||
let body = {
|
||||
attachments,
|
||||
files: [],
|
||||
model: 'claude-2.1',
|
||||
// 官方更新后这里没有传值了
|
||||
// model: 'claude-2.1',
|
||||
prompt: text,
|
||||
timezone: 'Asia/Hong_Kong'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ const defaultConfig = {
|
|||
openAiBaseUrl: defaultOpenAIReverseProxy,
|
||||
OpenAiPlatformRefreshToken: '',
|
||||
openAiForceUseReverse: false,
|
||||
apiStream: false,
|
||||
drawCD: 30,
|
||||
model: '',
|
||||
temperature: 0.8,
|
||||
|
|
@ -178,6 +179,7 @@ const defaultConfig = {
|
|||
sunoSessToken: '',
|
||||
sunoClientToken: '',
|
||||
translateSource: 'openai',
|
||||
enableMd: false, // 第三方md,非QQBot。需要适配器实现segment.markdown和segment.button方可使用,否则不建议开启,会造成各种错误
|
||||
version: 'v2.7.10'
|
||||
}
|
||||
const _path = process.cwd()
|
||||
|
|
|
|||
|
|
@ -479,7 +479,7 @@ export async function convertFaces (msg, handleAt = false, e) {
|
|||
groupCardQQMap[groupMembers.get(key).card || groupMembers.get(key).nickname] = groupMembers.get(key).user_id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let tmpMsg = ''
|
||||
let tmpFace = ''
|
||||
let tmpAt = ''
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ export async function makeWordcloud (e, groupId, duration = 0, userId) {
|
|||
let list = JSON.stringify(topK)
|
||||
logger.info(list)
|
||||
let img = await render(e, 'chatgpt-plugin', 'wordcloud/index', { list }, { retType: 'base64' })
|
||||
await e.reply(img, true)
|
||||
return img
|
||||
}
|
||||
|
||||
function getTokenizer (e) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue