feat: 增加API key和设定的配置功能

This commit is contained in:
ikechan8370 2023-03-08 10:54:10 +08:00
parent d1a8f667d6
commit fa1b1877d0
5 changed files with 109 additions and 9 deletions

View file

@ -1,6 +1,6 @@
import plugin from '../../../lib/plugins/plugin.js' import plugin from '../../../lib/plugins/plugin.js'
import _ from 'lodash' import _ from 'lodash'
import { Config } from '../utils/config.js' import {Config, defaultOpenAIAPI, defaultOpenAIReverseProxy} from '../utils/config.js'
import { v4 as uuid } from 'uuid' import { v4 as uuid } from 'uuid'
import delay from 'delay' import delay from 'delay'
import { ChatGPTAPI } from 'chatgpt' import { ChatGPTAPI } from 'chatgpt'
@ -13,7 +13,7 @@ import {
tryTimes, tryTimes,
upsertMessage, upsertMessage,
randomString, randomString,
getDefaultUserSetting getDefaultUserSetting, isCN
} from '../utils/common.js' } from '../utils/common.js'
import { ChatGPTPuppeteer } from '../utils/browser.js' import { ChatGPTPuppeteer } from '../utils/browser.js'
import { KeyvFile } from 'keyv-file' import { KeyvFile } from 'keyv-file'
@ -856,8 +856,9 @@ export class chatgpt extends plugin {
assistantLabel: Config.assistantLabel, assistantLabel: Config.assistantLabel,
fetch: newFetch fetch: newFetch
} }
if (opts.apiBaseUrl !== 'https://api.openai.com' && Config.proxy && !Config.openAiForceUseReverse) { let openAIAccessible = (Config.proxy || !(await isCN())) // 配了代理或者服务器在国外,默认认为不需要反代
// 如果配了proxy而且有反代但是没开启强制反代,将baseurl删掉 if (opts.apiBaseUrl !== defaultOpenAIAPI && openAIAccessible && !Config.openAiForceUseReverse) {
// 如果配了proxy(或者不在国内),而且有反代,但是没开启强制反代,将baseurl删掉
delete opts.apiBaseUrl delete opts.apiBaseUrl
} }
this.chatGPTApi = new ChatGPTAPI(opts) this.chatGPTApi = new ChatGPTAPI(opts)

View file

@ -79,6 +79,21 @@ export class ChatgptManagement extends plugin {
reg: '^#chatgpt查看闭嘴', reg: '^#chatgpt查看闭嘴',
fnc: 'listShutUp', fnc: 'listShutUp',
permission: 'master' permission: 'master'
},
{
reg: '^#chatgpt设置(API|key)(Key|key)',
fnc: 'setAPIKey',
permission: 'master'
},
{
reg: '^#chatgpt设置(API|api)设定',
fnc: 'setAPIPromptPrefix',
permission: 'master'
},
{
reg: '^#chatgpt设置(Bing|必应|Sydney|悉尼|sydney|bing)设定',
fnc: 'setBingPromptPrefix',
permission: 'master'
} }
] ]
}) })
@ -419,4 +434,61 @@ export class ChatgptManagement extends plugin {
await this.reply(list.map(item => item.groupId !== 'ALL' ? `群聊${item.groupId}: ${item.ttlFormat}` : `全局: ${item.ttlFormat}`).join('\n')) await this.reply(list.map(item => item.groupId !== 'ALL' ? `群聊${item.groupId}: ${item.ttlFormat}` : `全局: ${item.ttlFormat}`).join('\n'))
} }
} }
async setAPIKey (e) {
this.setContext('saveAPIKey')
await this.reply('请发送OpenAI API Key.', true)
return false
}
async saveAPIKey () {
if (!this.e.msg) return
let token = this.e.msg
if (!token.startsWith('sk-')) {
await this.reply('OpenAI API Key格式错误', true)
this.finish('saveAPIKey')
return
}
// todo
Config.apiKey = token
await this.reply('OpenAI API Key设置成功', true)
this.finish('saveAPIKey')
}
async setAPIPromptPrefix (e) {
this.setContext('saveAPIPromptPrefix')
await this.reply('请发送用于API模式的设定', true)
return false
}
async saveAPIPromptPrefix (e) {
if (!this.e.msg) return
if (this.e.msg === '取消') {
await this.reply('已取消设置API设定', true)
this.finish('saveAPIPromptPrefix')
return
}
// todo
Config.promptPrefixOverride = this.e.msg
await this.reply('API模式的设定设置成功', true)
this.finish('saveAPIPromptPrefix')
}
async setBingPromptPrefix (e) {
this.setContext('saveBingPromptPrefix')
await this.reply('请发送用于Bing Sydney模式的设定', true)
return false
}
async saveBingPromptPrefix (e) {
if (!this.e.msg) return
if (this.e.msg === '取消') {
await this.reply('已取消设置Sydney设定', true)
this.finish('saveBingPromptPrefix')
return
}
Config.sydney = this.e.msg
await this.reply('Bing Sydney模式的设定设置成功', true)
this.finish('saveBingPromptPrefix')
}
} }

