批量测活refresh token、claude session key、gemini api服务玩具

使用claude搞的玩具
demo: Token Checker

可用下面的cf worker代码直接部署

通过生成at测活rt(好像没啥用),可下载csv:

批量测活claude sessionkey,可下载csv,现在引用重试机制,解决了官方接口有效的sessionkey有时候调用会403的bug
引用重试


没引用重试

批量测活gemini api,Gemini并发推荐设置为2:


cf worker代码:

addEventListener('fetch', function(event) {
  event.respondWith(handleRequest(event.request));
});

var corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
  'Access-Control-Allow-Headers': 'Content-Type',
};

function handleRequest(request) {
  console.log('Received request:', request.method, request.url);

  if (request.method === 'OPTIONS') {
    return new Response(null, { headers: corsHeaders });
  }

  if (request.method === 'POST') {
    return request.json().then(function(content) {
      console.log('Request body:', JSON.stringify(content));
      var type = content.type;
    
      var responsePromise;
      if (type === 'refreshTokens') {
        responsePromise = handleRefreshTokens(content.tokens);
      } else if (type === 'sessionKeys') {
        responsePromise = handleSessionKeys(content);
      } else if (type === 'geminiAPI') {
        responsePromise = handleTestAPIs(content);
      } else {
        responsePromise = Promise.resolve(new Response(JSON.stringify({ error: 'Invalid request type' }), {
          status: 400,
          headers: { 'Content-Type': 'application/json' }
        }));
      }

      return responsePromise.then(function(response) {
        return addCorsHeaders(response);
      }).catch(function(error) {
        console.error('Error processing request:', error);
        return addCorsHeaders(new Response(JSON.stringify({ error: error.message }), {
          status: 500,
          headers: { 'Content-Type': 'application/json' }
        }));
      });
    });
  } else if (request.method === 'GET') {
    return new Response(renderHTML(), {
      headers: Object.assign({}, corsHeaders, { 'Content-Type': 'text/html; charset=utf-8' })
    });
  }
  
  return new Response('Not Found', { status: 404 });
}

function addCorsHeaders(response) {
  var headers = new Headers(response.headers);
  Object.keys(corsHeaders).forEach(function(key) {
    headers.set(key, corsHeaders[key]);
  });
  return new Response(response.body, {
    status: response.status,
    statusText: response.statusText,
    headers: headers
  });
}

function handleRefreshTokens(refreshTokens) {
  return Promise.all(refreshTokens.map(checkTokenValidity)).then(function(results) {
    return new Response(JSON.stringify(results), {
      headers: { 'Content-Type': 'application/json' }
    });
  }).catch(function(error) {
    throw new Error('Error processing refresh tokens: ' + error.message);
  });
}

function checkTokenValidity(refreshToken) {
  return fetch('https://token.oaifree.com/api/auth/refresh', {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: 'refresh_token=' + encodeURIComponent(refreshToken)
  }).then(function(response) {
    if (response.ok) {
      return response.json().then(function(data) {
        return { refreshToken: refreshToken, accessToken: data.access_token, valid: true };
      });
    }
    return { refreshToken: refreshToken, accessToken: null, valid: false };
  }).catch(function() {
    return { refreshToken: refreshToken, accessToken: null, valid: false };
  });
}

