@@ -14,7 +14,7 @@ import { getCacheApiKeys, getCacheConfig, getOriginConfig } from '../storage/con
1414import { sendResponse } from '../utils'
1515import { hasAnyRole , isNotEmptyString } from '../utils/is'
1616import type { ChatContext , ChatGPTUnofficialProxyAPIOptions , JWT , ModelConfig } from '../types'
17- import { getChatByMessageId } from '../storage/mongo'
17+ import { getChatByMessageId , updateRoomAccountId } from '../storage/mongo'
1818import type { RequestOptions } from './types'
1919
2020const { HttpsProxyAgent } = httpsProxyAgent
@@ -84,13 +84,22 @@ export async function initApi(key: KeyConfig, chatModel: CHATMODEL) {
8484}
8585const processThreads : { userId : string ; abort : AbortController ; messageId : string } [ ] = [ ]
8686async function chatReplyProcess ( options : RequestOptions ) {
87- const model = options . chatModel
88- const key = await getRandomApiKey ( options . user , options . user . config . chatModel )
87+ const model = options . user . config . chatModel
88+ const key = await getRandomApiKey ( options . user , options . user . config . chatModel , options . room . accountId )
8989 const userId = options . user . _id . toString ( )
9090 const messageId = options . messageId
9191 if ( key == null || key === undefined )
9292 throw new Error ( '没有可用的配置。请再试一次 | No available configuration. Please try again.' )
9393
94+ if ( key . keyModel === 'ChatGPTUnofficialProxyAPI' ) {
95+ if ( ! options . room . accountId )
96+ updateRoomAccountId ( userId , options . room . roomId , getAccountId ( key . key ) )
97+
98+ if ( options . lastContext && ( ( options . lastContext . conversationId && ! options . lastContext . parentMessageId )
99+ || ( ! options . lastContext . conversationId && options . lastContext . parentMessageId ) ) )
100+ throw new Error ( '无法在一个房间同时使用 AccessToken 以及 Api,请联系管理员,或新开聊天室进行对话 | Unable to use AccessToken and Api at the same time in the same room, please contact the administrator or open a new chat room for conversation' )
101+ }
102+
94103 const { message, lastContext, process, systemMessage, temperature, top_p } = options
95104
96105 try {
@@ -270,10 +279,10 @@ function formatDate(date) {
270279
271280async function chatConfig ( ) {
272281 const config = await getOriginConfig ( ) as ModelConfig
273- if ( config . apiModel === 'ChatGPTAPI' )
274- config . balance = await fetchBalance ( )
275- else
276- config . accessTokenExpiredTime = await fetchAccessTokenExpiredTime ( )
282+ // if (config.apiModel === 'ChatGPTAPI')
283+ // config.balance = await fetchBalance()
284+ // else
285+ // config.accessTokenExpiredTime = await fetchAccessTokenExpiredTime()
277286 return sendResponse < ModelConfig > ( {
278287 type : 'Success' ,
279288 data : config ,
@@ -354,9 +363,23 @@ async function randomKeyConfig(keys: KeyConfig[]): Promise<KeyConfig | null> {
354363 return thisKey
355364}
356365
357- async function getRandomApiKey ( user : UserInfo , chatModel : CHATMODEL ) : Promise < KeyConfig | undefined > {
358- const keys = ( await getCacheApiKeys ( ) ) . filter ( d => hasAnyRole ( d . userRoles , user . roles ) )
359- return randomKeyConfig ( keys . filter ( d => d . chatModels . includes ( chatModel ) ) )
366+ async function getRandomApiKey ( user : UserInfo , chatModel : CHATMODEL , accountId ?: string ) : Promise < KeyConfig | undefined > {
367+ let keys = ( await getCacheApiKeys ( ) ) . filter ( d => hasAnyRole ( d . userRoles , user . roles ) )
368+ . filter ( d => d . chatModels . includes ( chatModel ) )
369+ if ( accountId )
370+ keys = keys . filter ( d => d . keyModel === 'ChatGPTUnofficialProxyAPI' && getAccountId ( d . key ) === accountId )
371+
372+ return randomKeyConfig ( keys )
373+ }
374+
375+ function getAccountId ( accessToken : string ) : string {
376+ try {
377+ const jwt = jwt_decode ( accessToken ) as JWT
378+ return jwt [ 'https://api.openai.com/auth' ] . user_id
379+ }
380+ catch ( error ) {
381+ return ''
382+ }
360383}
361384
362385export type { ChatContext , ChatMessage }
0 commit comments