Created
February 17, 2025 12:51
-
-
Save BlueSkyXN/356f2f120004b9b6c06cd6d3d4e7d3da to your computer and use it in GitHub Desktop.
snova2api.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 配置多个 access token(output) From https://cloud.sambanova.ai/ | |
| const ACCESS_TOKENS = [ | |
| "your_access_token_1", | |
| "your_access_token_2", | |
| "your_access_token_3" | |
| ]; | |
| // 用于验证客户端请求的 token(input) | |
| const TOKEN = "your_hardcoded_token_here"; | |
| // 记录 token 使用状态 | |
| let tokenStatus = new Map(ACCESS_TOKENS.map(token => [token, { | |
| lastUsed: 0, | |
| consecutiveFailures: 0, | |
| disabled: false | |
| }])); | |
| // 获取随机可用的 token | |
| function getRandomToken() { | |
| const availableTokens = ACCESS_TOKENS.filter(token => !tokenStatus.get(token).disabled); | |
| if (availableTokens.length === 0) { | |
| throw new Error("No available access tokens"); | |
| } | |
| return availableTokens[Math.floor(Math.random() * availableTokens.length)]; | |
| } | |
| // 更新 token 状态 | |
| function updateTokenStatus(token, success) { | |
| const status = tokenStatus.get(token); | |
| status.lastUsed = Date.now(); | |
| if (success) { | |
| status.consecutiveFailures = 0; | |
| } else { | |
| status.consecutiveFailures++; | |
| // 如果连续失败超过3次,暂时禁用该 token | |
| if (status.consecutiveFailures >= 3) { | |
| status.disabled = true; | |
| // 30分钟后自动重启 | |
| setTimeout(() => { | |
| status.disabled = false; | |
| status.consecutiveFailures = 0; | |
| }, 30 * 60 * 1000); | |
| } | |
| } | |
| tokenStatus.set(token, status); | |
| } | |
| // 使用指定 token 发送请求 | |
| async function sendRequestWithToken(token, headers, body) { | |
| const requestHeaders = new Headers(headers); | |
| requestHeaders.set("Cookie", `access_token=${token}`); | |
| const response = await fetch("https://cloud.sambanova.ai/api/completion", { | |
| method: "POST", | |
| headers: requestHeaders, | |
| body: JSON.stringify(body) | |
| }); | |
| return response; | |
| } | |
| addEventListener("fetch", (event) => { | |
| event.respondWith(handleRequest(event.request)); | |
| }); | |
| async function handleRequest(request) { | |
| // 处理 CORS 预检请求 | |
| if (request.method === "OPTIONS") { | |
| return new Response(null, { | |
| headers: { | |
| "Access-Control-Allow-Origin": "*", | |
| "Access-Control-Allow-Methods": "POST, OPTIONS", | |
| "Access-Control-Allow-Headers": "Content-Type, Authorization", | |
| "Access-Control-Max-Age": "86400", | |
| }, | |
| }); | |
| } | |
| // 只允许 POST 请求 | |
| if (request.method !== "POST") { | |
| return new Response("Method not allowed", { status: 405 }); | |
| } | |
| // 验证 Authorization 请求头 | |
| const authHeader = request.headers.get("Authorization"); | |
| if (TOKEN) { | |
| if (!authHeader || authHeader !== `Bearer ${TOKEN}`) { | |
| return new Response("Unauthorized", { | |
| status: 401, | |
| headers: { | |
| "Content-Type": "application/json", | |
| "Access-Control-Allow-Origin": "*", | |
| }, | |
| }); | |
| } | |
| } | |
| try { | |
| // 解析请求体 | |
| const body_raw = await request.json(); | |
| const body = { | |
| body: body_raw, | |
| }; | |
| // 构造请求头 | |
| const headers = new Headers({ | |
| "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0", | |
| "Accept": "text/event-stream", | |
| "Accept-Encoding": "gzip, deflate, br, zstd", | |
| "Content-Type": "application/json", | |
| "sec-ch-ua-platform": "Windows", | |
| "sec-ch-ua": "\"Not(A:Brand\";v=\"99\", \"Microsoft Edge\";v=\"133\", \"Chromium\";v=\"133\"", | |
| "sec-ch-ua-mobile": "?0", | |
| "Origin": "https://cloud.sambanova.ai", | |
| "Sec-Fetch-Site": "same-site", | |
| "Sec-Fetch-Mode": "cors", | |
| "Sec-Fetch-Dest": "empty", | |
| "Referer": "https://cloud.sambanova.ai/" | |
| }); | |
| // 尝试使用不同的 token 发送请求,直到成功或所有 token 都失败 | |
| let lastError = null; | |
| const usedTokens = new Set(); | |
| while (usedTokens.size < ACCESS_TOKENS.length) { | |
| try { | |
| const token = getRandomToken(); | |
| if (usedTokens.has(token)) { | |
| continue; | |
| } | |
| usedTokens.add(token); | |
| const response = await sendRequestWithToken(token, headers, body); | |
| // 如果请求成功 | |
| if (response.ok) { | |
| updateTokenStatus(token, true); | |
| // 构造响应并添加 CORS 头部 | |
| return new Response(response.body, { | |
| status: response.status, | |
| statusText: response.statusText, | |
| headers: { | |
| "Access-Control-Allow-Origin": "*", | |
| "Content-Type": response.headers.get("Content-Type") || "application/json", | |
| }, | |
| }); | |
| } | |
| // 如果请求失败,记录失败状态并继续尝试下一个 token | |
| updateTokenStatus(token, false); | |
| lastError = new Error(`Request failed with status ${response.status}`); | |
| } catch (error) { | |
| lastError = error; | |
| // 出现网络错误等情况,继续尝试下一个 token | |
| continue; | |
| } | |
| } | |
| // 所有 token 都尝试失败 | |
| throw lastError || new Error("All tokens failed"); | |
| } catch (error) { | |
| // 统一错误处理 | |
| return new Response(JSON.stringify({ | |
| error: error.message, | |
| code: "TOKEN_ERROR", | |
| timestamp: new Date().toISOString() | |
| }), { | |
| status: 500, | |
| headers: { | |
| "Content-Type": "application/json", | |
| "Access-Control-Allow-Origin": "*", | |
| }, | |
| }); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment