Added use URL SMS provider so anyone can bridge to their own SMS solution (#4478)
Ylian Saint-Hilaire committed
Sep 1, 2022 at 13:31 UTC
dce036658e4d64db12da98e2dd3aa7fccd2f8173
3 files changed
+37
meshcentral-config-schema.json
+8
@@ -1310,6 +1310,14 @@
1310
"from": { "type": "string" }
1311
},
1312
"required": [ "provider", "apikey", "from" ]
1313
+ },
1314
+ {
1315
+ "type": "object",
1316
+ "properties": {
1317
+ "provider": { "type": "string", "enum": [ "url" ] },
1318
+ "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." }
1319
+ },
1320
+ "required": [ "url" ]
1321
}
1322
]
1323
}
meshsms.js
+25
@@ -78,6 +78,14 @@ module.exports.CreateMeshSMS = function (parent) {
78
obj.provider = require('telnyx')(parent.config.sms.apikey);
79
break;
80
}
81
+ case 'url': {
82
+ // Validate URL configuration values
83
+ if (typeof parent.config.sms.url != 'string') { console.log('Invalid or missing SMS gateway URL value.'); return null; }
84
+ 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; }
85
+ if (parent.config.sms.url.indexOf('{{message}}') == -1) { console.log('Invalid or missing SMS gateway, URL must include {{message}}.'); return null; }
86
+ if (parent.config.sms.url.indexOf('{{phone}}') == -1) { console.log('Invalid or missing SMS gateway, URL must include {{phone}}.'); return null; }
87
+ break;
88
+ }
89
default: {
90
// Unknown SMS gateway provider
91
console.log('Unknown SMS gateway provider: ' + parent.config.sms.provider);
@@ -123,6 +131,23 @@ module.exports.CreateMeshSMS = function (parent) {
131
if (err != null) { parent.debug('email', 'SMS error: ' + err.type); } else { parent.debug('email', 'SMS result: ' + JSON.stringify(result)); }
132
if (func != null) { func((err == null), err ? err.type : null, result); }
133
});
134
+ } else if (parent.config.sms.provider == 'url') { // URL
135
+ var sms = parent.config.sms.url.split('{{phone}}').join(encodeURIComponent(to)).split('{{message}}').join(encodeURIComponent(msg));
136
+ parent.debug('email', 'SMS URL: ' + sms);
137
+ sms = require('url').parse(sms);
138
+ if (sms.protocol == 'https:') {
139
+ // HTTPS GET request
140
+ const options = { hostname: sms.hostname, port: sms.port ? sms.port : 443, path: sms.path, method: 'GET', rejectUnauthorized: false };
141
+ 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) { }); });
142
+ request.on('error', function (err) { parent.debug('email', 'SMS error: ' + err); if (func != null) { func(false, err, null); } });
143
+ request.end();
144
+ } else {
145
+ // HTTP GET request
146
+ const options = { hostname: sms.hostname, port: sms.port ? sms.port : 80, path: sms.path, method: 'GET' };
147
+ 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) { }); });
148
+ request.on('error', function (err) { parent.debug('email', 'SMS error: ' + err); if (func != null) { func(false, err, null); } });
149
+ request.end();
150
+ }
151
}
152
}
153
sample-config-advanced.json
+4
@@ -601,5 +601,9 @@
601
"provider": "telnyx",
602
"apikey": "xxxxxxx",
603
"from": "1-555-555-5555"
604
+ },
605
+ "____sms": {
606
+ "provider": "url",
607
+ "url": "http://example.com/sms.ashx?phone={{phone}}&message={{message}}"
608
}
609
}