Spaces:
Sleeping
Sleeping
Upload 15 files
Browse files- Dockerfile +0 -9
- proxy_server.log +7 -0
- src/lightweight-client-express.js +99 -6
- src/lightweight-client.js +0 -47
Dockerfile
CHANGED
@@ -16,15 +16,6 @@ RUN npm install --production
|
|
16 |
# Copy the rest of the application source code to the working directory
|
17 |
COPY . .
|
18 |
|
19 |
-
# Grant execute permission to the proxy server binary
|
20 |
-
RUN chmod +x /app/src/proxy/chrome_proxy_server_linux_amd64
|
21 |
-
|
22 |
-
# Change ownership of the app directory to the node user
|
23 |
-
RUN chown -R node:node /app
|
24 |
-
|
25 |
-
# Switch to a non-root user
|
26 |
-
USER node
|
27 |
-
|
28 |
# Make port 7860 available to the world outside this container
|
29 |
EXPOSE 7860
|
30 |
|
|
|
16 |
# Copy the rest of the application source code to the working directory
|
17 |
COPY . .
|
18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
# Make port 7860 available to the world outside this container
|
20 |
EXPOSE 7860
|
21 |
|
proxy_server.log
CHANGED
@@ -132,3 +132,10 @@
|
|
132 |
2025/06/08 00:54:49.325299 chrome_tls_proxy.go:711: 已强制使用IPv4连接,并使用8.8.8.8作为DNS服务器
|
133 |
2025/06/08 00:54:49.325299 chrome_tls_proxy.go:712: 使用Chrome浏览器的TLS指纹进行连接
|
134 |
2025/06/08 00:54:49.325813 chrome_tls_proxy.go:716: 服务器启动失败: listen tcp :10655: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
2025/06/08 00:54:49.325299 chrome_tls_proxy.go:711: 已强制使用IPv4连接,并使用8.8.8.8作为DNS服务器
|
133 |
2025/06/08 00:54:49.325299 chrome_tls_proxy.go:712: 使用Chrome浏览器的TLS指纹进行连接
|
134 |
2025/06/08 00:54:49.325813 chrome_tls_proxy.go:716: 服务器启动失败: listen tcp :10655: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.
|
135 |
+
2025/06/08 19:06:11.117107 chrome_tls_proxy.go:706: Chrome TLS指纹代理服务器运行在 http://localhost:10655/proxy
|
136 |
+
2025/06/08 19:06:11.123148 chrome_tls_proxy.go:707: 使用方法:向/proxy发送POST请求,请求体包含目标URL、方法、请求头和请求体
|
137 |
+
2025/06/08 19:06:11.123148 chrome_tls_proxy.go:708: 支持流式响应,需要在请求体中添加 'stream': true
|
138 |
+
2025/06/08 19:06:11.123148 chrome_tls_proxy.go:709: 已禁用速率限制:允许无限制请求
|
139 |
+
2025/06/08 19:06:11.123148 chrome_tls_proxy.go:710: 已禁用并发限制:允许同一IP发起多个并发请求
|
140 |
+
2025/06/08 19:06:11.123148 chrome_tls_proxy.go:711: 已强制使用IPv4连接,并使用8.8.8.8作为DNS服务器
|
141 |
+
2025/06/08 19:06:11.123148 chrome_tls_proxy.go:712: 使用Chrome浏览器的TLS指纹进行连接
|
src/lightweight-client-express.js
CHANGED
@@ -4,6 +4,7 @@ import { randomUUID } from 'crypto';
|
|
4 |
import { fileURLToPath } from 'url';
|
5 |
import { dirname, join } from 'path';
|
6 |
import chalk from 'chalk';
|
|
|
7 |
import {
|
8 |
ChatMessage, ChatCompletionRequest, Choice, ChoiceDelta, ChatCompletionChunk
|
9 |
} from './models.js';
|
@@ -22,6 +23,10 @@ const __dirname = dirname(__filename);
|
|
22 |
// 加载环境变量
|
23 |
dotenv.config({ path: join(dirname(__dirname), '.env') });
|
24 |
|
|
|
|
|
|
|
|
|
25 |
// 日志配置
|
26 |
const logger = {
|
27 |
info: (message) => console.log(chalk.blue(`[info] ${message}`)),
|
@@ -62,6 +67,71 @@ app.use((req, res, next) => {
|
|
62 |
next();
|
63 |
});
|
64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
// 认证中间件
|
66 |
function authenticate(req, res, next) {
|
67 |
const authHeader = req.headers.authorization;
|
@@ -119,6 +189,14 @@ app.post('/v1/chat/completions', authenticate, async (req, res) => {
|
|
119 |
});
|
120 |
}
|
121 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
// 验证请求数据
|
123 |
const requestData = req.body;
|
124 |
|
@@ -230,8 +308,13 @@ app.get('/health', (req, res) => {
|
|
230 |
const PORT = process.env.PORT || 7860;
|
231 |
|
232 |
// 初始化并启动服务器
|
233 |
-
initialize()
|
234 |
-
|
|
|
|
|
|
|
|
|
|
|
235 |
logger.info(`服务已启动 - 端口: ${PORT}`);
|
236 |
logger.info(`访问地址: http://localhost:${PORT}`);
|
237 |
|
@@ -242,7 +325,17 @@ initialize().then(() => {
|
|
242 |
logger.warning(`警告: Notion ID未成功获取,API调用将无法正常工作`);
|
243 |
logger.warning(`请检查NOTION_COOKIE配置或手动设置NOTION_SPACE_ID和NOTION_ACTIVE_USER_HEADER`);
|
244 |
}
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
import { fileURLToPath } from 'url';
|
5 |
import { dirname, join } from 'path';
|
6 |
import chalk from 'chalk';
|
7 |
+
import fetch from 'node-fetch';
|
8 |
import {
|
9 |
ChatMessage, ChatCompletionRequest, Choice, ChoiceDelta, ChatCompletionChunk
|
10 |
} from './models.js';
|
|
|
23 |
// 加载环境变量
|
24 |
dotenv.config({ path: join(dirname(__dirname), '.env') });
|
25 |
|
26 |
+
// 用户邮箱信息
|
27 |
+
let userEmails = [];
|
28 |
+
let currentEmailIndex = 0;
|
29 |
+
|
30 |
// 日志配置
|
31 |
const logger = {
|
32 |
info: (message) => console.log(chalk.blue(`[info] ${message}`)),
|
|
|
67 |
next();
|
68 |
});
|
69 |
|
70 |
+
// 获取用户邮箱信息
|
71 |
+
async function fetchUserEmails() {
|
72 |
+
logger.info('开始获取用户邮箱信息...');
|
73 |
+
|
74 |
+
const cookies = process.env.NOTION_COOKIE;
|
75 |
+
if (!cookies) {
|
76 |
+
logger.error('未设置 NOTION_COOKIE 环境变量,无法获取用户邮箱信息');
|
77 |
+
return [];
|
78 |
+
}
|
79 |
+
|
80 |
+
const cookiePairs = cookies.split('|');
|
81 |
+
const emails = [];
|
82 |
+
|
83 |
+
for (let i = 0; i < cookiePairs.length; i++) {
|
84 |
+
try {
|
85 |
+
const cookie = cookiePairs[i].trim();
|
86 |
+
const response = await fetch("https://www.notion.so/api/v3/getUserAnalyticsSettings", {
|
87 |
+
method: 'POST',
|
88 |
+
headers: {
|
89 |
+
'Content-Type': 'application/json',
|
90 |
+
'accept': '*/*',
|
91 |
+
'accept-language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7',
|
92 |
+
'notion-audit-log-platform': 'web',
|
93 |
+
'notion-client-version': '23.13.0.3799',
|
94 |
+
'cookie': cookie
|
95 |
+
},
|
96 |
+
body: '{}'
|
97 |
+
});
|
98 |
+
|
99 |
+
if (response.ok) {
|
100 |
+
const data = await response.json();
|
101 |
+
if (data && data.user_email) {
|
102 |
+
emails.push({
|
103 |
+
email: data.user_email,
|
104 |
+
name: data.user_name || '未知用户',
|
105 |
+
cookie: cookie
|
106 |
+
});
|
107 |
+
logger.success(`获取到账号信息: ${data.user_email} (${data.user_name || '未知用户'})`);
|
108 |
+
} else {
|
109 |
+
logger.warning(`无法从 Notion API 响应中获取用户邮箱信息 (cookie ${i+1})`);
|
110 |
+
}
|
111 |
+
} else {
|
112 |
+
logger.warning(`Notion API 请求失败,状态码: ${response.status} (cookie ${i+1})`);
|
113 |
+
}
|
114 |
+
} catch (error) {
|
115 |
+
logger.error(`获取用户邮箱时出错 (cookie ${i+1}): ${error.message}`);
|
116 |
+
}
|
117 |
+
}
|
118 |
+
|
119 |
+
logger.info(`共获取到 ${emails.length} 个用户账号信息`);
|
120 |
+
return emails;
|
121 |
+
}
|
122 |
+
|
123 |
+
// 获取当前使用的邮箱信息
|
124 |
+
function getCurrentEmail() {
|
125 |
+
if (userEmails.length === 0) {
|
126 |
+
return null;
|
127 |
+
}
|
128 |
+
|
129 |
+
const email = userEmails[currentEmailIndex];
|
130 |
+
// 轮询到下一个邮箱
|
131 |
+
currentEmailIndex = (currentEmailIndex + 1) % userEmails.length;
|
132 |
+
return email;
|
133 |
+
}
|
134 |
+
|
135 |
// 认证中间件
|
136 |
function authenticate(req, res, next) {
|
137 |
const authHeader = req.headers.authorization;
|
|
|
189 |
});
|
190 |
}
|
191 |
|
192 |
+
// 获取当前使用的邮箱信息并打印
|
193 |
+
const emailInfo = getCurrentEmail();
|
194 |
+
if (emailInfo) {
|
195 |
+
logger.info(`本次调用使用账号: ${emailInfo.email} (${emailInfo.name})`);
|
196 |
+
} else {
|
197 |
+
logger.warning('未能获取到用户邮箱信息,无法显示当前使用的账号');
|
198 |
+
}
|
199 |
+
|
200 |
// 验证请求数据
|
201 |
const requestData = req.body;
|
202 |
|
|
|
308 |
const PORT = process.env.PORT || 7860;
|
309 |
|
310 |
// 初始化并启动服务器
|
311 |
+
initialize()
|
312 |
+
.then(() => fetchUserEmails())
|
313 |
+
.then((emails) => {
|
314 |
+
userEmails = emails;
|
315 |
+
return app.listen(PORT);
|
316 |
+
})
|
317 |
+
.then(() => {
|
318 |
logger.info(`服务已启动 - 端口: ${PORT}`);
|
319 |
logger.info(`访问地址: http://localhost:${PORT}`);
|
320 |
|
|
|
325 |
logger.warning(`警告: Notion ID未成功获取,API调用将无法正常工作`);
|
326 |
logger.warning(`请检查NOTION_COOKIE配置或手动设置NOTION_SPACE_ID和NOTION_ACTIVE_USER_HEADER`);
|
327 |
}
|
328 |
+
|
329 |
+
if (userEmails.length > 0) {
|
330 |
+
logger.success(`邮箱账号状态: ✅ (共 ${userEmails.length} 个账号)`);
|
331 |
+
userEmails.forEach((email, index) => {
|
332 |
+
logger.info(`账号 ${index + 1}: ${email.email} (${email.name})`);
|
333 |
+
});
|
334 |
+
} else {
|
335 |
+
logger.warning(`邮箱账号状态: ❌`);
|
336 |
+
logger.warning(`警告: 未能获取到任何用户邮箱信息`);
|
337 |
+
}
|
338 |
+
})
|
339 |
+
.catch((error) => {
|
340 |
+
logger.error(`初始化失败: ${error}`);
|
341 |
+
});
|
src/lightweight-client.js
CHANGED
@@ -312,50 +312,6 @@ async function fetchAndSetNotionIds() {
|
|
312 |
}
|
313 |
}
|
314 |
|
315 |
-
// 获取并记录用户邮箱
|
316 |
-
async function fetchAndLogUserEmail() {
|
317 |
-
if (!NOTION_COOKIE || !FETCHED_NOTION_USER_ID) {
|
318 |
-
logger.warning("无法获取用户邮箱:缺少Cookie或用户ID。");
|
319 |
-
return;
|
320 |
-
}
|
321 |
-
|
322 |
-
try {
|
323 |
-
const fetchOptions = {
|
324 |
-
method: 'POST',
|
325 |
-
headers: {
|
326 |
-
'Content-Type': 'application/json',
|
327 |
-
'accept': '*/*',
|
328 |
-
'notion-client-version': '23.13.0.3799',
|
329 |
-
'x-notion-active-user-header': FETCHED_NOTION_USER_ID,
|
330 |
-
'Cookie': NOTION_COOKIE,
|
331 |
-
},
|
332 |
-
body: JSON.stringify({}),
|
333 |
-
};
|
334 |
-
|
335 |
-
if (PROXY_URL) {
|
336 |
-
const { HttpsProxyAgent } = await import('https-proxy-agent');
|
337 |
-
fetchOptions.agent = new HttpsProxyAgent(PROXY_URL);
|
338 |
-
}
|
339 |
-
|
340 |
-
const response = await fetch("https://www.notion.so/api/v3/getUserAnalyticsSettings", fetchOptions);
|
341 |
-
|
342 |
-
if (response.ok) {
|
343 |
-
const data = await response.json();
|
344 |
-
if (data.user_email) {
|
345 |
-
logger.success(`当前登录的Notion用户: ${data.user_name} (${data.user_email})`);
|
346 |
-
} else {
|
347 |
-
logger.warning("无法在响应中找到用户邮箱。");
|
348 |
-
}
|
349 |
-
} else {
|
350 |
-
logger.error(`获取用户邮箱失败,状态码: ${response.status}`);
|
351 |
-
const errorBody = await response.text();
|
352 |
-
logger.error(`错误详情: ${errorBody}`);
|
353 |
-
}
|
354 |
-
} catch (error) {
|
355 |
-
logger.error(`获取用户邮箱时发生网络错误: ${error.message}`);
|
356 |
-
}
|
357 |
-
}
|
358 |
-
|
359 |
// 构建Notion请求
|
360 |
function buildNotionRequest(requestData) {
|
361 |
// 当前时间
|
@@ -974,9 +930,6 @@ async function initialize() {
|
|
974 |
logger.info(`正在初始化本地代理池...`);
|
975 |
await proxyPool.initialize();
|
976 |
}
|
977 |
-
|
978 |
-
// 获取并记录用户邮箱
|
979 |
-
await fetchAndLogUserEmail();
|
980 |
}
|
981 |
|
982 |
// 导出函数
|
|
|
312 |
}
|
313 |
}
|
314 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
315 |
// 构建Notion请求
|
316 |
function buildNotionRequest(requestData) {
|
317 |
// 当前时间
|
|
|
930 |
logger.info(`正在初始化本地代理池...`);
|
931 |
await proxyPool.initialize();
|
932 |
}
|
|
|
|
|
|
|
933 |
}
|
934 |
|
935 |
// 导出函数
|