mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-23 00:53:33 +00:00
use proxy if configured in Gemini OAuth requests
This commit is contained in:
@@ -138,11 +138,19 @@ function createOAuth2Client(redirectUri = null, proxyConfig = null) {
|
|||||||
return new OAuth2Client(clientOptions)
|
return new OAuth2Client(clientOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成授权 URL (支持 PKCE)
|
// 生成授权 URL (支持 PKCE 和代理)
|
||||||
async function generateAuthUrl(state = null, redirectUri = null) {
|
async function generateAuthUrl(state = null, redirectUri = null, proxyConfig = null) {
|
||||||
// 使用新的 redirect URI
|
// 使用新的 redirect URI
|
||||||
const finalRedirectUri = redirectUri || 'https://codeassist.google.com/authcode'
|
const finalRedirectUri = redirectUri || 'https://codeassist.google.com/authcode'
|
||||||
const oAuth2Client = createOAuth2Client(finalRedirectUri)
|
const oAuth2Client = createOAuth2Client(finalRedirectUri, proxyConfig)
|
||||||
|
|
||||||
|
if (proxyConfig) {
|
||||||
|
logger.info(
|
||||||
|
`🌐 Using proxy for Gemini auth URL generation: ${ProxyHelper.getProxyDescription(proxyConfig)}`
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
logger.debug('🌐 No proxy configured for Gemini auth URL generation')
|
||||||
|
}
|
||||||
|
|
||||||
// 生成 PKCE code verifier
|
// 生成 PKCE code verifier
|
||||||
const codeVerifier = await oAuth2Client.generateCodeVerifierAsync()
|
const codeVerifier = await oAuth2Client.generateCodeVerifierAsync()
|
||||||
@@ -965,12 +973,10 @@ async function getAccountRateLimitInfo(accountId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取配置的OAuth客户端 - 参考GeminiCliSimulator的getOauthClient方法
|
// 获取配置的OAuth客户端 - 参考GeminiCliSimulator的getOauthClient方法(支持代理)
|
||||||
async function getOauthClient(accessToken, refreshToken) {
|
async function getOauthClient(accessToken, refreshToken, proxyConfig = null) {
|
||||||
const client = new OAuth2Client({
|
const client = createOAuth2Client(null, proxyConfig)
|
||||||
clientId: OAUTH_CLIENT_ID,
|
|
||||||
clientSecret: OAUTH_CLIENT_SECRET
|
|
||||||
})
|
|
||||||
const creds = {
|
const creds = {
|
||||||
access_token: accessToken,
|
access_token: accessToken,
|
||||||
refresh_token: refreshToken,
|
refresh_token: refreshToken,
|
||||||
@@ -980,6 +986,14 @@ async function getOauthClient(accessToken, refreshToken) {
|
|||||||
expiry_date: 1754269905646
|
expiry_date: 1754269905646
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (proxyConfig) {
|
||||||
|
logger.info(
|
||||||
|
`🌐 Using proxy for Gemini OAuth client: ${ProxyHelper.getProxyDescription(proxyConfig)}`
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
logger.debug('🌐 No proxy configured for Gemini OAuth client')
|
||||||
|
}
|
||||||
|
|
||||||
// 设置凭据
|
// 设置凭据
|
||||||
client.setCredentials(creds)
|
client.setCredentials(creds)
|
||||||
|
|
||||||
@@ -996,8 +1010,8 @@ async function getOauthClient(accessToken, refreshToken) {
|
|||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调用 Google Code Assist API 的 loadCodeAssist 方法
|
// 调用 Google Code Assist API 的 loadCodeAssist 方法(支持代理)
|
||||||
async function loadCodeAssist(client, projectId = null) {
|
async function loadCodeAssist(client, projectId = null, proxyConfig = null) {
|
||||||
const axios = require('axios')
|
const axios = require('axios')
|
||||||
const CODE_ASSIST_ENDPOINT = 'https://cloudcode-pa.googleapis.com'
|
const CODE_ASSIST_ENDPOINT = 'https://cloudcode-pa.googleapis.com'
|
||||||
const CODE_ASSIST_API_VERSION = 'v1internal'
|
const CODE_ASSIST_API_VERSION = 'v1internal'
|
||||||
@@ -1017,7 +1031,7 @@ async function loadCodeAssist(client, projectId = null) {
|
|||||||
metadata: clientMetadata
|
metadata: clientMetadata
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await axios({
|
const axiosConfig = {
|
||||||
url: `${CODE_ASSIST_ENDPOINT}/${CODE_ASSIST_API_VERSION}:loadCodeAssist`,
|
url: `${CODE_ASSIST_ENDPOINT}/${CODE_ASSIST_API_VERSION}:loadCodeAssist`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@@ -1026,7 +1040,20 @@ async function loadCodeAssist(client, projectId = null) {
|
|||||||
},
|
},
|
||||||
data: request,
|
data: request,
|
||||||
timeout: 30000
|
timeout: 30000
|
||||||
})
|
}
|
||||||
|
|
||||||
|
// 添加代理配置
|
||||||
|
const proxyAgent = ProxyHelper.createProxyAgent(proxyConfig)
|
||||||
|
if (proxyAgent) {
|
||||||
|
axiosConfig.httpsAgent = proxyAgent
|
||||||
|
logger.info(
|
||||||
|
`🌐 Using proxy for Gemini loadCodeAssist: ${ProxyHelper.getProxyDescription(proxyConfig)}`
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
logger.debug('🌐 No proxy configured for Gemini loadCodeAssist')
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await axios(axiosConfig)
|
||||||
|
|
||||||
logger.info('📋 loadCodeAssist API调用成功')
|
logger.info('📋 loadCodeAssist API调用成功')
|
||||||
return response.data
|
return response.data
|
||||||
@@ -1059,8 +1086,8 @@ function getOnboardTier(loadRes) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调用 Google Code Assist API 的 onboardUser 方法(包含轮询逻辑)
|
// 调用 Google Code Assist API 的 onboardUser 方法(包含轮询逻辑,支持代理)
|
||||||
async function onboardUser(client, tierId, projectId, clientMetadata) {
|
async function onboardUser(client, tierId, projectId, clientMetadata, proxyConfig = null) {
|
||||||
const axios = require('axios')
|
const axios = require('axios')
|
||||||
const CODE_ASSIST_ENDPOINT = 'https://cloudcode-pa.googleapis.com'
|
const CODE_ASSIST_ENDPOINT = 'https://cloudcode-pa.googleapis.com'
|
||||||
const CODE_ASSIST_API_VERSION = 'v1internal'
|
const CODE_ASSIST_API_VERSION = 'v1internal'
|
||||||
@@ -1073,15 +1100,8 @@ async function onboardUser(client, tierId, projectId, clientMetadata) {
|
|||||||
metadata: clientMetadata
|
metadata: clientMetadata
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info('📋 开始onboardUser API调用', {
|
// 创建基础axios配置
|
||||||
tierId,
|
const baseAxiosConfig = {
|
||||||
projectId,
|
|
||||||
hasProjectId: !!projectId,
|
|
||||||
isFreeTier: tierId === 'free-tier' || tierId === 'FREE'
|
|
||||||
})
|
|
||||||
|
|
||||||
// 轮询onboardUser直到长运行操作完成
|
|
||||||
let lroRes = await axios({
|
|
||||||
url: `${CODE_ASSIST_ENDPOINT}/${CODE_ASSIST_API_VERSION}:onboardUser`,
|
url: `${CODE_ASSIST_ENDPOINT}/${CODE_ASSIST_API_VERSION}:onboardUser`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@@ -1090,8 +1110,29 @@ async function onboardUser(client, tierId, projectId, clientMetadata) {
|
|||||||
},
|
},
|
||||||
data: onboardReq,
|
data: onboardReq,
|
||||||
timeout: 30000
|
timeout: 30000
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加代理配置
|
||||||
|
const proxyAgent = ProxyHelper.createProxyAgent(proxyConfig)
|
||||||
|
if (proxyAgent) {
|
||||||
|
baseAxiosConfig.httpsAgent = proxyAgent
|
||||||
|
logger.info(
|
||||||
|
`🌐 Using proxy for Gemini onboardUser: ${ProxyHelper.getProxyDescription(proxyConfig)}`
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
logger.debug('🌐 No proxy configured for Gemini onboardUser')
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info('📋 开始onboardUser API调用', {
|
||||||
|
tierId,
|
||||||
|
projectId,
|
||||||
|
hasProjectId: !!projectId,
|
||||||
|
isFreeTier: tierId === 'free-tier' || tierId === 'FREE'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 轮询onboardUser直到长运行操作完成
|
||||||
|
let lroRes = await axios(baseAxiosConfig)
|
||||||
|
|
||||||
let attempts = 0
|
let attempts = 0
|
||||||
const maxAttempts = 12 // 最多等待1分钟(5秒 * 12次)
|
const maxAttempts = 12 // 最多等待1分钟(5秒 * 12次)
|
||||||
|
|
||||||
@@ -1099,17 +1140,7 @@ async function onboardUser(client, tierId, projectId, clientMetadata) {
|
|||||||
logger.info(`⏳ 等待onboardUser完成... (${attempts + 1}/${maxAttempts})`)
|
logger.info(`⏳ 等待onboardUser完成... (${attempts + 1}/${maxAttempts})`)
|
||||||
await new Promise((resolve) => setTimeout(resolve, 5000))
|
await new Promise((resolve) => setTimeout(resolve, 5000))
|
||||||
|
|
||||||
lroRes = await axios({
|
lroRes = await axios(baseAxiosConfig)
|
||||||
url: `${CODE_ASSIST_ENDPOINT}/${CODE_ASSIST_API_VERSION}:onboardUser`,
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
data: onboardReq,
|
|
||||||
timeout: 30000
|
|
||||||
})
|
|
||||||
|
|
||||||
attempts++
|
attempts++
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1121,8 +1152,13 @@ async function onboardUser(client, tierId, projectId, clientMetadata) {
|
|||||||
return lroRes.data
|
return lroRes.data
|
||||||
}
|
}
|
||||||
|
|
||||||
// 完整的用户设置流程 - 参考setup.ts的逻辑
|
// 完整的用户设置流程 - 参考setup.ts的逻辑(支持代理)
|
||||||
async function setupUser(client, initialProjectId = null, clientMetadata = null) {
|
async function setupUser(
|
||||||
|
client,
|
||||||
|
initialProjectId = null,
|
||||||
|
clientMetadata = null,
|
||||||
|
proxyConfig = null
|
||||||
|
) {
|
||||||
logger.info('🚀 setupUser 开始', { initialProjectId, hasClientMetadata: !!clientMetadata })
|
logger.info('🚀 setupUser 开始', { initialProjectId, hasClientMetadata: !!clientMetadata })
|
||||||
|
|
||||||
let projectId = initialProjectId || process.env.GOOGLE_CLOUD_PROJECT || null
|
let projectId = initialProjectId || process.env.GOOGLE_CLOUD_PROJECT || null
|
||||||
@@ -1141,7 +1177,7 @@ async function setupUser(client, initialProjectId = null, clientMetadata = null)
|
|||||||
|
|
||||||
// 调用loadCodeAssist
|
// 调用loadCodeAssist
|
||||||
logger.info('📞 调用 loadCodeAssist...')
|
logger.info('📞 调用 loadCodeAssist...')
|
||||||
const loadRes = await loadCodeAssist(client, projectId)
|
const loadRes = await loadCodeAssist(client, projectId, proxyConfig)
|
||||||
logger.info('✅ loadCodeAssist 完成', {
|
logger.info('✅ loadCodeAssist 完成', {
|
||||||
hasCloudaicompanionProject: !!loadRes.cloudaicompanionProject
|
hasCloudaicompanionProject: !!loadRes.cloudaicompanionProject
|
||||||
})
|
})
|
||||||
@@ -1164,7 +1200,7 @@ async function setupUser(client, initialProjectId = null, clientMetadata = null)
|
|||||||
|
|
||||||
// 调用onboardUser
|
// 调用onboardUser
|
||||||
logger.info('📞 调用 onboardUser...', { tierId: tier.id, projectId })
|
logger.info('📞 调用 onboardUser...', { tierId: tier.id, projectId })
|
||||||
const lroRes = await onboardUser(client, tier.id, projectId, clientMetadata)
|
const lroRes = await onboardUser(client, tier.id, projectId, clientMetadata, proxyConfig)
|
||||||
logger.info('✅ onboardUser 完成', { hasDone: !!lroRes.done, hasResponse: !!lroRes.response })
|
logger.info('✅ onboardUser 完成', { hasDone: !!lroRes.done, hasResponse: !!lroRes.response })
|
||||||
|
|
||||||
const result = {
|
const result = {
|
||||||
@@ -1178,8 +1214,8 @@ async function setupUser(client, initialProjectId = null, clientMetadata = null)
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调用 Code Assist API 计算 token 数量
|
// 调用 Code Assist API 计算 token 数量(支持代理)
|
||||||
async function countTokens(client, contents, model = 'gemini-2.0-flash-exp') {
|
async function countTokens(client, contents, model = 'gemini-2.0-flash-exp', proxyConfig = null) {
|
||||||
const axios = require('axios')
|
const axios = require('axios')
|
||||||
const CODE_ASSIST_ENDPOINT = 'https://cloudcode-pa.googleapis.com'
|
const CODE_ASSIST_ENDPOINT = 'https://cloudcode-pa.googleapis.com'
|
||||||
const CODE_ASSIST_API_VERSION = 'v1internal'
|
const CODE_ASSIST_API_VERSION = 'v1internal'
|
||||||
@@ -1196,7 +1232,7 @@ async function countTokens(client, contents, model = 'gemini-2.0-flash-exp') {
|
|||||||
|
|
||||||
logger.info('📊 countTokens API调用开始', { model, contentsLength: contents.length })
|
logger.info('📊 countTokens API调用开始', { model, contentsLength: contents.length })
|
||||||
|
|
||||||
const response = await axios({
|
const axiosConfig = {
|
||||||
url: `${CODE_ASSIST_ENDPOINT}/${CODE_ASSIST_API_VERSION}:countTokens`,
|
url: `${CODE_ASSIST_ENDPOINT}/${CODE_ASSIST_API_VERSION}:countTokens`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@@ -1205,7 +1241,20 @@ async function countTokens(client, contents, model = 'gemini-2.0-flash-exp') {
|
|||||||
},
|
},
|
||||||
data: request,
|
data: request,
|
||||||
timeout: 30000
|
timeout: 30000
|
||||||
})
|
}
|
||||||
|
|
||||||
|
// 添加代理配置
|
||||||
|
const proxyAgent = ProxyHelper.createProxyAgent(proxyConfig)
|
||||||
|
if (proxyAgent) {
|
||||||
|
axiosConfig.httpsAgent = proxyAgent
|
||||||
|
logger.info(
|
||||||
|
`🌐 Using proxy for Gemini countTokens: ${ProxyHelper.getProxyDescription(proxyConfig)}`
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
logger.debug('🌐 No proxy configured for Gemini countTokens')
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await axios(axiosConfig)
|
||||||
|
|
||||||
logger.info('✅ countTokens API调用成功', { totalTokens: response.data.totalTokens })
|
logger.info('✅ countTokens API调用成功', { totalTokens: response.data.totalTokens })
|
||||||
return response.data
|
return response.data
|
||||||
|
|||||||
Reference in New Issue
Block a user