function handleSessionKeys(content) {
  var sessionKeys = content.tokens;
  var maxAttempts = content.maxAttempts;
  var requestsPerSecond = content.requestsPerSecond;
  var delayBetweenRequests = 1000 / requestsPerSecond;

  function delay(ms) {
    return new Promise(function(resolve) {
      setTimeout(resolve, ms);
    });
  }

  function checkSessionKey(sessionKey) {
    var attempts = 0;
    var successCount = 0;

    function attemptCheck() {
      attempts++;
      return fetch('https://api.claude.ai/api/organizations', {
        headers: {
          'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
          'accept-language': 'en-US,en;q=0.9',
          'cache-control': 'max-age=0',
          'cookie': 'sessionKey=' + sessionKey,
          'user-agent': 'Mozilla/5.0 (X11; Linux x86_64)',
          'sec-fetch-mode': 'navigate',
          'sec-fetch-site': 'none'
        }
      }).then(function(response) {
        if (!response.ok) {
          throw new Error('HTTP error! status: ' + response.status);
        }
        return response.text();
      }).then(function(responseText) {
        if (responseText.toLowerCase().includes('unauthorized') || responseText.trim() === '') {
          throw new Error('Invalid response');
        }
        var objects = JSON.parse(responseText);
        successCount++;
        var name = objects[0].name || 'Unknown';
        var capabilities = objects[0].capabilities ? objects[0].capabilities.join(';') : '';
        return {
          sessionKey: sessionKey,
          name: name,
          capabilities: capabilities,
          available: true,
          attempts: attempts,
          successRate: successCount / attempts
        };
      }).catch(function(error) {
        if (attempts < maxAttempts) {
          return delay(delayBetweenRequests).then(attemptCheck);
        }
        return {
          sessionKey: sessionKey,
          name: 'Invalid',
          capabilities: '',
          available: false,
          attempts: attempts,
          successRate: successCount / attempts
        };
      });
    }

    return attemptCheck();
  }

  return Promise.all(sessionKeys.map(checkSessionKey)).then(function(results) {
    return new Response(JSON.stringify(results), {
      headers: { 'Content-Type': 'application/json' }
    });
  }).catch(function(error) {
    throw new Error('Error processing session keys: ' + error.message);
  });
}

function handleTestAPIs(content) {
  var apiKeys = content.tokens;
  var model = content.model;
  var rateLimit = content.rateLimit;
  var prompt = content.prompt;
  var user = content.user;

  if (!apiKeys || !Array.isArray(apiKeys) || apiKeys.length === 0) {
    throw new Error('Invalid or empty API keys');
  }

  return batchTestAPI(apiKeys, model, rateLimit, prompt, user).then(function(results) {
    var validKeys = results.filter(function(r) { return r.valid; }).map(function(r) { return r.key; });
    var invalidKeys = results.filter(function(r) { return !r.valid; }).map(function(r) { return r.key; });
    var errors = results.filter(function(r) { return r.error; }).map(function(r) { return { key: r.key, error: r.error }; });
    var validResults = results.filter(function(r) { return r.valid && r.data; });
    
    return new Response(JSON.stringify({
      valid: validKeys.length,
      invalid: invalidKeys.length,
      invalidKeys: invalidKeys,
      errors: errors,
      validResults: validResults
    }), {
      headers: { 'Content-Type': 'application/json' }
    });
  }).catch(function(error) {
    throw new Error('Error testing APIs: ' + error.message);
  });
}

function batchTestAPI(apiKeys, model, rateLimit, prompt, user) {
  var results = [];
  var delayBetweenRequests = 1000 / rateLimit;

  function delay(ms) {
    return new Promise(function(resolve) {
      setTimeout(resolve, ms);
    });
  }

  function testNextKey(index) {
    if (index >= apiKeys.length) {
      return Promise.resolve(results);
    }

    return testAPI(apiKeys[index], model, prompt, user).then(function(result) {
      results.push(result);
    }).catch(function(error) {
      results.push({ key: apiKeys[index], valid: false, error: error.message });
    }).then(function() {
      return delay(delayBetweenRequests);
    }).then(function() {
      return testNextKey(index + 1);
    });
  }

  return testNextKey(0);
}

function testAPI(apiKey, model, prompt, user) {
  var url = 'https://generativelanguage.googleapis.com/v1beta/models/' + model + ':generateContent?key=' + apiKey;
  return fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      contents: [{ 
        parts: [
          { text: prompt },
          { text: user }
        ] 
      }],
      safetySettings: [
        { category: "HARM_CATEGORY_DANGEROUS_CONTENT", threshold: "BLOCK_NONE" },
        { category: "HARM_CATEGORY_HATE_SPEECH", threshold: "BLOCK_NONE" },
        { category: "HARM_CATEGORY_HARASSMENT", threshold: "BLOCK_NONE" },
        { category: "HARM_CATEGORY_SEXUALLY_EXPLICIT", threshold: "BLOCK_NONE" }
      ]
    })
  }).then(function(response) {
    if (!response.ok) {
      return response.text().then(function(errorText) {
        throw new Error('API request failed: ' + response.status + ' ' + response.statusText + ' - ' + errorText);
      });
    }
    return response.json();
  }).then(function(data) {
    return { key: apiKey, valid: true, data: data };
  });
}

