Repository navigation
Expand file tree
/
Copy pathworker.js
More file actions
144 lines (119 loc) · 4.1 KB
/
Copy pathworker.js
File metadata and controls
144 lines (119 loc) · 4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
async function sendTGMessage(message, env) {
const botToken = env.TG_BOT_TOKEN;
const chatId = env.TG_CHAT_ID;
if (!botToken || !chatId) {
console.warn("⚠️ TG_BOT_TOKEN 或 TG_CHAT_ID 未设置,跳过 Telegram 消息发送");
return null;
}
const url = `https://api.telegram.org/bot${botToken}/sendMessage`;
const data = {
chat_id: chatId,
text: message,
parse_mode: 'Markdown',
};
try {
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`HTTP ${response.status}: ${errorText}`);
}
console.info("✅ Telegram 消息发送成功");
return await response.json();
} catch (e) {
console.error(`❌ 发送 Telegram 消息失败: ${e.message}`);
return null;
}
}
async function loginKoyeb(email, token) {
if (!token) {
return [false, "Token 为空"];
}
const url = 'https://app.koyeb.com/v1/apps';
const headers = {
'Authorization': `Bearer ${token.trim()}`,
'Accept': 'application/json',
'User-Agent': 'KoyebTokenLogin/1.0',
};
try {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 30000);
const response = await fetch(url, {
method: 'GET',
headers,
signal: controller.signal,
});
clearTimeout(timeout);
if (!response.ok) {
return [false, `HTTP ${response.status}`];
}
return [true, "登录成功(Token)"];
} catch (e) {
return [false, e.message];
}
}
async function validateEnvVariables(env) {
const koyebAccountsEnv = env.KOYEB_ACCOUNTS;
if (!koyebAccountsEnv) {
throw new Error("❌ KOYEB_ACCOUNTS 环境变量未设置或格式错误");
}
try {
return JSON.parse(koyebAccountsEnv);
} catch {
throw new Error("❌ KOYEB_ACCOUNTS JSON 格式无效");
}
}
async function scheduledEventHandler(event, env) {
try {
const KOYEB_ACCOUNTS = await validateEnvVariables(env);
if (!KOYEB_ACCOUNTS || KOYEB_ACCOUNTS.length === 0) {
throw new Error("❌ 没有找到有效的 Koyeb 账户信息");
}
const results = [];
const currentTime = new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' });
const totalAccounts = KOYEB_ACCOUNTS.length;
let successCount = 0;
for (let index = 0; index < totalAccounts; index++) {
const account = KOYEB_ACCOUNTS[index];
const email = account.email?.trim() || "未命名账号";
const token = account.token;
if (!token) {
console.warn(`⚠️ 账户未配置 Token,跳过: ${email}`);
results.push(`⚠️ 账户: ${email}\nToken 未配置,跳过\n`);
continue;
}
try {
console.info(`🔄 处理账户 ${index + 1}/${totalAccounts}: ${email}`);
if (index > 0) {
await new Promise(resolve => setTimeout(resolve, 5000)); // 5秒间隔
}
const [success, message] = await loginKoyeb(email, token);
if (success) {
successCount++;
results.push(`✅ 账户: ${email} 登录成功(Token)\n`);
} else {
results.push(`❌ 账户: ${email} 登录失败 - ${message}\n`);
}
} catch (e) {
results.push(`❌ 账户: ${email} 登录失败 - 执行异常: ${e.message}\n`);
}
}
if (results.length === 0) {
throw new Error("❌ 没有任何账户处理结果");
}
const summary = `📊 总计: ${totalAccounts} 个账户\n✅ 成功: ${successCount} | ❌ 失败: ${totalAccounts - successCount}\n\n`;
const tgMessage = `🤖 *Koyeb 登录状态报告*\n⏰ *检查时间:* ${currentTime}\n\n${summary}${results.join('')}`;
console.log(tgMessage);
await sendTGMessage(tgMessage, env);
} catch (e) {
const errorMessage = `❌ 程序执行出错: ${e.message}`;
console.error(errorMessage);
await sendTGMessage(errorMessage, env);
}
}
addEventListener('scheduled', event => {
event.waitUntil(scheduledEventHandler(event, event.environment));
});