@apidaze/node-red-contrib-apidaze
Version:
Node-RED module for Apidaze
82 lines (68 loc) • 2.34 kB
JavaScript
module.exports = function (RED) {
'use strict';
const { Builder } = require('xml2js');
function XMLResponse(config) {
RED.nodes.createNode(this, config);
const escapeHTML = str => str.replace(
/[&<>'"]/g,
tag => ({
'&': '&',
'<': '<',
'>': '>',
"'": ''',
'"': '"'
})[tag]
);
const builderOptions = {
attrkey: '_',
charkey: 'z',
rootName: 'document',
normalizeTags: true,
};
this.on('input', (msg, send) => {
const { payload } = msg;
const { call, script, webhookUrl } = payload;
const builder = new Builder(builderOptions);
let xmlOutput = builder.buildObject({ work: [script] });
const callProperties = [
'called_number',
'caller_number',
'caller_username',
'caller_id',
'dialed_digits',
'call_uuid',
'caller_descript',
'custom',
];
const entities = [];
for (const propertyName of callProperties) {
xmlOutput = xmlOutput.replace(new RegExp(`\\$${propertyName};`,'g'), `&${propertyName};`);
if (xmlOutput.indexOf(`&${propertyName};`) >= 0) {
const propertyValue = call[propertyName];
entities.push(`<!ENTITY ${propertyName} "${escapeHTML(propertyValue)}">`);
}
}
for (const propertyName of Object.keys(call.custom)) {
xmlOutput = xmlOutput.replace(new RegExp(`\\$custom_${propertyName};`,'g'), `&custom_${propertyName};`);
const propertyValue = call.custom[propertyName];
if (xmlOutput.indexOf(`&custom_${propertyName};`) > 0) {
entities.push(`<!ENTITY custom_${propertyName} "${escapeHTML(propertyValue)}">`);
}
}
xmlOutput = xmlOutput.replace(new RegExp(`\\$url;`,'g'), `&url;`);
if (xmlOutput.indexOf('&url;') > 0) {
entities.push(`<!ENTITY url "${escapeHTML(webhookUrl)}">`);
}
if (entities.length){
xmlOutput = xmlOutput.replace('<document>', '<!DOCTYPE document [\n' + (entities.join('\n')) + '\n]><document>');
}
if (msg.res._res) {
msg.res._res
.header('Content-Type', 'text/xml')
.status(200)
.send(xmlOutput);
}
});
}
RED.nodes.registerType('xml-response', XMLResponse);
};