-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
147 lines (134 loc) · 3.97 KB
/
index.js
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
145
146
147
const RPCClient = require('@alicloud/pop-core').RPCClient;
const got = require('got');
const assert = require('assert');
const { AccessKeyId, AccessKeySecret, Domain, SubDomain, TTL = 5 * 60 * 1000 } = process.env;
assert(AccessKeyId, `AccessKeyId cannot be empty.`);
assert(AccessKeySecret, `AccessKeySecret cannot be empty.`);
assert(Domain, `Domain cannot be empty.`);
assert(SubDomain, `SubDomain cannot be empty.`);
const client = new RPCClient({
accessKeyId: AccessKeyId,
accessKeySecret: AccessKeySecret,
endpoint: 'https://alidns.aliyuncs.com',
apiVersion: '2015-01-09'
});
function log(...args) {
console.log(`[${new Date().toLocaleString()}]`, ...args);
}
async function getIP() {
const ret = await got('https://ddns.oray.com/checkip');
if (ret.statusCode === 200 && ret.body) {
const match = ret.body.match(/Current IP Address: (.+?)$/);
if (match && match[1]) {
return match[1].trim();
}
}
throw new Error('获取IP异常,请检查网络连接');
}
async function query(domain, rr) {
const result = await client.request('DescribeDomainRecords', {
DomainName: domain,
RRKeyWord: rr,
TypeKeyWord: 'A',
PageSize: 100,
TTL: 600,
}, {
timeout: 3000, // default 3000 ms
formatAction: true, // default true, format the action to Action
formatParams: true, // default true, format the parameter name to first letter upper case
method: 'GET', // set the http method, default is GET
headers: {}, // set the http request headers
});
return result;
}
async function add(domain, rr, value) {
// options
const result = await client.request('AddDomainRecord', {
// Action: 'AddDomainRecord',
DomainName: domain,
RR: rr,
Type: 'A',
Value: value,
TTL: 600,
}, {
timeout: 3000, // default 3000 ms
formatAction: true, // default true, format the action to Action
formatParams: true, // default true, format the parameter name to first letter upper case
method: 'GET', // set the http method, default is GET
headers: {}, // set the http request headers
});
return result;
}
async function modify(recordId, rr, value) {
// options
const result = await client.request('UpdateDomainRecord', {
// Action: 'AddDomainRecord',
RecordId: recordId,
RR: rr,
Type: 'A',
Value: value,
TTL: 600,
}, {
timeout: 3000, // default 3000 ms
formatAction: true, // default true, format the action to Action
formatParams: true, // default true, format the parameter name to first letter upper case
method: 'GET', // set the http method, default is GET
headers: {}, // set the http request headers
});
return result;
}
async function main(domain, rr, interval) {
let ip;
try {
ip = await getIP();
log('当前公网IP', ip);
} catch (e) {
log(e.message);
return;
}
const list = await query(domain, rr);
let hasRecord = false;
let recordId;
if (list.DomainRecords && list.DomainRecords.Record && list.DomainRecords.Record.length) {
for (const record of list.DomainRecords.Record) {
if (record.DomainName === domain && record.RR === rr) {
if (record.Value === ip) {
log('公网IP未变化');
return;
}
hasRecord = true;
recordId = record.RecordId;
}
}
}
try {
let result;
if (!hasRecord) {
log('当前无记录');
result = await add(domain, rr, ip);
} else {
log('当前有记录', recordId);
result = await modify(recordId, rr, ip);
}
if (result.RequestId) {
log('设置成功', result.RequestId);
}
} catch (e) {
log('设置失败');
if (e.message.indexOf('DomainRecordDuplicateError')) {
log('[DomainRecordDuplicateError] 可能是公网IP并未发生变化');
} else {
log(e.message);
}
}
}
async function tick() {
try {
await main(Domain, SubDomain)
} catch (e) {
log('发生未知错误');
log(e);
}
setTimeout(tick, TTL);
}
tick();