function renderHTML() {
  return `
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Token Checker</title>
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
  <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;700&family=Source+Code+Pro&display=swap" rel="stylesheet">
  <style>
    body, html {
      background-color: #0a0a1e;
      color: #00ffff;
      font-family: 'Orbitron', sans-serif;
      height: 100%;
      margin: 0;
      padding: 0;
      overflow-x: hidden;
    }
    .container {
      max-width: 1200px;
      padding: 20px;
      background: rgba(10, 10, 30, 0.9);
      border-radius: 15px;
      box-shadow: 0 0 20px rgba(0, 255, 255, 0.5);
    }
    h1, h2, h3, h4, h5, h6 {
      color: #00ffff;
      text-shadow: 0 0 10px #00ffff;
    }
    .form-control, .btn {
      background-color: #1a1a3e;
      border-color: #00ffff;
      color: #00ffff;
      margin: 5px 0;
    }
    .form-control:focus {
      background-color: #2a2a5e;
      border-color: #00ffff;
      color: #00ffff;
      box-shadow: 0 0 0 0.25rem rgba(0, 255, 255, 0.25);
    }
    textarea.form-control, .table td {
      font-family: 'Source Code Pro', monospace;
    }
    .table {
      color: #00ffff;
      border-color: #00ffff;
      background-color: #1a1a3e;
    }
    .table th, .table td {
      border-color: #00ffff;
      color: #00ffff;
    }
    .table tr {
      border-bottom: none;
    }
    .table-striped>tbody>tr:nth-of-type(odd)>* {
      --bs-table-accent-bg: var(--bs-table-striped-bg);
      color: #00ffff;
    }
    .truncate {
      max-width: 150px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .table-custom {
      border-radius: 10px;
      overflow: hidden;
      border: 1px solid #00ffff;
    }
    .table-custom thead th {
      background-color: rgba(0, 255, 255, 0.2);
      border-bottom: 2px solid #00ffff;
    }
    .table-custom tbody td {
      padding: 12px;
    }
    .nav-tabs {
      border-bottom: none;
    }
    .nav-tabs .nav-link {
      color: #00ffff;
      background-color: transparent !important;
      border: 2px solid #00ffff;
      position: relative;
      transition: all 0.3s ease;
      margin-right: 10px;
      padding: 10px 20px;
      border-radius: 5px;
      overflow: hidden;
    }
    .nav-tabs .nav-link:hover {
      color: #ff00ff;
    }
    .nav-tabs .nav-link.active {
      color: #ff00ff;
      border-color: #ff00ff;
    }
    .btn-cyberpunk {
      background: transparent;
      color: #00ffff;
      font-weight: bold;
      text-transform: uppercase;
      letter-spacing: 2px;
      position: relative;
      overflow: hidden;
      z-index: 1;
      transition: all 0.3s ease;
      padding: 12px 24px;
      border-radius: 5px;
      border: 2px solid #00ffff;
    }
    .btn-cyberpunk:hover {
      color: #ff00ff;
    }
    .btn-cyberpunk:active {
      transform: scale(0.95);
    }
    .btn-cyberpunk .ripple {
      position: absolute;
      border-radius: 50%;
      background-color: rgba(255, 255, 255, 0.7);
      transform: scale(0);
      animation: ripple 0.6s linear;
    }
    @keyframes ripple {
      to {
        transform: scale(4);
        opacity: 0;
      }
    }
    .toast {
      position: fixed;
      top: 20px;
      right: 20px;
      background-color: rgba(0, 255, 255, 0.8);
      color: #0a0a1e;
      padding: 10px 20px;
      border-radius: 5px;
      display: none;
      z-index: 1000;
    }
    .text-center *::-webkit-scrollbar,
    textarea::-webkit-scrollbar {
      width: 2px;
      height: 2px;
    }
    .text-center *::-webkit-scrollbar-track,
    textarea::-webkit-scrollbar-track {
      background: #0a0a1e;
    }
    .text-center *::-webkit-scrollbar-thumb,
    textarea::-webkit-scrollbar-thumb {
      background: linear-gradient(45deg, #ff00ff, #00ffff);
      border-radius: 1px;
    }
    .text-center *::-webkit-scrollbar-thumb:hover,
    textarea::-webkit-scrollbar-thumb:hover {
      background: linear-gradient(45deg, #00ffff, #ff00ff);
    }
    .cyberpunk-toggle {
      display: inline-block;
      margin-right: 15px;
    }
    .cyberpunk-checkbox {
      display: none;
    }
    .cyberpunk-label {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      min-width: 180px;
      height: 40px;
      background: #333;
      border: 2px solid #00ffff;
      border-radius: 20px;
      position: relative;
      cursor: pointer;
      transition: 0.3s;
      font-size: 14px;
      line-height: 1;
      padding: 0 15px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .cyberpunk-label:after {
      content: '';
      position: absolute;
      width: 36px;
      height: 36px;
      border-radius: 50%;
      top: 0;
      left: 0;
      background: #00ffff;
      transition: 0.3s;
    }
    .cyberpunk-checkbox:checked + .cyberpunk-label {
      background: #00ffff;
      color: #333;
    }
    .cyberpunk-checkbox:checked + .cyberpunk-label:after {
      left: calc(100% - 36px);
      background: #333;
    }
  </style>
</head>
<body>
  <div class="container mt-5">
    <h1 class="text-center mb-4">Token Checker</h1>
    <ul class="nav nav-tabs mb-3" id="myTab" role="tablist">
      <li class="nav-item" role="presentation">
        <button class="nav-link active" id="refresh-tab" data-bs-toggle="tab" data-bs-target="#refresh" type="button" role="tab" aria-controls="refresh" aria-selected="true">Refresh Tokens</button>
      </li>
      <li class="nav-item" role="presentation">
        <button class="nav-link" id="session-tab" data-bs-toggle="tab" data-bs-target="#session" type="button" role="tab" aria-controls="session" aria-selected="false">Session Keys</button>
      </li>
      <li class="nav-item" role="presentation">
        <button class="nav-link" id="gemini-tab" data-bs-toggle="tab" data-bs-target="#gemini" type="button" role="tab" aria-controls="gemini" aria-selected="false">Gemini API</button>
      </li>
    </ul>
    <div class="tab-content" id="myTabContent">
      <div class="tab-pane fade show active" id="refresh" role="tabpanel" aria-labelledby="refresh-tab">
        <textarea class="form-control mb-3" id="refreshTokensInput" rows="10" placeholder="Enter refresh tokens, one per line"></textarea>
        <button class="btn btn-cyberpunk mt-3" onclick="processTokens('refreshTokens')">Check Refresh Tokens</button>
        <button class="btn btn-cyberpunk mt-3" id="downloadRefreshTokensCSV" style="display: none;">Download CSV</button>
        <div class="table-responsive mt-3">
          <table class="table table-custom table-striped" id="refreshTokensTable">
            <thead>
              <tr>
                <th>Refresh Token</th>
                <th>Access Token</th>
                <th>Valid</th>
                <th>Action</th>
              </tr>
            </thead>
            <tbody id="refreshTokensBody"></tbody>
          </table>
        </div>
      </div>
      <div class="tab-pane fade" id="session" role="tabpanel" aria-labelledby="session-tab">
        <textarea class="form-control mb-3" id="sessionKeysInput" rows="10" placeholder="Enter session keys, one per line"></textarea>
        <div class="row mb-3">
          <div class="col-md-6">
            <label for="maxAttempts" class="form-label">Max Attempts per Session Key</label>
            <input type="number" class="form-control" id="maxAttempts" value="5" min="1" max="10">
          </div>
          <div class="col-md-6">
            <label for="requestsPerSecond" class="form-label">Requests per Second</label>
            <input type="number" class="form-control" id="requestsPerSecond" value="2" min="1" max="5">
          </div>
        </div>
        <button class="btn btn-cyberpunk mt-3" onclick="processTokens('sessionKeys')">Check Session Keys</button>
        <button class="btn btn-cyberpunk mt-3" id="downloadSessionKeysCSV" style="display: none;">Download CSV</button>
        <div class="table-responsive mt-3">
          <table class="table table-custom table-striped" id="sessionKeysTable">
            <thead>
              <tr>
                <th>Session Key</th>
                <th>Name</th>
                <th>Capabilities</th>
                <th>Available</th>
                <th>Attempts</th>
                <th>Success Rate</th>
              </tr>
            </thead>
            <tbody id="sessionKeysBody"></tbody>
          </table>
        </div>
      </div>
      <div class="tab-pane fade" id="gemini" role="tabpanel" aria-labelledby="gemini-tab">
        <textarea class="form-control mb-3" id="geminiAPIInput" rows="10" placeholder="Enter Gemini API keys, one per line"></textarea>
        <div class="row">
          <div class="col-md-6">
            <label for="geminiModel" class="form-label">Model</label>
            <input type="text" class="form-control" id="geminiModel" value="gemini-1.5-flash-002" placeholder="Enter model name">
          </div>
          <div class="col-md-6">
            <label for="geminiRateLimit" class="form-label">Requests per Second</label>
            <input type="number" class="form-control" id="geminiRateLimit" value="2" min="1" max="10" placeholder="Requests per second">
          </div>
        </div>
        <div class="row mt-3">
          <div class="col-12 d-flex justify-content-start align-items-center">
            <div class="cyberpunk-toggle">
              <input type="checkbox" id="chatToggle" class="cyberpunk-checkbox">
              <label for="chatToggle" class="cyberpunk-label">Chat Toggle</label>
            </div>
            <div class="cyberpunk-toggle">
              <input type="checkbox" id="showValidResults" class="cyberpunk-checkbox">
              <label for="showValidResults" class="cyberpunk-label">Valid API Results</label>
            </div>
          </div>
        </div>
        <div id="chatInputs" style="display: none;">
          <div class="row mt-3">
            <div class="col-12">
              <label for="geminiPrompt" class="form-label">Prompt</label>
              <textarea class="form-control" id="geminiPrompt" rows="3">用中文回答</textarea>
            </div>
          </div>
          <div class="row mt-3">
            <div class="col-12">
              <label for="geminiUser" class="form-label">User</label>
              <textarea class="form-control" id="geminiUser" rows="3">请进行自我介绍</textarea>
            </div>
          </div>
          <div class="row mt-3">
            <div class="col-12">
              <label for="geminiResult" class="form-label">Gemini</label>
              <textarea class="form-control" style="background-color:#1a1a3e;" id="geminiResult" rows="3" readonly></textarea>
            </div>
          </div>
        </div>
        <button class="btn btn-cyberpunk mt-3" onclick="processTokens('geminiAPI')">Test Gemini APIs</button>
        <div id="geminiAPIResult" class="mt-3"></div>
        <h5 class="mt-3">Valid API Results:</h5>
        <div class="table-responsive mt-3">
          <table class="table table-custom table-striped" id="geminiValidResultsTable" style="display: none;">
            <thead>
              <tr>
                <th>API Key</th>
                <th>Generated Content</th>
              </tr>
            </thead>
            <tbody></tbody>
          </table>
        </div>
        <h5 class="mt-3">Invalid API Keys:</h5>
        <div class="table-responsive mt-3">
          <table class="table table-custom table-striped" id="geminiInvalidKeysTable">
            <thead>
              <tr>
                <th>API Key</th>
                <th>Error Message</th>
              </tr>
            </thead>
            <tbody></tbody>
          </table>
        </div>
      </div>
    </div>
  </div>
  <div id="toast" class="toast">Copied successfully</div>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
  <script>
    function processTokens(type) {
      var input = document.getElementById(type + "Input").value;
      var tokens = input.split("\\n").filter(function(token) { return token.trim() !== ""; });
      var data = { type: type, tokens: tokens };
      
      if (type === 'sessionKeys') {
        data.maxAttempts = parseInt(document.getElementById('maxAttempts').value);
        data.requestsPerSecond = parseInt(document.getElementById('requestsPerSecond').value);
      } else if (type === 'geminiAPI') {
        data.model = document.getElementById('geminiModel').value.trim();
        data.rateLimit = parseInt(document.getElementById('geminiRateLimit').value);
        data.prompt = document.getElementById('geminiPrompt').value.trim();
        data.user = document.getElementById('geminiUser').value.trim();
      }
      
      fetch("/", {
        method: "POST",
        headers: { 
          "Content-Type": "application/json"
        },
        body: JSON.stringify(data)
      })
      .then(function(response) {
        if (!response.ok) {
          return response.json().then(function(err) { throw new Error(err.error || 'Unknown error'); });
        }
        return response.json();
      })
      .then(function(results) {
        if (type === 'geminiAPI') {
          displayGeminiResults(results);
        } else {
          displayResults(results, type); 
        }
      })
      .catch(function(error) {
        console.error('Error:', error);
        alert("Error processing request: " + error.message);
      });
    }

    function displayResults(results, type) {
      var table = document.getElementById(type + "Table");
      var body = document.getElementById(type + "Body");
      var downloadButton = document.getElementById("download" + type.charAt(0).toUpperCase() + type.slice(1) + "CSV");
      body.innerHTML = "";
      if (type === "refreshTokens") {
        results.forEach(function(result) {
          var row = body.insertRow();
          row.insertCell(0).textContent = result.refreshToken;
          var accessTokenCell = row.insertCell(1);
          accessTokenCell.innerHTML = '<div class="truncate" title="' + (result.accessToken || "N/A") + '">' + (result.accessToken ? result.accessToken.substring(0, 10) + "..." : "N/A") + '</div>';
          row.insertCell(2).textContent = result.valid ? "Valid" : "Invalid";
          var actionCell = row.insertCell(3);
          if (result.accessToken) {
            var copyButton = document.createElement("button");
            copyButton.textContent = "Copy AT";
            copyButton.className = "btn btn-sm btn-outline-primary";
            copyButton.onclick = function() { copyToClipboard(result.accessToken); };
            actionCell.appendChild(copyButton);
          }
        });
      } else if (type === "sessionKeys") {
        results.forEach(function(result) {
          var row = body.insertRow();
          var sessionKeyCell = row.insertCell(0);
          sessionKeyCell.innerHTML = '<div class="truncate" title="' + result.sessionKey + '">' + result.sessionKey.substring(0, 10) + "..." + '</div>';
          row.insertCell(1).textContent = result.name;
          row.insertCell(2).textContent = result.capabilities;
          row.insertCell(3).textContent = result.available ? "Yes" : "No";
          row.insertCell(4).textContent = result.attempts;
          row.insertCell(5).textContent = (result.successRate * 100).toFixed(2) + "%";
        });
      }
      table.style.display = "table";
      downloadButton.style.display = "inline-block";
      downloadButton.onclick = function() { downloadCSV(results, type); };
    }

    function displayGeminiResults(results) {
      var resultDiv = document.getElementById('geminiAPIResult');
      var invalidKeysTable = document.getElementById('geminiInvalidKeysTable').getElementsByTagName('tbody')[0];
      var validResultsTable = document.getElementById('geminiValidResultsTable').getElementsByTagName('tbody')[0];
      var showValidResults = document.getElementById('showValidResults').checked;

      resultDiv.innerHTML = 'Test completed. Valid: ' + results.valid + ', Invalid: ' + results.invalid;
      
      invalidKeysTable.innerHTML = '';
      validResultsTable.innerHTML = '';
      
      if (results.errors && results.errors.length > 0) {
        results.errors.forEach(function(error) {
          var row = invalidKeysTable.insertRow();
          var cellKey = row.insertCell(0);
          var cellError = row.insertCell(1);
          
          cellKey.textContent = error.key;
          var errorMessage = error.error;
          if (typeof errorMessage === 'object' && errorMessage !== null) {
            cellError.textContent = errorMessage.message || JSON.stringify(errorMessage);
          } else {
            cellError.textContent = errorMessage || 'Unknown error';
          }
        });
      }

      if (showValidResults && results.validResults && results.validResults.length > 0) {
        results.validResults.forEach(function(result) {
          var row = validResultsTable.insertRow();
          var cellKey = row.insertCell(0);
          var cellContent = row.insertCell(1);
          
          cellKey.textContent = result.key;
          cellContent.textContent = result.data.candidates[0].content.parts[0].text;
        });

        if (document.getElementById('chatToggle').checked) {
          document.getElementById('geminiResult').value = results.validResults[0].data.candidates[0].content.parts[0].text;
        }
      }

      document.getElementById('geminiValidResultsTable').style.display = showValidResults ? 'table' : 'none';
    }

    function copyToClipboard(text) {
      var textArea = document.createElement("textarea");
      textArea.value = text;
      document.body.appendChild(textArea);
      textArea.select();
      document.execCommand("copy");
      document.body.removeChild(textArea);
      showToast();
    }

    function showToast() {
      var toast = document.getElementById("toast");
      toast.style.display = "block";
      setTimeout(function() {
        toast.style.display = "none";
      }, 3000);
    }

    function downloadCSV(results, type) {
      var csvContent = "\\uFEFF";
      if (type === "refreshTokens") {
        csvContent += "Refresh Token,Access Token,Valid\\n";
        results.forEach(function(result) {
          csvContent += result.refreshToken + "," + (result.accessToken || "") + "," + result.valid + "\\n";
        });
      } else if (type === "sessionKeys") {
        csvContent += "SessionKey,Name,Capabilities,Available,Attempts,Success Rate\\n";
        results.forEach(function(result) {
          csvContent += result.sessionKey + "," + result.name + "," + result.capabilities + "," + 
                        (result.available ? "Yes" : "No") + "," + result.attempts + "," + 
                        (result.successRate * 100).toFixed(2) + "%\\n";
        });
      }
      var blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
      var link = document.createElement("a");
      if (link.download !== undefined) {
        var url = URL.createObjectURL(blob);
        link.setAttribute("href", url);
        link.setAttribute("download", type + "_results.csv");
        link.style.visibility = 'hidden';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      }
    }

    function createRipple(event) {
      var button = event.currentTarget;
      var ripple = document.createElement('span');
      var rect = button.getBoundingClientRect();
      var size = Math.max(rect.width, rect.height);
      var x = event.clientX - rect.left - size / 2;
      var y = event.clientY - rect.top - size / 2;
      
      ripple.style.width = ripple.style.height = size + 'px';
      ripple.style.left = x + 'px';
      ripple.style.top = y + 'px';
      ripple.className = 'ripple';
      
      button.appendChild(ripple);
      
      setTimeout(function() {
        ripple.remove();
      }, 600);
    }

    document.addEventListener('DOMContentLoaded', function() {
      var buttons = document.querySelectorAll('.btn-cyberpunk');
      buttons.forEach(function(button) {
        button.addEventListener('click', createRipple);
      });

      var showValidResultsCheckbox = document.getElementById('showValidResults');
      showValidResultsCheckbox.addEventListener('change', function() {
        var validResultsTable = document.getElementById('geminiValidResultsTable');
        validResultsTable.style.display = this.checked ? 'table' : 'none';
      });
      
      var chatToggle = document.getElementById('chatToggle');
      var chatInputs = document.getElementById('chatInputs');
      
      chatToggle.addEventListener('change', function() {
        chatInputs.style.display = this.checked ? 'block' : 'none';
      });
      
      var validResultsTable = document.getElementById('geminiValidResultsTable');
      validResultsTable.style.display = 'none';
      
      chatInputs.style.display = 'none';
    });
  </script>
</body>
</html>
  `;
}

claude sessionkey参考了
Cloudfare Worker 部署 Claude sessionKey 批量测活网站 - 开发调优 - LINUX DO
Claude sessionkey批量测活 - 开发调优 - LINUX DO

总结,好像没啥用

175 个赞

大佬厉害啊!

6 个赞

大佬好厉害,这个好!!

33 个赞

感谢分享大佬厉害~

4 个赞

太强了!大佬!

5 个赞

好东西 感谢大佬

5 个赞

大佬,太强了

太棒啦!!点赞!拿去worker部署下试试!!

sessionkey 不行。

1 个赞

我找了1个 sk.然后一会403 一会yes。

1 个赞

原项目也有这个问题,官方接口自身的问题
换ip刷新几次和多检查几次就可以。

UI漂亮,有claude号池么


只是自己有三个号
然后论坛里面白嫖了两个

UI针不戳 :tieba_020: :tieba_020:

现在引用重试机制,解决了官方接口有效的sessionkey有时候调用会403的问题

1 个赞

这么多码,厉害了

看上去似乎很有用,实际上对我来说非常有用!! :grinning:

请问一下gemini同号申请多个key有意义吗?同一个账号的cd是否公用

没意义,多搞几个号

好的,谢谢解答