UNPKG

@apidaze/node-red-contrib-apidaze

Version:
82 lines (68 loc) 2.34 kB
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 => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', "'": '&#39;', '"': '&quot;' })[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); };