diff --git a/meshcentral-config-schema.json b/meshcentral-config-schema.json index 1ae2a626..b8733ce5 100644 --- a/meshcentral-config-schema.json +++ b/meshcentral-config-schema.json @@ -1310,6 +1310,14 @@ "from": { "type": "string" } }, "required": [ "provider", "apikey", "from" ] + }, + { + "type": "object", + "properties": { + "provider": { "type": "string", "enum": [ "url" ] }, + "url": { "type": "string", "description": "A http or https URL with {{phone}} and {{message}} in the string. These will be replaced with the URL encoded target phone number and message." } + }, + "required": [ "url" ] } ] } diff --git a/meshsms.js b/meshsms.js index e2b2b7ce..138e7a2a 100644 --- a/meshsms.js +++ b/meshsms.js @@ -78,6 +78,14 @@ module.exports.CreateMeshSMS = function (parent) { obj.provider = require('telnyx')(parent.config.sms.apikey); break; } + case 'url': { + // Validate URL configuration values + if (typeof parent.config.sms.url != 'string') { console.log('Invalid or missing SMS gateway URL value.'); return null; } + if (!parent.config.sms.url.toLowerCase().startsWith('http://') && !parent.config.sms.url.toLowerCase().startsWith('https://')) { console.log('Invalid or missing SMS gateway, URL must start with http:// or https://.'); return null; } + if (parent.config.sms.url.indexOf('{{message}}') == -1) { console.log('Invalid or missing SMS gateway, URL must include {{message}}.'); return null; } + if (parent.config.sms.url.indexOf('{{phone}}') == -1) { console.log('Invalid or missing SMS gateway, URL must include {{phone}}.'); return null; } + break; + } default: { // Unknown SMS gateway provider console.log('Unknown SMS gateway provider: ' + parent.config.sms.provider); @@ -123,6 +131,23 @@ module.exports.CreateMeshSMS = function (parent) { if (err != null) { parent.debug('email', 'SMS error: ' + err.type); } else { parent.debug('email', 'SMS result: ' + JSON.stringify(result)); } if (func != null) { func((err == null), err ? err.type : null, result); } }); + } else if (parent.config.sms.provider == 'url') { // URL + var sms = parent.config.sms.url.split('{{phone}}').join(encodeURIComponent(to)).split('{{message}}').join(encodeURIComponent(msg)); + parent.debug('email', 'SMS URL: ' + sms); + sms = require('url').parse(sms); + if (sms.protocol == 'https:') { + // HTTPS GET request + const options = { hostname: sms.hostname, port: sms.port ? sms.port : 443, path: sms.path, method: 'GET', rejectUnauthorized: false }; + const request = require('https').request(options, function (res) { parent.debug('email', 'SMS result: ' + res.statusCode); func(res.statusCode == 200, (res.statusCode == 200) ? null : res.statusCode, null); res.on('data', function (d) { }); }); + request.on('error', function (err) { parent.debug('email', 'SMS error: ' + err); if (func != null) { func(false, err, null); } }); + request.end(); + } else { + // HTTP GET request + const options = { hostname: sms.hostname, port: sms.port ? sms.port : 80, path: sms.path, method: 'GET' }; + const request = require('http').request(options, function (res) { parent.debug('email', 'SMS result: ' + res.statusCode); func(res.statusCode == 200, (res.statusCode == 200) ? null : res.statusCode, null); res.on('data', function (d) { }); }); + request.on('error', function (err) { parent.debug('email', 'SMS error: ' + err); if (func != null) { func(false, err, null); } }); + request.end(); + } } } diff --git a/sample-config-advanced.json b/sample-config-advanced.json index ea23bfdc..a42f77c3 100644 --- a/sample-config-advanced.json +++ b/sample-config-advanced.json @@ -601,5 +601,9 @@ "provider": "telnyx", "apikey": "xxxxxxx", "from": "1-555-555-5555" + }, + "____sms": { + "provider": "url", + "url": "http://example.com/sms.ashx?phone={{phone}}&message={{message}}" } }