UNPKG

keli-chatgpt

Version:

keli 的 OpenAI / ChatGPT 插件

138 lines (108 loc) 3.76 kB
const { Plugin } = require('keli') const { Configuration, OpenAIApi } = require('openai') const { name, version } = require('./package.json') const plugin = new Plugin(name, version) const config = { // OpenAI apiKey apiKey: '', // 使用的模型,参考这里:https://platform.openai.com/docs/models/models model: 'gpt-3.5-turbo', // 触发命令前缀 cmdPrefix: '%', // 超时时间(毫秒,默认一分钟) timeout: 60000, temperature: 0.3, max_tokens: 1200, // 是否开启 at 触发 enableAt: true, // 是否在群聊中开启(发言不可控,为了账号安全可以关闭群聊功能,仅保留私聊) enableGroup: true } const msgs = { needConfig: `ChatGPT: 请先配置 apiKey,格式:/chatgpt setkey <apikey>`, apiError: 'ChatGPT: API 请求异常,可能是 apiKey 错误或请求太频繁,请查看日志', emptyMessage: '这个 OpenAI 不知道哦' } const cmds = [ '/chatgpt setkey <apiKey>', '/chatgpt at on/off', '/chatgpt group on/off', '/chatgpt prefix <触发前缀>' ] plugin.onMounted(async bot => { plugin.saveConfig(Object.assign(config, plugin.loadConfig())) plugin.onAdminCmd('/chatgpt', (e, params) => { const [cmd, value] = params if (cmd === 'setkey' && value) { config.apiKey = value plugin.saveConfig(config) return e.reply('apiKey 配置完成,重载插件生效', true) } if (cmd === 'at' && ['on', 'off'].includes(value)) { config.enableAt = value === 'on' plugin.saveConfig(config) return e.reply(`已${config.enableAt ? '开启' : '关闭'} at 触发`, true) } if (cmd === 'group' && ['on', 'off'].includes(value)) { config.enableGroup = value === 'on' plugin.saveConfig(config) return e.reply(`已${config.enableGroup ? '开启' : '关闭'}群聊功能`, true) } if (cmd === 'prefix' && value) { config.cmdPrefix = value plugin.saveConfig(config) return e.reply('已修改命令触发前缀', true) } return e.reply(cmds.join('\n'), true) }) if (!config.apiKey) { bot.sendPrivateMsg(plugin.mainAdmin, msgs.needConfig) return plugin.log(msgs.needConfig) } const configuration = new Configuration({ apiKey: config.apiKey, basePath: 'https://gpt.viki.moe/v1' }) const openai = new OpenAIApi(configuration) plugin.onMessage(async event => { const { message, message_type } = event const text = message .filter(e => e.type === 'text') .map(e => e.text) .join('') // 配置关闭群聊时,过滤群聊信息 if (!config.enableGroup && message_type !== 'private') { return } // 消息符合命令前缀 const isCmd = text.startsWith(config.cmdPrefix) // Bot 被艾特 const isAt = message.some(e => e.type === 'at' && e.qq === bot.uin) // 触发条件(符合命令前缀 或者 在启用艾特触发时,Bot 被艾特) const isHit = isCmd || (config.enableAt && isAt) // 过滤不触发的消息 if (!isHit) { return } try { const question = text.replace(config.cmdPrefix, '').trim() const { data } = await openai.createChatCompletion( { model: config.model, temperature: config.temperature, max_tokens: config.max_tokens, messages: [{ role: 'user', content: question }] }, { timeout: config.timeout } ) const res = data.choices[0]?.message?.content?.trim() ?? '' event.reply(res ?? msgs.emptyMessage, true) } catch (err) { plugin.logger.error(err?.message ?? err) return event.reply(err?.message ?? msgs.apiError, true) } }) }) module.exports = { plugin }