From 156a669ec6dc991ecd68a409e15e7439db53cb52 Mon Sep 17 00:00:00 2001 From: ikechan8370 Date: Mon, 6 Mar 2023 20:30:57 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=97=AD=E5=98=B4=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/chat.js | 5 ++ apps/help.js | 15 ++++++ apps/management.js | 132 ++++++++++++++++++++++++++++++++++++++++++++- utils/common.js | 57 +++++++++++++++++++- utils/config.js | 2 +- 5 files changed, 208 insertions(+), 3 deletions(-) diff --git a/apps/chat.js b/apps/chat.js index 9625337..e8208a8 100644 --- a/apps/chat.js +++ b/apps/chat.js @@ -412,6 +412,11 @@ export class chatgpt extends plugin { return false } } + let groupId = e.isGroup ? e.group.group_id : '' + if (await redis.get('CHATGPT:SHUT_UP:ALL') || await redis.get(`CHATGPT:SHUT_UP:${groupId}`)) { + logger.info('chatgpt闭嘴中,不予理会') + return false + } let userSetting = await redis.get(`CHATGPT:USER:${e.sender.user_id}`) if (userSetting) { userSetting = JSON.parse(userSetting) diff --git a/apps/help.js b/apps/help.js index d68ca5d..1059070 100644 --- a/apps/help.js +++ b/apps/help.js @@ -61,6 +61,21 @@ let helpData = [ title: '#chatgpt对话列表', desc: '查询当前哪些人正在与机器人聊天.目前API3模式下支持切换对话' }, + { + icon: 'destroy', + title: '#chatgpt(本群)?(群xxx)?闭嘴(x秒/分钟/小时)', + desc: '让机器人在本群/某群闭嘴。不指定群时认为全局闭嘴。' + }, + { + icon: 'chat', + title: '#chatgpt(本群)?(群xxx)?(张嘴|开口|说话|上班)', + desc: '让机器人在本群/某群重新可以说话。不指定群时认为全局开口。' + }, + { + icon: 'chat', + title: '#chatgpt查看闭嘴', + desc: '查看当前闭嘴情况。' + }, { icon: 'switch', title: '#chatgpt切换对话+对话id', diff --git a/apps/management.js b/apps/management.js index 1f806ce..6de2689 100644 --- a/apps/management.js +++ b/apps/management.js @@ -2,7 +2,7 @@ import plugin from '../../../lib/plugins/plugin.js' import { Config } from '../utils/config.js' import { BingAIClient } from '@waylaidwanderer/chatgpt-api' import { exec } from 'child_process' -import { checkPnpm } from '../utils/common.js' +import { checkPnpm, formatDuration, parseDuration } from '../utils/common.js' export class ChatgptManagement extends plugin { constructor (e) { @@ -64,6 +64,21 @@ export class ChatgptManagement extends plugin { { reg: '^#chatgpt(强制)?更新$', fnc: 'updateChatGPTPlugin' + }, + { + reg: '^#chatgpt(本群)?(群\\d+)?闭嘴', + fnc: 'shutUp', + permission: 'master' + }, + { + reg: '^#chatgpt(本群)?(群\\d+)?(张嘴|开口|说话|上班)', + fnc: 'openMouth', + permission: 'master' + }, + { + reg: '^#chatgpt查看闭嘴', + fnc: 'listShutUp', + permission: 'master' } ] }) @@ -280,4 +295,119 @@ export class ChatgptManagement extends plugin { ` await this.reply(message) } + + async shutUp (e) { + let duration = e.msg.replace(/^#chatgpt(本群)?(群\d+)?闭嘴/, '') + let scope + let time = 3600000 + if (duration === '永久') { + time = 0 + } else if (duration) { + time = parseDuration(duration) + } + const match = e.msg.match(/#chatgpt群(\d+)闭嘴(.*)/) + if (e.msg.indexOf('本群') > -1) { + if (e.isGroup) { + scope = e.group.group_id + 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)}`) + } else { + await redis.set(`CHATGPT:SHUT_UP:${scope}`, '1', { EX: time }) + await e.reply(`好的,从现在开始我会在当前群聊闭嘴${formatDuration(time)}`) + } + } else { + await e.reply('本群是指?你也没在群聊里让我闭嘴啊?') + return false + } + } else if (match) { + const groupId = parseInt(match[1], 10) + if (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 }) + await e.reply(`好的,从现在开始我会在群聊${groupId}闭嘴${formatDuration(time)}`) + } else { + await redis.set(`CHATGPT:SHUT_UP:${groupId}`, '1', { EX: time }) + await e.reply(`好的,从现在开始我会在群聊${groupId}闭嘴${formatDuration(time)}`) + } + } else { + await e.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)}`) + } else { + await redis.set('CHATGPT:SHUT_UP:ALL', '1', { EX: time }) + await e.reply(`好的,我会闭嘴${formatDuration(time)}`) + } + } + } + + async openMouth (e) { + const match = e.msg.match(/^#chatgpt群(\d+)/) + if (e.msg.indexOf('本群') > -1) { + if (await redis.get('CHATGPT:SHUT_UP:ALL')) { + await e.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('好的主人,我终于又可以在本群说话了') + } else { + await e.reply('啊?我也没闭嘴啊?') + } + } else { + await e.reply('本群是指?你也没在群聊里让我张嘴啊?') + return false + } + } else if (match) { + if (await redis.get('CHATGPT:SHUT_UP:ALL')) { + await e.reply('主人,我现在全局闭嘴呢,你让我在那个群张嘴咱也不敢张啊') + return false + } + const groupId = parseInt(match[1], 10) + if (Bot.getGroupList().get(groupId)) { + if (await redis.get(`CHATGPT:SHUT_UP:${groupId}`)) { + await redis.del(`CHATGPT:SHUT_UP:${groupId}`) + await e.reply(`好的主人,我终于又可以在群${groupId}说话了`) + } else { + await e.reply(`啊?我也没在群${groupId}闭嘴啊?`) + } + } else { + await e.reply('这是什么群?') + return false + } + } else { + if (await redis.get('CHATGPT:SHUT_UP:ALL')) { + await redis.del('CHATGPT:SHUT_UP:ALL') + await e.reply('好的,我会结束全局闭嘴') + } else { + await e.reply('啊?我也没全局闭嘴啊?') + } + } + } + + async listShutUp () { + let keys = await redis.keys('CHATGPT:SHUT_UP:*') + if (!keys || keys.length === 0) { + await this.reply('我没有在任何群闭嘴', true) + } else { + let list = [] + for (let i = 0; i < keys.length; i++) { + let key = keys[i] + let groupId = key.replace('CHATGPT:SHUT_UP:', '') + let ttl = await redis.ttl(key) + let ttlFormat = formatDuration(ttl) + list.push({ groupId, ttlFormat }) + } + await this.reply(list.map(item => item.groupId !== 'ALL' ? `群聊${item.groupId}: ${item.ttlFormat}` : `全局: ${item.ttlFormat}`).join('\n')) + } + } } diff --git a/utils/common.js b/utils/common.js index 539b88d..5eb87ca 100644 --- a/utils/common.js +++ b/utils/common.js @@ -5,7 +5,7 @@ import lodash from 'lodash' import fs from 'node:fs' import path from 'node:path' import puppeteer from '../../../lib/puppeteer/puppeteer.js' -import {Config} from "./config.js"; +import { Config } from './config.js' // export function markdownToText (markdown) { // return remark() // .use(stripMarkdown) @@ -296,3 +296,58 @@ export function getDefaultUserSetting () { ttsRole: Config.defaultTTSRole } } + +export function parseDuration (duration) { + const timeMap = { + 秒: 1000, + 分: 60 * 1000, + 小时: 60 * 60 * 1000 + } + + // 去掉多余的空格并将单位转化为小写字母 + duration = duration.trim().toLowerCase() + + // 去掉末尾的 "钟" 字符 + if (duration.endsWith('钟')) { + duration = duration.slice(0, -1) + } + + // 提取数字和单位 + const match = duration.match(/^(\d+)\s*([\u4e00-\u9fa5]+)$/) + + if (!match) { + throw new Error('Invalid duration string: ' + duration) + } + + const num = parseInt(match[1], 10) + const unit = match[2] + + if (!(unit in timeMap)) { + throw new Error('Unknown time unit: ' + unit) + } + + return num * timeMap[unit] +} + +export function formatDuration (duration) { + const timeMap = { + 小时: 60 * 60 * 1000, + 分钟: 60 * 1000, + 秒钟: 1000 + } + + const units = Object.keys(timeMap) + let result = '' + + for (let i = 0; i < units.length; i++) { + const unit = units[i] + const value = Math.floor(duration / timeMap[unit]) + + if (value > 0) { + result += value + unit + duration -= value * timeMap[unit] + } + } + + return result || '0秒钟' +} diff --git a/utils/config.js b/utils/config.js index 8daf9b5..012dbbd 100644 --- a/utils/config.js +++ b/utils/config.js @@ -46,7 +46,7 @@ const defaultConfig = { noiseScaleW: 0.668, lengthScale: 1.2, initiativeChatGroups: [], - version: 'v2.0.19' + version: 'v2.0.20' } const _path = process.cwd() let config = {}