Skip to content

Instantly share code, notes, and snippets.

@14790897
Last active February 26, 2024 10:56
Show Gist options
  • Save 14790897/e7140b27b977fc27b6e4eeb8502c0d38 to your computer and use it in GitHub Desktop.
Save 14790897/e7140b27b977fc27b6e4eeb8502c0d38 to your computer and use it in GitHub Desktop.
cfworkers c号的token轮询
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
addEventListener('scheduled', event => {
event.waitUntil(doSomeTaskOnASchedule());
});
async function doSomeTaskOnASchedule() {
await handleChecklist();
}
const KV = cocopilot;
async function handleRequest(request) {
const url = new URL(request.url);
let response;
const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET',
'Access-Control-Allow-Headers': '*',
};
if (request.method === 'OPTIONS') return new Response(null, { headers: corsHeaders });
if (url.pathname === '/upload' && request.method === 'POST') {
response = await handleUpload(request);
} else if (url.pathname.startsWith('/v1')) {
response = await handleProxy(request, url);
} else if (url.pathname === '/list' && request.method === 'GET') {
response = await handleList();
} else {
response = new Response('Invalid request method or path', {status: 405});
}
return response;
}
async function handleUpload(request) {
const data = await request.json();
for (let key in data) {
if (!key.startsWith('gh') || !data[key].startsWith('gh')) {
return new Response(JSON.stringify({message: 'Key and value must start with "copilot secret"', data: data}), {status: 400});
}
const headers = {
'Host': 'api.github.com',
'authorization': `token ${key}`,
'Editor-Version': 'vscode/1.85.2',
'Editor-Plugin-Version': 'copilot-chat/0.11.1',
'User-Agent': 'GitHubCopilotChat/0.11.1',
'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate, br'
}
const upload_response = await fetch('https://api.github.com/copilot_internal/v2/token', { headers });
const upload_responseBody = await upload_response.json();
if (upload_response.status === 200 && upload_responseBody.token) {
await KV.put(key, data[key]);
}
}
return new Response(JSON.stringify({message: 'ghu upload Success', data: data}), {status: 200});
}
async function handleProxy(request, url) {
const keys = await KV.list();
const randomKey = keys.keys[Math.floor(Math.random() * keys.keys.length)].name;
const ghu = await KV.get(randomKey);
const requestBody = await request.json();
const response = await fetch(`https://proxy.cocopilot.org${url.pathname}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${ghu}`
},
body: JSON.stringify(requestBody)
});
// 设置跨域头部
const newHeaders = new Headers(response.headers);
newHeaders.set('Access-Control-Allow-Origin', '*');
newHeaders.set('Access-Control-Allow-Methods', '*');
// 创建一个新的 Response 对象,使用新的头部
const newResponse = new Response(response.body, {
...response,
headers: newHeaders
});
return newResponse;
}
async function handleList() {
const keys = await KV.list();
return new Response(JSON.stringify({total: keys.keys.length}), {status: 200});
}
async function handleChecklist() {
const keys = await KV.list();
if (keys.keys.length === 0) {
return new Response(JSON.stringify({message: 'No keys in KV'}), {status: 200});
}
for (let key of keys.keys) {
const ghu = await KV.get(key.name);
const headers = {
'Host': 'api.github.com',
'authorization': `token ${ghu}`,
'Editor-Version': 'vscode/1.85.2',
'Editor-Plugin-Version': 'copilot-chat/0.11.1',
'User-Agent': 'GitHubCopilotChat/0.11.1',
'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate, br'
}
const response = await fetch('https://api.github.com/copilot_internal/v2/token', { headers });
const responseData = await response.json();
if (response.status !== 200 || !responseData.token) {
await KV.delete(key.name);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment