lkcc commited on
Commit
dad756a
·
verified ·
1 Parent(s): e76a800

Update index.js

Browse files
Files changed (1) hide show
  1. index.js +87 -16
index.js CHANGED
@@ -5,6 +5,10 @@ import dotenv from 'dotenv';
5
  import cors from 'cors';
6
  import puppeteer from 'puppeteer';
7
  import { v4 as uuidv4 } from 'uuid';
 
 
 
 
8
 
9
  dotenv.config();
10
  // 配置常量
@@ -16,13 +20,13 @@ const CONFIG = {
16
  },
17
  API: {
18
  BASE_URL: "https://grok.com",
19
- API_KEY: process.env.API_KEY || "sk-123456",
20
  SSO_TOKEN: null,//登录时才有的认证cookie,这里暂时用不到,之后可能需要
21
  SIGNATURE_COOKIE: null,
22
  PICGO_KEY: process.env.PICGO_KEY || null //想要生图的话需要填入这个PICGO图床的key
23
  },
24
  SERVER: {
25
- PORT: process.env.PORT || 3000,
26
  BODY_LIMIT: '5mb'
27
  },
28
  RETRY: {
@@ -30,7 +34,7 @@ const CONFIG = {
30
  DELAY_BASE: 1000 // 基础延迟时间(毫秒)
31
  },
32
  ISSHOW_SEARCH_RESULTS: process.env.ISSHOW_SEARCH_RESULTS === 'true',//是否显示搜索结果,默认关闭
33
- CHROME_PATH: process.env.CHROME_PATH || "/usr/bin/chromium"//chrome路径
34
  };
35
 
36
  // 请求头配置
