From 91abd8a95947bd8af9e249b2bd687edf182aecf5 Mon Sep 17 00:00:00 2001 From: ikechan8370 Date: Thu, 7 Dec 2023 22:41:44 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20refresh=E8=87=AA=E5=8A=A8=E8=8E=B7?= =?UTF-8?q?=E5=8F=96sessKey=E4=BD=9C=E4=B8=BAAPI=20Key?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/help.js | 7 ++++- apps/management.js | 78 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/apps/help.js b/apps/help.js index 8de904c..1c2a7c6 100644 --- a/apps/help.js +++ b/apps/help.js @@ -209,7 +209,12 @@ let helpData = [ { icon: 'token', title: '#chatgpt设置后台刷新token', - desc: '用于查看API余额。注意和配置的key保持同一账号。' + desc: '用于获取刷新令牌,以便获取sessKey。' + }, + { + icon: 'key', + title: '#chatgpt设置sessKey', + desc: '使用sessKey作为APIKey,适用于未手机号验证的用户' }, { icon: 'token', diff --git a/apps/management.js b/apps/management.js index 2a8d364..c482c4b 100644 --- a/apps/management.js +++ b/apps/management.js @@ -20,6 +20,23 @@ import fs from 'fs' import loader from '../../../lib/plugins/loader.js' import VoiceVoxTTS, { supportConfigurations as voxRoleList } from '../utils/tts/voicevox.js' import { supportConfigurations as azureRoleList } from '../utils/tts/microsoft-azure.js' +import fetch from 'node-fetch' +import { getProxy } from '../utils/proxy.js' + +let proxy = getProxy() +const newFetch = (url, options = {}) => { + const defaultOptions = Config.proxy + ? { + agent: proxy(Config.proxy) + } + : {} + const mergedOptions = { + ...defaultOptions, + ...options + } + + return fetch(url, mergedOptions) +} export class ChatgptManagement extends plugin { constructor (e) { @@ -254,6 +271,10 @@ export class ChatgptManagement extends plugin { reg: '^#chatgpt设置后台(刷新|refresh)(t|T)oken$', fnc: 'setOpenAIPlatformToken' }, + { + reg: '^#chatgpt设置sessKey$', + fnc: 'getSessKey' + }, { reg: '^#(chatgpt)?查看回复设置$', fnc: 'viewUserSetting' @@ -1114,8 +1135,8 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务, async saveAPIKey () { if (!this.e.msg) return let token = this.e.msg - if (!token.startsWith('sk-')) { - await this.reply('OpenAI API Key格式错误', true) + if (!token.startsWith('sk-') && !token.startsWith('sess-')) { + await this.reply('OpenAI API Key格式错误。如果是格式特殊的非官方Key请前往锅巴或工具箱手动设置', true) this.finish('saveAPIKey') return } @@ -1302,7 +1323,58 @@ 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如果仍不能查看余额,请退出登录重新获取刷新令牌') + 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使用') + } + + async getSessKey (e) { + if (!Config.OpenAiPlatformRefreshToken) { + this.reply('当前未配置platform.openai.com的刷新token,请发送【#chatgpt设置后台刷新token】进行配置。') + return false + } + let authHost = 'https://auth0.openai.com' + if (Config.openAiBaseUrl && !Config.openAiBaseUrl.startsWith('https://api.openai.com')) { + authHost = Config.openAiBaseUrl.replace('/v1', '').replace('/v1/', '') + } + let refreshRes = await newFetch(`${authHost}/oauth/token`, { + method: 'POST', + body: JSON.stringify({ + refresh_token: Config.OpenAiPlatformRefreshToken, + client_id: 'DRivsnm2Mu42T3KOpqdtwB3NYviHYzwD', + grant_type: 'refresh_token' + }) + }) + if (refreshRes.status !== 200) { + let errMsg = await refreshRes.json() + if (errMsg.error === 'access_denied') { + await e.reply('刷新令牌失效,请重新发送【#chatgpt设置后台刷新token】进行配置。建议退出platform.openai.com重新登录后再获取和配置') + } else { + await e.reply('获取失败') + } + return false + } + let newToken = await refreshRes.json() + // eslint-disable-next-line camelcase + const { access_token, refresh_token } = newToken + // eslint-disable-next-line camelcase + Config.OpenAiPlatformRefreshToken = refresh_token + let host = Config.openAiBaseUrl.replace('/v1', '').replace('/v1/', '') + let res = await newFetch(`${host}/dashboard/onboarding/login`, { + headers: { + // eslint-disable-next-line camelcase + Authorization: `Bearer ${access_token}` + }, + method: 'POST' + }) + if (res.status === 200) { + let authRes = await res.json() + let sess = authRes.user.session.sensitive_id + if (sess) { + Config.apiKey = sess + await e.reply('已成功将sessKey设置为apiKey,您可以发送#open余额来查看该账号余额') + } else { + await e.reply('设置失败!') + } + } } async doSetOpenAIPlatformToken () {