UNPKG

node-red-contrib-chatbot

Version:

REDBot a Chat bot for a full featured chat bot for Telegram, Facebook Messenger and Slack. Almost no coding skills required

179 lines (160 loc) 4.92 kB
var _ = require('underscore'); var utils = require('./helpers/utils'); var when = utils.when; var moment = require('moment'); module.exports = function(msg, node) { // extract subtokens from a object value var extractObjectKeys = function(value, subtokens) { var result = value; var currentValue = value; if (_.isArray(subtokens) && !_.isEmpty(subtokens)) { _(subtokens).each(function(subtoken) { if (_.isObject(currentValue) && currentValue[subtoken] != null) { currentValue = currentValue[subtoken]; } }); result = currentValue; } return result; }; var getTokenValue = function(token) { var value = null; var context = node.context(); var subtokens = token.split('.'); var variable = subtokens[0]; var chatContext = msg.chat(); if (token === 'payload') { value = String(msg.payload); } else if (chatContext != null && chatContext.get(variable) != null) { value = chatContext.get(variable); } else if (!_.isEmpty(context.flow.get(variable))) { value = context.flow.get(variable); } else if (!_.isEmpty(context.get(variable))) { value = context.get(variable); } else if (!_.isEmpty(context.global.get(variable))) { value = context.global.get(variable); } else if (!_.isEmpty(msg[variable])) { value = msg[variable]; } return when(value) .then(function(value) { // if nothing found, return empty space return value != null ? value : when(null); }) .then(function(value) { if (subtokens.length > 0) { value = extractObjectKeys(value, subtokens.slice(1)); } return value; }); }; var replaceTokens = function(message, tokens) { var stack = new Promise(function(resolve) { resolve(message); }); if (tokens != null && tokens.length !== 0) { // replace all tokens _(tokens).each(function(token) { stack = stack.then(function(message) { return new Promise(function(resolve) { getTokenValue(token) .then(function(value) { // if value was not fount, leve the token in place if (value != null) { // todo take the format date from config var formattedValue = value instanceof moment ? value.format('DD MMMM,YYYY') : value; resolve(message.replace(new RegExp('{{' + token + '}}', 'g'), formattedValue)); } else { resolve(message); } }); }); }); }); } return stack; }; function renderString(message) { if (_.isEmpty(message)) { return message; } // extract tokens var tokens = message.match(/\{\{([A-Za-z0-9\-\._]*?)\}\}/g); if (tokens != null && tokens.length != 0) { tokens = _(tokens).map(function (token) { return token.replace('{{', '').replace('}}', ''); }); } // replace them return replaceTokens(message, tokens); } function renderObject(item) { var task = when(true); var result = {}; return new Promise(function(resolve) { _(item).each(function (value, key) { task = task.then(function() { return renderItem(value); }).then(function(translated) { result[key] = translated; }); }); task.then(function() { resolve(result); }); }); } function renderArray(item) { var task = when(true); var result = []; return new Promise(function(resolve) { _(item).each(function (value) { task = task.then(function() { return renderItem(value); }).then(function(translated) { result.push(translated); }); }); task.then(function() { resolve(result); }); }); } function renderItem(item) { if (_.isString(item)) { return renderString(item); } else if (_.isNumber(item)) { return renderString(String(item)); } else if (_.isArray(item)) { return renderArray(item); } else if (_.isObject(item)) { return renderObject(item); } return when(item); } return function() { var toTranslate = Array.prototype.slice.call(arguments, 0); return new Promise(function(resolve) { var translated = []; var task = when(true); // translate each element of the array _(toTranslate).each(function(sentence) { task = task .then(function() { return renderItem(sentence); }) .then(function(message) { translated.push(message); }); }); // finally task.then(function() { if (translated.length === 1) { resolve(translated[0]); } else { resolve(translated); } }); }); } };