@@ -51,8 +55,70 @@ const DEFAULT_HEADERS = {
51
  'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36',
52
  'baggage': 'sentry-public_key=b311e0f2690c81f25e2c4cf6d4f7ce1c'
53
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
  class Utils {
 
 
56
  static async extractGrokHeaders() {
57
  console.log("开始提取头信息");
58
  try {
@@ -94,6 +160,9 @@ class Utils {
94
  }
95
  }
96
  static async get_signature() {
 
 
 
97
  if (CONFIG.API.SIGNATURE_COOKIE) {
98
  return CONFIG.API.SIGNATURE_COOKIE;
99
  }
@@ -104,7 +173,7 @@ class Utils {
104
  if (headers) {
105
  console.log("获取认证信息成功");
106
  CONFIG.API.SIGNATURE_COOKIE = { cookie: `x-anonuserid=${headers["x-anonuserid"]}; x-challenge=${headers["x-challenge"]}; x-signature=${headers["x-signature"]}` };
107
- return CONFIG.API.SIGNATURE_COOKIE;
108
  }
109
  retryCount++;
110
  if (retryCount >= CONFIG.RETRY.MAX_ATTEMPTS) {
@@ -411,7 +480,7 @@ app.use(cors({
411
  allowedHeaders: ['Content-Type', 'Authorization']
412
  }));
413
  // API路由
414
- app.get('/hf/v1/models', (req, res) => {
415
  res.json({
416
  object: "list",
417
  data: Object.keys(CONFIG.MODELS).map((model, index) => ({
@@ -423,8 +492,9 @@ app.get('/hf/v1/models', (req, res) => {
423
  });
424
  });
425
 
426
- app.post('/hf/v1/chat/completions', async (req, res) => {
427
  const authToken = req.headers.authorization?.replace('Bearer ', '');
 
428
  if (authToken !== CONFIG.API.API_KEY) {
429
  return res.status(401).json({ error: 'Unauthorized' });
430
  }
@@ -508,6 +578,7 @@ async function handleStreamResponse(response, model, res) {
508
  const trimmedLine = line.trim();
509
  if (trimmedLine.startsWith('data: ')) {
510
  const data = trimmedLine.substring(6);
 
511
  if(data === "[DONE]"){
512
  console.log("流结束");
513
  res.write('data: [DONE]\n\n');
@@ -517,10 +588,16 @@ async function handleStreamResponse(response, model, res) {
517
  if(!data.trim())continue;
518
  const linejosn = JSON.parse(data);
519
  if (linejosn?.error?.name === "RateLimitError") {
520
- var responseData = MessageProcessor.createChatResponse(`${linejosn.error.name},请重新对话`, model, true);
521
- fs.unlinkSync(path.resolve(process.cwd(), 'signature.json'));
 
 
 
 
 
522
  CONFIG.API.SIGNATURE_COOKIE = null;
523
- console.log("认证信息已删除");
 
524
  res.write(`data: ${JSON.stringify(responseData)}\n\n`);
525
  res.write('data: [DONE]\n\n');
526
  return res.end();
@@ -563,12 +640,6 @@ async function handleStreamResponse(response, model, res) {
563
  }
564
  }
565
  });
566
- stream.on('error', (error) => {
567
- console.error('流处理错误:', error);
568
- res.write('data: [DONE]\n\n');
569
- res.end();
570
- });
571
-
572
  } catch (error) {
573
  console.error('处理响应错误:', error);
574
  res.write('data: [DONE]\n\n');
@@ -706,4 +777,4 @@ app.use((req, res) => {
706
  // 启动服务器
707
  app.listen(CONFIG.SERVER.PORT, () => {
708
  console.log(`服务器已启动,监听端口: ${CONFIG.SERVER.PORT}`);
709
- });
 
5
  import cors from 'cors';
6
  import puppeteer from 'puppeteer';
7
  import { v4 as uuidv4 } from 'uuid';
8
+ import fs from 'fs';
9
+ //path
10
+
11
+ import path from 'path';
12
 
13
  dotenv.config();
14
  // 配置常量
 
20
  },
21
  API: {
22
  BASE_URL: "https://grok.com",
23
+ API_KEY: process.env.API_KEY_GUIJI || "linux.do",
24
  SSO_TOKEN: null,//登录时才有的认证cookie,这里暂时用不到,之后可能需要
25
  SIGNATURE_COOKIE: null,
26
  PICGO_KEY: process.env.PICGO_KEY || null //想要生图的话需要填入这个PICGO图床的key
27
  },
28
  SERVER: {
29
+ PORT: 9300,
30
  BODY_LIMIT: '5mb'
31
  },
32
  RETRY: {
 
34
  DELAY_BASE: 1000 // 基础延迟时间(毫秒)
35
  },
36
  ISSHOW_SEARCH_RESULTS: process.env.ISSHOW_SEARCH_RESULTS === 'true',//是否显示搜索结果,默认关闭
37
+ CHROME_PATH: process.env.CHROME_PATH || '/usr/bin/google-chrome-stable'
38
  };
39
 
40
  // 请求头配置
 
55
  'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36',
56
  'baggage': 'sentry-public_key=b311e0f2690c81f25e2c4cf6d4f7ce1c'
57
  };
58
+ // Add this class for managing authentication state
59
+ class AuthManager {
60
+ constructor() {
61
+ this.authPromise = null;
62
+ this.lastAuthTime = null;
63
+ this.AUTH_LIFETIME = 30 * 60 * 1000; // 30 minutes
64
+ this.isRefreshing = false;
65
+ this.waitingQueue = [];
66
+ }
67
+
68
+ async getAuth() {
69
+ // Check if we need to refresh
70
+ if (this.shouldRefreshAuth()) {
71
+ return this.refreshAuth();
72
+ }
73
+ return CONFIG.API.SIGNATURE_COOKIE;
74
+ }
75
+
76
+ shouldRefreshAuth() {
77
+ return !CONFIG.API.SIGNATURE_COOKIE ||
78
+ !this.lastAuthTime ||
79
+ (Date.now() - this.lastAuthTime > this.AUTH_LIFETIME);
80
+ }
81
+
82
+ async refreshAuth() {
83
+ // If already refreshing, wait for it
84
+ if (this.isRefreshing) {
85
+ return new Promise((resolve) => {
86
+ this.waitingQueue.push(resolve);
87
+ });
88
+ }
89
+
90
+ try {
91
+ this.isRefreshing = true;
92
+ const headers = await Utils.extractGrokHeaders();
93
+
94
+ if (!headers) {
95
+ throw new Error('Failed to extract headers');
96
+ }
97
+
98
+ CONFIG.API.SIGNATURE_COOKIE = {
99
+ cookie: `x-anonuserid=${headers["x-anonuserid"]}; x-challenge=${headers["x-challenge"]}; x-signature=${headers["x-signature"]}`
100
+ };
101
+ this.lastAuthTime = Date.now();
102
+
103
+ // Resolve all waiting requests
104
+ this.waitingQueue.forEach(resolve => resolve(CONFIG.API.SIGNATURE_COOKIE));
105
+ this.waitingQueue = [];
106
+
107
+ return CONFIG.API.SIGNATURE_COOKIE;
108
+ } catch (error) {
109
+ console.error('Auth refresh failed:', error);
110
+ this.waitingQueue.forEach(resolve => resolve(null));
111
+ this.waitingQueue = [];
112
+ throw error;
113
+ } finally {
114
+ this.isRefreshing = false;
115
+ }
116
+ }
117
+ }
118
 
119
  class Utils {
120
+ static authManager = new AuthManager();
121
+
122
  static async extractGrokHeaders() {
123
  console.log("开始提取头信息");
124
  try {
 
160
  }
161
  }
162
  static async get_signature() {
163
+ return Utils.authManager.getAuth();
164
+ }
165
+ static async get_signature_bak() {
166
  if (CONFIG.API.SIGNATURE_COOKIE) {
167
  return CONFIG.API.SIGNATURE_COOKIE;
168
  }
 
173
  if (headers) {
174
  console.log("获取认证信息成功");
175
  CONFIG.API.SIGNATURE_COOKIE = { cookie: `x-anonuserid=${headers["x-anonuserid"]}; x-challenge=${headers["x-challenge"]}; x-signature=${headers["x-signature"]}` };
176
+ return;
177
  }
178
  retryCount++;
179
  if (retryCount >= CONFIG.RETRY.MAX_ATTEMPTS) {
 
480
  allowedHeaders: ['Content-Type', 'Authorization']
481
  }));
482
  // API路由
483
+ app.get('/v1/models', (req, res) => {
484
  res.json({
485
  object: "list",
486
  data: Object.keys(CONFIG.MODELS).map((model, index) => ({
 
492
  });
493
  });
494
 
495
+ app.post('/v1/chat/completions', async (req, res) => {
496
  const authToken = req.headers.authorization?.replace('Bearer ', '');
497
+ console.log(authToken);
498
  if (authToken !== CONFIG.API.API_KEY) {
499
  return res.status(401).json({ error: 'Unauthorized' });
500
  }
 
578
  const trimmedLine = line.trim();
579
  if (trimmedLine.startsWith('data: ')) {
580
  const data = trimmedLine.substring(6);
581
+
582
  if(data === "[DONE]"){
583
  console.log("流结束");
584
  res.write('data: [DONE]\n\n');
 
588
  if(!data.trim())continue;
589
  const linejosn = JSON.parse(data);
590
  if (linejosn?.error?.name === "RateLimitError") {
591
+ var responseData = MessageProcessor.createChatResponse(
592
+ `${linejosn.error.name},请重新对话`,
593
+ model,
594
+ true
595
+ );
596
+
597
+ // Remove file deletion - it's not needed
598
  CONFIG.API.SIGNATURE_COOKIE = null;
599
+ console.log("认证信息已重置");
600
+
601
  res.write(`data: ${JSON.stringify(responseData)}\n\n`);
602
  res.write('data: [DONE]\n\n');
603
  return res.end();
 
640
  }
641
  }
642
  });
 
 
 
 
 
 
643
  } catch (error) {
644
  console.error('处理响应错误:', error);
645
  res.write('data: [DONE]\n\n');
 
777
  // 启动服务器
778
  app.listen(CONFIG.SERVER.PORT, () => {
779
  console.log(`服务器已启动,监听端口: ${CONFIG.SERVER.PORT}`);
780
+ });