UNPKG

google-ddns

Version:

Google Dynamic DNS client update tool. Updates the DNS IP address to the current public IP.

133 lines (115 loc) 5.63 kB
{ "use strict"; // Define the required modules for this class. const fs = require('fs'); const path = require('path'); const DynamicDNS = require('./DynamicDNS'); /** * This is a service class designed to run the Google DynamicDNS as a service on a time interval that checks if the public IP has * changed in-order to update the Google host DNS IP address. This is intended to be simple and clean, for more complex features use * this as a template in conjunction with DynamicDNS class. * * @class * @memberof DEDA-Google-DDNS * @author Charbel Choueiri <charbel.choueiri@gmail.com> */ class Service { /** * Creates a new class with the given options. * @param {object} options See [getDefaultOptions()]{@link DEDA-Google-DDNS.Service.getDefaultOptions} for more details. */ constructor(options) { /** * An instance of the Google DynamicDNS class used within this service. * @member {DEDA-Google-DDNS.DynamicDNS} */ this.dynamicDNS = new DynamicDNS(options); /** * Keeps track of the number of consecutive errors in-order to determine what to do next base don the set options. * @member {number} */ this.consecutiveErrors = 0; /** * The class options as defined by [getDefaultOptions()]{@link DEDA-Google-DDNS.Service.getDefaultOptions} * On initialization the constructor options parameters are merged with the default options. * @member {DEDA-Google-DDNS.Service.DefaultOptions} */ this.options = Object.assign(this.constructor.getDefaultOptions(), options); // Update log file to include first entry. this.log('Creating new service.\n'); } /** * @typedef {Object} DefaultOptions * @property {number} [checkInterval = 60] - The amount of time in seconds to wait before checking if the public IP has changed. * @property {number} [maxConsecutiveErrors = 10] - The maximum number of check consecutive errors before stopping the check timer loop. * @property {boolean} [exitOnMaxErrors = true] - Defines whether to exit process when the max consecutive errors has been reached. * @property {string | boolean} [logPath = './logs.log'] - Defines the log output path. Set to false to disable output logs. * @property {boolean} [logToConsole = true] - Defines whether to log output to the console or not. * @memberof DEDA-Google-DDNS.Service */ /** * Returns a list of all possible options for this class with their default values. * @returns {DEDA-Google-DDNS.Service.DefaultOptions} Returns the component default options. */ static getDefaultOptions() { return { checkInterval: 60, maxConsecutiveErrors: 3, exitOnMaxErrors: true, logPath: './logs.log', logToConsole: true }; } /** * Starts the service check loop that will check for public IP changes every set time interval to ensure it remains * synchronized with the host name DNS IP address. */ async start() { let checkInterval = this.options.checkInterval; // Call the sync method and get the results. const result = await this.dynamicDNS.sync(); // If it was successful then set time out to the next interval. if (result.status !== 'error') { // Clear the current error counter. this.consecutiveErrors = 0; // If it was actually updated then log it. if (result.status === 'success') this.log(result.message); } // Otherwise if an error occurred then update the counter and log the error. else { // Update the error counter and log the error. this.consecutiveErrors++; this.log(result.message, 'error'); // If google returned '911' then wait 5 minutes before trying again. Even if if checkInterval was longer than 5 minutes, we missed this one and should try again. if (result.response === '911') checkInterval = 6*60; } // If we have not exceeded the consecutive errors then run the timer again. if (this.consecutiveErrors < this.options.maxConsecutiveErrors) setTimeout(()=>this.start(), checkInterval*1000); // Otherwise log the error and exit. else this.log('The maximum consecutive errors have occurred.', 'error'); } /** * * @param {*} message * @param {*} type */ log(message, type = 'log') { // Get the current date time stamp as a string. Add the message type and time stamp. const date = new Date(); message = `${type.toUpperCase()} (${date.getFullYear()}-${(date.getMonth()+1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}:${date.getSeconds().toString().padStart(2, '0')}): ${message}`; // Append the message to the log file if provided. Also append the message to the console if set. if (this.options.logPath) fs.writeFileSync( path.resolve(process.argv[1], '../', this.options.logPath), message + '\n', {flag: 'a'} ); if (this.options.logToConsole) console[type](message); } } // Export the class Service.namespace = 'DEDA.Google.Domains.DynamicDNS.Service'; module.exports = Service; };