Last active
March 28, 2024 06:22
-
-
Save lsongdev/6e27ff7d1ee5ed4acd04fe7d8a25180a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
async function handleRequest(request, env) { | |
const url = new URL(request.url); | |
const domain = url.searchParams.get('domain'); | |
const ip = url.searchParams.get('ip') || request.headers.get('CF-Connecting-IP'); | |
const type = url.searchParams.get('type') || (isIPv6(ip) ? 'AAAA' : 'A'); | |
const token = url.searchParams.get('token') || env.API_TOKEN; | |
if (!domain) { | |
return new Response('Missing domain query parameter', { status: 400 }); | |
} | |
try { | |
const updateResult = await updateDNSRecord(token, ip, domain, type); | |
return new Response(updateResult.message, { | |
headers: { 'Content-Type': 'text/plain' }, | |
}); | |
} catch (error) { | |
return new Response(error.message, { status: 500 }); | |
} | |
} | |
async function findZoneIdByDomain(token, domain) { | |
const endpoint = `https://api.cloudflare.com/client/v4/zones?name=${domain}&status=active`; | |
const response = await fetch(endpoint, { | |
headers: { | |
'Authorization': `Bearer ${token}`, | |
'Content-Type': 'application/json', | |
}, | |
}); | |
const data = await response.json(); | |
if (!data.success) { | |
throw new Error('Failed to fetch zone details'); | |
} | |
if (data.result.length > 0) { | |
return data.result[0].id; // Return the Zone ID of the matched domain | |
} else { | |
throw new Error('No matching zone found'); | |
} | |
} | |
async function updateDNSRecord(token, ip, domain, type) { | |
const zoneId = await findZoneIdByDomain(token, domain); | |
const dnsRecord = await findDNSRecord(token, zoneId, domain, type); | |
console.log("dnsRecord.content:" , dnsRecord.content, ip); | |
if (dnsRecord.content === ip) { | |
return { success: true, message: 'IP address is the same, update skipped' }; | |
} | |
const endpoint = `https://api.cloudflare.com/client/v4/zones/${zoneId}/dns_records/${dnsRecord.id}`; | |
const response = await fetch(endpoint, { | |
method: 'PUT', | |
headers: { | |
'Authorization': `Bearer ${token}`, | |
'Content-Type': 'application/json', | |
}, | |
body: JSON.stringify({ | |
type: type, | |
name: domain, | |
content: ip, | |
ttl: 1, // 1 means automatic | |
}), | |
}); | |
const data = await response.json(); | |
if (!data.success) { | |
throw new Error('Failed to update DNS record'); | |
} | |
return { success: true, message: 'DNS record updated successfully' }; | |
} | |
async function findDNSRecord(token, zoneId, domain, type) { | |
const endpoint = `https://api.cloudflare.com/client/v4/zones/${zoneId}/dns_records?name=${domain}&type=${type}`; | |
const response = await fetch(endpoint, { | |
headers: { | |
'Authorization': `Bearer ${token}`, | |
'Content-Type': 'application/json', | |
}, | |
}); | |
const data = await response.json(); | |
if (!data.success || data.result.length === 0) { | |
throw new Error('DNS record not found'); | |
} | |
return data.result[0]; // Assuming the first record is the one we want to update | |
} | |
function isIPv6(ip) { | |
return ip.includes(':'); | |
} | |
export default { | |
fetch: handleRequest | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment