[
  {
    "path": "LICENSE.txt",
    "content": "MIT License\n\nCopyright (c) 2018 Aleksandr Tebiev\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Mikrotik Duck DNS Dynamic IP Updater\n## How to use\n#### 1.  Duck DNS token and subdomain\nGo to [duckdns.org](https://www.duckdns.org) authorise and get your token.  \n![](https://raw.githubusercontent.com/beeyev/Mikrotik-Duckdns-Dynamic-IP-Updater/master/howto/get-token.png)\n\nThen create your new subdomain.  \n![](https://raw.githubusercontent.com/beeyev/Mikrotik-Duckdns-Dynamic-IP-Updater/master/howto/make-subdomain.png)\n\n#### 2. Create new mikrotik script\nUsing WinBox tool, go to: System -> Scripts [Add]  \n  \n**Imprtant!** Script name has to be `Duckdns-Dynamic-IP-Updater`  \nPut [script source](https://raw.githubusercontent.com/beeyev/Mikrotik-Duckdns-Dynamic-IP-Updater/master/mikrotik-duckdns-dynamic-ip-updater.rsc) and set your **token** and **subdomain** into corresponding variables.\n![](https://raw.githubusercontent.com/beeyev/Mikrotik-Duckdns-Dynamic-IP-Updater/master/howto/script-name-params.png)\n\n> If you want to use **IPv6**, change `ipv6mode` variable in the script  \n\n#### 3. Create scheduled task\nWinBox: System -> Scheduler [Add]  \n  \nName: `Duckdns-Dynamic-IP-Updater`  \nStart Time: `00:10:00`  \nInterval: `01:10:00`  \nOn Event: `/system script run Duckdns-Dynamic-IP-Updater;`  \nScheduler will run the script to update IP address every hour. If you want to make it more frequently, change the \"Interval\" parameter.\n\n![](https://raw.githubusercontent.com/beeyev/Mikrotik-Duckdns-Dynamic-IP-Updater/master/howto/scheduler-task.png)\n\nOr you can use this command to create the task:\n```\n/system scheduler add name=\"Duckdns-Dynamic-IP-Updater\" on-event=\"/system script run Duckdns-Dynamic-IP-Updater;\" start-time=00:10:00 interval=01:10:00 comment=\"\" disabled=no\n```\n---\nIf you love this project, please consider giving me a ⭐\n"
  },
  {
    "path": "mikrotik-duckdns-dynamic-ip-updater.rsc",
    "content": "#----------SCRIPT INFORMATION---------------------------------------------------\n#\n# Script:  Beeyev DuckDNS.org Dynamic DNS Update Script\n# Version: 1.2.1\n# Created: 29/07/2019\n# Updated: 11/08/2022\n# Author:  Alexander Tebiev\n# Website: https://github.com/beeyev\n#\n#----------MODIFY THIS SECTION AS NEEDED----------------------------------------\n\n# DuckDNS Sub Domain\n:local duckdnsSubDomain \"PUT-SUBDOMAIN-HERE\"\n\n# DuckDNS Token\n:local duckdnsToken \"PUT-TOKEN-HERE\"\n\n# Set true if you want to use IPv6\n:local ipv6mode false;\n\n#-------------------------------------------------------------------------------\n\n# Online services which respond with your IPv4, two for redundancy\n:local ipDetectService1 \"https://api.ipify.org/\"\n:local ipDetectService2 \"https://ipv4.icanhazip.com/\"\n\n# Online services which respond with your IPv6, two for redundancy\n:local ipv6DetectService1 \"https://api64.ipify.org/\"\n:local ipv6DetectService2 \"https://ipv6.icanhazip.com/\"\n\n#-------------------------------------------------------------------------------\n\n:local previousIP; :local currentIP\n# DuckDNS Full Domain (FQDN)\n:local duckdnsFullDomain \"$duckdnsSubDomain.duckdns.org\"\n\n:log warning message=\"START: DuckDNS.org DDNS Update\"\n\nif ($ipv6mode = true) do={\n\t:set ipDetectService1 $ipv6DetectService1;\n\t:set ipDetectService2 $ipv6DetectService2;\n\t:log error \"DuckDNS: ipv6 mode enabled\"\n}\n\n# Resolve current DuckDNS subdomain ip address\n:do {:set previousIP [:resolve $duckdnsFullDomain]} on-error={ :log warning \"DuckDNS: Could not resolve dns name $duckdnsFullDomain\" };\n\n# Detect our public IP adress useing special services\n:do {:set currentIP ([/tool fetch url=$ipDetectService1 output=user as-value]->\"data\")} on-error={\n\t\t:log error \"DuckDNS: Service does not work: $ipDetectService1\"\n\t\t#Second try in case the first one is failed\n\t\t:do {:set currentIP ([/tool fetch url=$ipDetectService2 output=user as-value]->\"data\")} on-error={\n\t\t\t:log error \"DuckDNS: Service does not work: $ipDetectService2\"\n\t\t};\n\t};\n\t\n\n:log info \"DuckDNS: DNS IP ($previousIP), current internet IP ($currentIP)\"\n\n:if ($currentIP != $previousIP) do={\n\t:log info \"DuckDNS: Current IP $currentIP is not equal to previous IP, update needed\"\n\t:log info \"DuckDNS: Sending update for $duckdnsFullDomain\"\n\t:local duckRequestUrl \"https://www.duckdns.org/update\\?domains=$duckdnsSubDomain&token=$duckdnsToken&ip=$currentIP&verbose=true\"\n\t:log info \"DuckDNS: using GET request: $duckRequestUrl\"\n\n\t:local duckResponse\n\t:do {:set duckResponse ([/tool fetch url=$duckRequestUrl output=user as-value]->\"data\")} on-error={\n\t\t:log error \"DuckDNS: could not send GET request to the DuckDNS server. Going to try again in a while.\"\n\t\t:delay 5m;\n\t\t\t:do {:set duckResponse ([/tool fetch url=$duckRequestUrl output=user as-value]->\"data\")} on-error={\n\t\t\t\t:log error \"DuckDNS: could not send GET request to the DuckDNS server for the second time.\"\n\t\t\t\t:error \"DuckDNS: bye!\"\n\t\t\t}\n\t}\n\n\t# Checking server's answer\n\t:if ([:pick $duckResponse 0 2] = \"OK\") do={\n\t\t:log info \"DuckDNS: New IP address ($currentIP) for domain $duckdnsFullDomain has been successfully set!\"\n\t} else={ \n\t\t:log warning \"DuckDNS: There is an error occurred during IP address update, server did not answer with \\\"OK\\\" response!\"\n\t}\n\n\t:log info \"DuckDNS: server answer is: $duckResponse\"\n} else={\n\t:log info \"DuckDNS: Previous IP ($previousIP) is equal to current IP ($currentIP), no need to update\"\n}\n\n:log warning message=\"END: DuckDNS.org DDNS Update finished\"\n"
  }
]