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

359 lines (326 loc) 9.03 kB
const _ = require('lodash'); const utils = require('../lib/helpers/utils'); const helpers = require('../lib/helpers/regexps'); const GlobalContextHelper = require('../lib/helpers/global-context-helper'); const GetEnvironment = require('../lib/helpers/get-environment'); const when = utils.when; const Types = { isLanguage(rule, message) { return new Promise((resolve, reject) => { var chatContext = message.chat(); when(chatContext.get('language')) .then(language => { if (rule.language === language) { resolve(rule); } else { reject(); } }); }); }, isTransportPreferred(rule, message) { return new Promise((resolve, reject) => { message.isTransportPreferred(rule.transport, message) .then( isAvailable => { if (isAvailable) { resolve(rule) } else { reject(); } }, () => reject() ); }); }, isTransportAvailable(rule, message) { return new Promise((resolve, reject) => { message.isTransportAvailable(rule.transport, message) .then( isAvailable => { if (isAvailable) { resolve(rule) } else { reject(); } }, () => reject() ); }); }, pending(rule, message) { return new Promise(function(resolve, reject) { var chatContext = message.chat(); when(chatContext.get('pending')) .then(function(pending) { if (pending) { resolve(rule); } else { reject(); } }); }); }, notPending(rule, message) { return new Promise(function(resolve, reject) { var chatContext = message.chat(); when(chatContext.get('pending')) .then(function(pending) { if (!pending) { resolve(rule); } else { reject(); } }); }); }, isVariable(rule, message) { return new Promise(function(resolve, reject) { var chatContext = message.chat(); when(chatContext.get(rule.variable)) .then( function(variable) { if (variable == rule.value) { resolve(rule); } else { reject(); } }, function() { reject(); }); }); }, transport(rule, message) { return new Promise(function(resolve, reject) { if (message != null && message.payload != null) { if (message.originalMessage.transport === rule.transport) { resolve(rule); } else { reject(); } } }); }, messageType(rule, message) { return new Promise(function(resolve, reject) { if (message != null && message.payload != null) { if ((helpers.isCommand(message.payload.content) && rule.messageType === 'command') || (message.payload.type === rule.messageType)) { resolve(rule); } else { reject(); } } }); }, messageEvent(rule, message) { return new Promise(function(resolve, reject) { if (message != null && message.payload != null) { if (message.payload.type === 'event' && message.payload.eventType === rule.event) { resolve(rule); } else { reject(); } } }); }, messageAnyEvent(rule, message) { return new Promise(function(resolve, reject) { if (message != null && message.payload != null) { if (message.payload.type === 'event') { resolve(rule); } else { reject(); } } }); }, notMessageType(rule, message) { return new Promise(function(resolve, reject) { if (message != null && message.payload != null) { if ((helpers.isCommand(message.payload.content) && rule.messageType === 'command') || (message.payload.type === rule.messageType)) { reject(); } else { resolve(rule); } } }); }, environment(rule, message, global) { var environment = global != null && global.environment === 'production' ? 'production' : 'development'; return new Promise(function(resolve, reject) { if (environment === rule.environment) { resolve(rule); } else { reject(); } }); }, inbound(rule, message) { return new Promise(function(resolve, reject) { if (message.payload != null && message.payload.inbound === true) { resolve(rule); } else { reject(); } }); }, anyCommand(rule, message) { return new Promise(function(resolve, reject) { if (message.payload != null && _.isString(message.payload.content) && helpers.isCommand(message.payload.content)) { resolve(rule); } else { reject(); } }); }, commandStartsWith(rule, message) { return new Promise(function(resolve, reject) { if (message.payload != null && helpers.isCommandStartsWith(message.payload.content, rule.command)) { resolve(rule); } else { reject(); } }); }, command(rule, message) { return new Promise(function(resolve, reject) { if (message.payload != null && helpers.isCommand(message.payload.content, rule.command)) { resolve(rule); } else { reject(); } }); }, outbound(rule, message) { return new Promise(function(resolve, reject) { if (message.payload != null && message.payload.inbound === false) { resolve(rule); } else { reject(); } }); }, catchAll(rule) { return new Promise(function (resolve) { resolve(rule); }); }, hasNotVariable(rule, message) { return new Promise(function (resolve, reject) { var chatContext = message.chat(); when(chatContext.get(rule.variable)) .then( function (content) { if (content == null) { resolve(rule); } else { reject(); } }, function () { reject(); }); }); }, hasVariable(rule, message) { return new Promise(function (resolve, reject) { var chatContext = message.chat(); when(chatContext.get(rule.variable)) .then( function (content) { if (content != null) { resolve(rule); } else { reject(); } }, function () { reject(); }); }); } }; /** * @method executeRules * Execute a set of rules, the first rules that complies resolve the promise with argument the rule (augumented with * the position of the rule in the list) * @deferred * @param {Array} rules * @param {Object} message * @param {Object} RED * @param {Number} [current=1] */ function executeRules(rules, message, global, current) { current = current || 1; if (_.isEmpty(rules)) { // if empty, means all rules failed return new Promise(function(resolve, reject) { reject(); }); } var first = _.first(rules); return new Promise(function(resolve, reject) { // rules doesn't exist if (!_.isFunction(Types[first.type])) { reject(); } // check if the first rule applies Types[first.type](first, message, global) .then( function () { var rule = _.clone(first); rule.index = current; resolve(rule); }, function () { var nextRules = _.tail(rules); if (_.isEmpty(nextRules)) { reject(); } else { executeRules(nextRules, message, global, current + 1) .then( function(rule) { resolve(rule); }, function() { reject(); } ); } } ); }); } module.exports = function(RED) { const globalContextHelper = GlobalContextHelper(RED); const getEnvironment = GetEnvironment(RED); function ChatBotRules(config) { RED.nodes.createNode(this, config); globalContextHelper.init(this.context().global); const node = this; const global = { environment: getEnvironment() }; node.rules = config.rules; this.on('input', function(msg) { const rules = utils.extractValue('arrayOfObject', 'rules', node, msg, true); executeRules(rules, msg, global) .then( function(rule) { var result = new Array(rules.length); result = _.map(result, function(value, idx) { return idx === (rule.index - 1) ? msg : null }); node.send(result); }, function() { // all rules failed, do nothing } ); }); } RED.nodes.registerType('chatbot-rules', ChatBotRules); };