Files
CF-Workers-SUB/_worker.js
2024-03-11 01:58:11 +08:00

159 lines
6.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 部署完成后在网址后面加上这个,获取自建节点和机场聚合节点,/?token=auto或/auto或
let mytoken = 'auto'; //可以随便取或者uuid生成https://1024tools.com/uuid
let BotToken =''; //可以为空,或者@BotFather中输入/start/newbot并关注机器人
let ChatID =''; //可以为空,或者@userinfobot中获取/start
let TG = 0; //1 为推送所有的访问信息0 为不推送订阅转换后端的访问信息与异常访问
let SUBUpdateTime = 6; //自定义订阅更新时间,单位小时
//自建节点
const MainData = `
vless://b7a392e2-4ef0-4496-90bc-1c37bb234904@cf.090227.xyz:443?encryption=none&security=tls&sni=edgetunnel-2z2.pages.dev&fp=random&type=ws&host=edgetunnel-2z2.pages.dev&path=%2F%3Fed%3D2048#%E5%8A%A0%E5%85%A5%E6%88%91%E7%9A%84%E9%A2%91%E9%81%93t.me%2FCMLiussss%E8%A7%A3%E9%94%81%E6%9B%B4%E5%A4%9A%E4%BC%98%E9%80%89%E8%8A%82%E7%82%B9
vmess://ew0KICAidiI6ICIyIiwNCiAgInBzIjogIuWKoOWFpeaIkeeahOmikemBk3QubWUvQ01MaXVzc3Nz6Kej6ZSB5pu05aSa5LyY6YCJ6IqC54K5PuiLseWbvSDlgKvmlabph5Hono3ln44iLA0KICAiYWRkIjogImNmLjA5MDIyNy54eXoiLA0KICAicG9ydCI6ICI4NDQzIiwNCiAgImlkIjogIjAzZmNjNjE4LWI5M2QtNjc5Ni02YWVkLThhMzhjOTc1ZDU4MSIsDQogICJhaWQiOiAiMCIsDQogICJzY3kiOiAiYXV0byIsDQogICJuZXQiOiAid3MiLA0KICAidHlwZSI6ICJub25lIiwNCiAgImhvc3QiOiAicHBmdjJ0bDl2ZW9qZC1tYWlsbGF6eS5wYWdlcy5kZXYiLA0KICAicGF0aCI6ICIvamFkZXIuZnVuOjQ0My9saW5rdndzIiwNCiAgInRscyI6ICJ0bHMiLA0KICAic25pIjogInBwZnYydGw5dmVvamQtbWFpbGxhenkucGFnZXMuZGV2IiwNCiAgImFscG4iOiAiIiwNCiAgImZwIjogIiINCn0=
`
//机场信息可多个也可为0
const urls = [
'https://sub.xf.free.hr/auto',
'https://hy2sub.pages.dev',
// 添加更多订阅,支持base64
];
let subconverter = "api.v1.mk"; //在线订阅转换后端目前使用肥羊的订阅转换功能。支持自建psub 可自行搭建https://github.com/bulianglin/psub
let subconfig = "https://raw.githubusercontent.com/cmliu/ACL4SSR/main/Clash/config/ACL4SSR_Online_Full.ini"; //订阅配置文件
export default {
async fetch (request,env) {
const userAgentHeader = request.headers.get('User-Agent');
const userAgent = userAgentHeader ? userAgentHeader.toLowerCase() : "null";
const url = new URL(request.url);
const token = url.searchParams.get('token');
mytoken = env.TOKEN || mytoken;
BotToken = env.TGTOKEN || BotToken;
ChatID = env.TGID || ChatID;
TG = env.TG || TG;
subconverter = env.SUBAPI || subconverter;
subconfig = env.SUBCONFIG || subconfig;
if ( !(token == mytoken || url.pathname == ("/"+ mytoken) || url.pathname.includes("/"+ mytoken + "?")) ) {
if ( TG == 1 && url.pathname !== "/" && url.pathname !== "/favicon.ico" ) await sendMessage("#异常访问", request.headers.get('CF-Connecting-IP'), `UA: ${userAgent}</tg-spoiler>\n域名: ${url.hostname}\n<tg-spoiler>入口: ${url.pathname + url.search}</tg-spoiler>`);
return new Response('Hello World!', { status: 403 });
} else if ( TG == 1 || !userAgent.includes('subconverter') ){
await sendMessage("#获取订阅", request.headers.get('CF-Connecting-IP'), `UA: ${userAgent}</tg-spoiler>\n域名: ${url.hostname}\n<tg-spoiler>入口: ${url.pathname + url.search}</tg-spoiler>`);
}
if (userAgent.includes('clash')) {
const subconverterUrl = `https://${subconverter}/sub?target=clash&url=${encodeURIComponent(request.url)}&insert=false&config=${encodeURIComponent(subconfig)}&emoji=true&list=false&tfo=false&scv=false&fdn=false&sort=false&new_name=true`;
try {
const subconverterResponse = await fetch(subconverterUrl);
if (!subconverterResponse.ok) {
throw new Error(`Error fetching subconverterUrl: ${subconverterResponse.status} ${subconverterResponse.statusText}`);
}
const subconverterContent = await subconverterResponse.text();
return new Response(subconverterContent ,{
headers: {
"content-type": "text/plain; charset=utf-8",
"Profile-Update-Interval": `${SUBUpdateTime}`,
}
});
} catch (error) {
return new Response(`Error: ${error.message}`, {
status: 500,
headers: { 'content-type': 'text/plain; charset=utf-8' },
});
}
} else if (userAgent.includes('sing-box') || userAgent.includes('singbox')) {
const subconverterUrl = `https://${subconverter}/sub?target=singbox&url=${encodeURIComponent(request.url)}&insert=false&config=${encodeURIComponent(subconfig)}&emoji=true&list=false&tfo=false&scv=false&fdn=false&sort=false&new_name=true`;
try {
const subconverterResponse = await fetch(subconverterUrl);
if (!subconverterResponse.ok) {
throw new Error(`Error fetching subconverterUrl: ${subconverterResponse.status} ${subconverterResponse.statusText}`);
}
const subconverterContent = await subconverterResponse.text();
return new Response(subconverterContent ,{
headers: {
"content-type": "text/plain; charset=utf-8",
"Profile-Update-Interval": `${SUBUpdateTime}`,
}
});
} catch (error) {
return new Response(`Error: ${error.message}`, {
status: 500,
headers: { 'content-type': 'text/plain; charset=utf-8' },
});
}
} else {
let req_data = "";
req_data += MainData;
try {
const responses = await Promise.all(urls.map(url => fetch(url,{
method: 'get',
headers: {
'Accept': 'text/html,application/xhtml+xml,application/xml;',
'User-Agent': 'CF-Workers-SUB/cmliu'
}
})));
for (const response of responses) {
if (response.ok) {
const content = await response.text();
req_data += atob(content) + '\n';
}
}
} catch (error) {
}
//修复中文错误
const utf8Encoder = new TextEncoder();
const encodedData = utf8Encoder.encode(req_data);
const text = String.fromCharCode.apply(null, encodedData);
//去重
const uniqueLines = new Set(text.split('\n'));
const result = [...uniqueLines].join('\n');
//console.log(result);
const base64Data = btoa(result);
return new Response(base64Data ,{
headers: {
"content-type": "text/plain; charset=utf-8",
"Profile-Update-Interval": `${SUBUpdateTime}`,
}
});
}
}
};
async function sendMessage(type, ip, add_data = "") {
if ( BotToken !== '' && ChatID !== ''){
let msg = "";
const response = await fetch(`http://ip-api.com/json/${ip}?lang=zh-CN`);
if (response.status == 200) {
const ipInfo = await response.json();
msg = `${type}\nIP: ${ip}\n国家: ${ipInfo.country}\n<tg-spoiler>城市: ${ipInfo.city}\n组织: ${ipInfo.org}\nASN: ${ipInfo.as}\n${add_data}`;
} else {
msg = `${type}\nIP: ${ip}\n<tg-spoiler>${add_data}`;
}
let url = "https://api.telegram.org/bot"+ BotToken +"/sendMessage?chat_id=" + ChatID + "&parse_mode=HTML&text=" + encodeURIComponent(msg);
return fetch(url, {
method: 'get',
headers: {
'Accept': 'text/html,application/xhtml+xml,application/xml;',
'Accept-Encoding': 'gzip, deflate, br',
'User-Agent': 'Mozilla/5.0 Chrome/90.0.4430.72'
}
});
}
}