Hello,
Thank you for your suggestion. I solved the issue by removing the fetch command from inside the variable jsonData and instead writing the fetch result to a file. I'm not entirely sure why, but it seems that a variable only accepts string, int, float, or an array, not JSON data? I had attempted using the deserialize command before, but it didn't work with fetch inside the variable.
The current working code is as follows:
Thanks
Thank you for your suggestion. I solved the issue by removing the fetch command from inside the variable jsonData and instead writing the fetch result to a file. I'm not entirely sure why, but it seems that a variable only accepts string, int, float, or an array, not JSON data? I had attempted using the deserialize command before, but it didn't work with fetch inside the variable.
The current working code is as follows:
Code:
# ------Cloudflare DDNS script licensed under GPL 3 write by Massimo Ciani ----------## v. 1.0# Works with RouterOS versions 7.13 and above.##--------------- Change Values in this section to match your setup ------------------# Your Clouflare API token variables. Generate in your cloudflare website area:local cfToken ""# work with only one root domain or subdomain.# if you want to manage multiple domain or subdomain clone the script and change based on new domain# policy read, write, ftp and test# IMPORTANT: Before to start the script, remember to create manually the records for domain or subdomain.# ZoneID is inside the cloudflare user area.:local cfZoneId ""##### To obtain cfDnsId use following command in any unix shell:##### curl -X GET "https://api.cloudflare.com/client/v4/zones/YOUR_ZONE_ID/dns_records" -H "X-Auth-Email: YOUR_EMAIL" -H "X-Auth-Key: YOUR_API_KEY" -H "Content-Type: application/json" | python -mjson.tool:local cfDnsId "":local domain "example.com or sub.example.com":local dnsType "A":local dnsTTL 1:local dnsProxied true:local resolver "1.1.1.1"# Set the name of interface where get the internet public IP:local inetinterface "ether1"#------------------------------------------------------------------------------------# No more changes need# get current IP:global currentIP:if ([/interface get $inetinterface value-name=running]) do={ :global currentIPa [/ip address get [find interface="$inetinterface" disabled=no] address] # cancel netmask from interface IP address :for i from=( [:len $currentIPa] - 1) to=0 do={ :if ( [:pick $currentIPa $i] = "/") do={ :set currentIP [:pick $currentIPa 0 $i] } }} else={ :log info "Cloudflare: $inetinterface is not currently running, so therefore will not update." :error [:log info "bye"]}:global previousIPb# Resolve domain and update on IP changes. This method work only if use non proxied record.#:set previousIPb [:resolve domain-name="$domain" server="$resolver"]#### download json of the DNS record using the cloudflare API. ####:local getApiUrl "https://api.cloudflare.com/client/v4/zones/$cfZoneId/dns_records/$cfDnsId":local authHeader "content-type:application/json,Authorization:Bearer $cfToken"/tool fetch mode=https http-method=get url="$getApiUrl" http-header-field="$authHeader" output=file#### extract IP from the json DNS record file.:local fileContent [/file get "$cfDnsId" contents]:set previousIPb ([:deserialize from=json value=$fileContent]->"result"->"content"):log info "Previous IP is $previousIPb":if ($currentIP != $previousIPb) do={ :log info "Cloudflare $domain: Current IP $currentIP is not equal to previous IP, update needed" :log info "Cloudflare $domain: Sending update" # compose endpoint # docs: https://api.cloudflare.com/#dns-records-for-a-zone-update-dns-record :local apiUrl "https://api.cloudflare.com/client/v4/zones/$cfZoneId/dns_records/$cfDnsId" # compose headers :local headers "content-type:application/json,Authorization:Bearer $cfToken" :local payload "{\"type\":\"$dnsType\",\"name\":\"$domain\",\"content\":\"$currentIP\",\"ttl\":$dnsTTL,\"proxied\":$dnsProxied}" /tool fetch mode=https http-method=put url="$apiUrl" http-header-field="$headers" http-data="$payload" dst-path="" output=none :log info "Cloudflare $domain: updated on Cloudflare with IP $currentIP"} else={ :log info "Cloudflare $domain: Previous IP $previousIPb is equal to current IP, no update needed"}
Thanks
Statistics: Posted by nocivo — Wed Mar 20, 2024 4:01 pm