package org.ruoyi.common.chat.openai.interceptor; import cn.hutool.json.JSONUtil; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import okhttp3.Request; import okhttp3.Response; import org.ruoyi.common.chat.entity.common.OpenAiResponse; import org.ruoyi.common.chat.openai.exception.CommonError; import org.ruoyi.common.core.exception.base.BaseException; import java.io.IOException; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; /** * 动态处理key的鉴权拦截器 * * @author https:www.unfbx.com * @since 2023-04-25 */ @Getter @Slf4j public class DynamicKeyOpenAiAuthInterceptor extends OpenAiAuthInterceptor { /** * 账号被封了 */ private static final String ACCOUNT_DEACTIVATED = "account_deactivated"; /** * key不正确 */ private static final String INVALID_API_KEY = "invalid_api_key"; /** * 请求头处理 * */ public DynamicKeyOpenAiAuthInterceptor() { this.setWarringConfig(null); } /** * 构造方法 * * @param warringConfig 所有的key都失效后的告警参数配置 */ public DynamicKeyOpenAiAuthInterceptor(Map warringConfig) { this.setWarringConfig(warringConfig); } @Override public Response intercept(Chain chain) throws IOException { String key = getKey(); Request original = chain.request(); Request request = this.auth(key, original); Response response = chain.proceed(request); if (!response.isSuccessful()) { String errorMsg = response.body().string(); if (response.code() == CommonError.OPENAI_AUTHENTICATION_ERROR.code() || response.code() == CommonError.OPENAI_LIMIT_ERROR.code() || response.code() == CommonError.OPENAI_SERVER_ERROR.code()) { OpenAiResponse openAiResponse = JSONUtil.toBean(errorMsg, OpenAiResponse.class); String errorCode = openAiResponse.getError().getCode(); log.error("--------> 请求openai异常,错误code:{}", errorCode); log.error("--------> 请求异常:{}", errorMsg); //账号被封或者key不正确就移除掉 if (ACCOUNT_DEACTIVATED.equals(errorCode) || INVALID_API_KEY.equals(errorCode)) { super.setApiKey(this.onErrorDealApiKeys(key)); } throw new BaseException(openAiResponse.getError().getMessage()); } //非官方定义的错误code log.error("--------> 请求异常:{}", errorMsg); OpenAiResponse openAiResponse = JSONUtil.toBean(errorMsg, OpenAiResponse.class); if (Objects.nonNull(openAiResponse.getError())) { log.error(openAiResponse.getError().getMessage()); throw new BaseException(openAiResponse.getError().getMessage()); } throw new BaseException(CommonError.RETRY_ERROR.msg()); } return response; } @Override protected List onErrorDealApiKeys(String errorKey) { List apiKey = super.getApiKey().stream().filter(e -> !errorKey.equals(e)).collect(Collectors.toList()); log.error("--------> 当前ApiKey:[{}] 失效了,移除!", errorKey); return apiKey; } /** * 所有的key都失效后,自定义预警配置 * 不配置直接return */ @Override protected void noHaveActiveKeyWarring() { log.error("--------> [告警] 没有可用的key!!!"); return; } @Override public Request auth(String key, Request original) { return super.auth(key, original); } }