Files
ddns-agent/agent/task.ts
2025-11-16 13:32:35 +08:00

93 lines
2.5 KiB
TypeScript
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.

import { app } from './app.ts';
import { createStorage } from "unstorage";
import fsDriver from "unstorage/drivers/fs";
const storage = createStorage({
driver: fsDriver({
base: process.cwd() + '/storage/ddns-agent'
}),
});
type CloudflareConfig = {
// Cloudflare 访问地址
website: string;
domain: string;
zone_id: string;
// 更新IPv4记录的ID
record_id4: string;
// 更新IPv6记录的ID
record_id6: string;
api_token: string;
ipv6: string;
ipv4: string;
flag: number; // 0: 不更新, 1: 仅IPv4, 2: 仅IPv6, 3: IPv4和IPv6
time: string; // 上次更新时间戳
}
app.route({
path: 'ip',
key: 'task',
description: `执行IP更新任务
1. 读取配置文件cloudflare.json
2. 根据flag决定更新IPv4和/或IPv6地址
3. 获取当前公网IP地址
4. 如果IP地址有变化则调用 router: cf/update 更新DNS记录
5. 保存最新的IP地址和更新时间戳到配置文件
`,
}).define(async (ctx) => {
const config = await storage.getItem<CloudflareConfig>('cloudflare.json');
if (!config) {
ctx.throw?.('未找到配置');
}
const now = Date.now();
const date = new Date(now);
const updateIp = async (isV4 = true) => {
const res = await app.call({ path: 'ip', key: isV4 ? 'v4' : 'v6' });
if (res.code !== 200) {
ctx.throw(res.message);
}
const newIp = res.body.ip as string;
const oldIp = isV4 ? config.ipv4 : config.ipv6;
if (newIp !== oldIp) {
// IP地址有变化更新DNS记录
await app.call({ path: 'cf', key: 'update' }, {
zone_id: config.zone_id,
record_id: isV4 ? config.record_id4 : config.record_id6,
domain: config.domain,
new_ip: newIp,
api_token: config.api_token,
type: isV4 ? 'A' : 'AAAA',
});
// 更新配置文件中的IP地址
if (isV4) {
config.ipv4 = newIp;
} else {
config.ipv6 = newIp;
}
config.time = date.toLocaleString();
await storage.setItem('cloudflare.json', config);
console.log(date.toLocaleString() + ` 更新 ${isV4 ? 'IPv4' : 'IPv6'} 地址为: ${newIp}`);
} else {
console.log(date.toLocaleString() + ` ${isV4 ? 'IPv4' : 'IPv6'} 地址未改变: ${newIp}`);
}
}
if (config.flag === 1) {
await updateIp(true);
}
if (config.flag === 2) {
await updateIp(false);
}
if (config.flag === 3) {
await updateIp(true);
await updateIp(false);
}
ctx.body = { message: '任务完成' };
}).addTo(app);
export const main = () => {
app.call({
path: 'ip',
key: 'task',
})
}