View file

@ -7,6 +7,7 @@ import crypto from 'crypto'
import HttpsProxyAgent from 'https-proxy-agent' import HttpsProxyAgent from 'https-proxy-agent'
import { Config } from './config.js' import { Config } from './config.js'
import {isCN} from "./common.js";
if (!globalThis.fetch) { if (!globalThis.fetch) {
globalThis.fetch = fetch globalThis.fetch = fetch
@ -58,9 +59,9 @@ export default class SydneyAIClient {
...opts, ...opts,
host: opts.host || Config.sydneyReverseProxy || 'https://www.bing.com' host: opts.host || Config.sydneyReverseProxy || 'https://www.bing.com'
} }
if (opts.proxy && !Config.sydneyForceUseReverse) { // if (opts.proxy && !Config.sydneyForceUseReverse) {
this.opts.host = 'https://www.bing.com' // this.opts.host = 'https://www.bing.com'
} // }
this.debug = opts.debug this.debug = opts.debug
} }
@ -102,6 +103,11 @@ export default class SydneyAIClient {
if (this.opts.proxy) { if (this.opts.proxy) {
fetchOptions.agent = proxy(Config.proxy) fetchOptions.agent = proxy(Config.proxy)
} }
let accessible = !(await isCN()) || this.opts.proxy
if (accessible && !Config.sydneyForceUseReverse) {
// 本身能访问bing.com那就不用反代啦重置host
this.opts.host = 'https://www.bing.com'
}
const response = await fetch(`${this.opts.host}/turing/conversation/create`, fetchOptions) const response = await fetch(`${this.opts.host}/turing/conversation/create`, fetchOptions)
let text = await response.text() let text = await response.text()
try { try {

View file

@ -351,3 +351,20 @@ export function formatDuration (duration) {
return result || '0秒钟' return result || '0秒钟'
} }
/**
* 判断服务器所在地是否为中国
* @returns {Promise<boolean>}
*/
export async function isCN () {
if (await redis.get('CHATGPT:COUNTRY_CODE')) {
return await redis.get('CHATGPT:COUNTRY_CODE') === 'CN'
} else {
let response = await fetch('https://ipinfo.io/country')
let countryCode = await response.text()
await redis.set('CHATGPT:COUNTRY_CODE', countryCode, { EX: 3600 * 24 * 7 })
if (countryCode !== 'CN') {
return false
}
}
}

View file

@ -2,6 +2,10 @@ import fs from 'fs'
import lodash from 'lodash' import lodash from 'lodash'
export const defaultChatGPTAPI = 'https://pimon.d201.cn/backend-api/conversation' export const defaultChatGPTAPI = 'https://pimon.d201.cn/backend-api/conversation'
export const officialChatGPTAPI = 'https://apps.openai.com/api/conversation' export const officialChatGPTAPI = 'https://apps.openai.com/api/conversation'
// Reverse proxy of https://api.openai.com
export const defaultOpenAIReverseProxy = 'https://mondstadt.d201.eu.org'
// blocked in China Mainland
export const defaultOpenAIAPI = 'https://api.openai.com'
const defaultConfig = { const defaultConfig = {
blockWords: ['屏蔽词1', '屏蔽词b'], blockWords: ['屏蔽词1', '屏蔽词b'],
promptBlockWords: ['屏蔽词1', '屏蔽词b'], promptBlockWords: ['屏蔽词1', '屏蔽词b'],
@ -20,7 +24,7 @@ const defaultConfig = {
cacheUrl: 'https://content.alcedogroup.com', cacheUrl: 'https://content.alcedogroup.com',
cacheEntry: false, cacheEntry: false,
apiKey: '', apiKey: '',
openAiBaseUrl: 'https://api.openai.com', openAiBaseUrl: defaultOpenAIReverseProxy,
openAiForceUseReverse: false, openAiForceUseReverse: false,
drawCD: 30, drawCD: 30,
model: '', model: '',
@ -51,7 +55,7 @@ const defaultConfig = {
noiseScaleW: 0.668, noiseScaleW: 0.668,
lengthScale: 1.2, lengthScale: 1.2,
initiativeChatGroups: [], initiativeChatGroups: [],
version: 'v2.1.0' version: 'v2.1.1'
} }
const _path = process.cwd() const _path = process.cwd()
let config = {} let config = {}