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
407 lines (371 loc) • 10.5 kB
JavaScript
var utils = require('../lib/helpers/utils');
var helpers = require('../lib/helpers/regexps');
var _ = require('underscore');
var when = utils.when;
var Types = {
isSlotConfirmationStatus: function(rule, message) {
return new Promise(function(resolve, reject) {
if (message.payload != null && message.payload.type === 'intent' && message.payload.slotConfirmationStatus != null
&& message.payload.slotConfirmationStatus[rule.slot] === rule.confirmationStatus) {
resolve(rule);
} else {
reject();
}
});
},
isIntentConfirmationStatus: function(rule, message) {
return new Promise(function(resolve, reject) {
if (message.payload != null && message.payload.type === 'intent'
&& message.payload.confirmationStatus === rule.confirmationStatus) {
resolve(rule);
} else {
reject();
}
});
},
isIntentName: function(rule, message) {
return new Promise(function(resolve, reject) {
if (message.payload != null && message.payload.type === 'intent' && message.payload.intent === rule.intent) {
resolve(rule);
} else {
reject();
}
});
},
isIntent: function(rule, message) {
return new Promise(function(resolve, reject) {
if (message.payload != null && message.payload.type === 'intent') {
resolve(rule);
} else {
reject();
}
});
},
dialogState: function(rule, message) {
return new Promise(function(resolve, reject) {
if (message.payload != null && message.payload.type === 'intent' && message.payload.dialogState === rule.state) {
resolve(rule);
} else {
reject();
}
});
},
pending: function(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: function(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: function(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: function(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: function(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: function(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();
}
}
});
},
notMessageType: function(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: function(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: function(rule, message) {
return new Promise(function(resolve, reject) {
if (message.payload != null && message.payload.inbound === true) {
resolve(rule);
} else {
reject();
}
});
},
anyCommand: function(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();
}
});
},
command: function(rule, message) {
return new Promise(function(resolve, reject) {
if (message.payload != null && helpers.isCommand(message.payload.content, rule.command)) {
resolve(rule);
} else {
reject();
}
});
},
outbound: function(rule, message) {
return new Promise(function(resolve, reject) {
if (message.payload != null && message.payload.inbound === false) {
resolve(rule);
} else {
reject();
}
});
},
isTopicEmpty: function(rule, message) {
return new Promise(function(resolve, reject) {
var chatContext = message.chat();
when(chatContext.get('topic'))
.then(
function(topic) {
if (_.isEmpty(topic)) {
resolve(rule);
} else {
reject();
}
},
function() {
reject();
});
});
},
catchAll: function(rule) {
return new Promise(function (resolve) {
resolve(rule);
});
},
isNotTopic: function(rule, message) {
return new Promise(function (resolve, reject) {
var chatContext = message.chat();
when(chatContext.get('topic'))
.then(
function (topic) {
if (topic !== rule.topic) {
resolve(rule);
} else {
reject();
}
},
function () {
reject();
});
});
},
isTopic: function(rule, message) {
return new Promise(function (resolve, reject) {
var chatContext = message.chat();
when(chatContext.get('topic'))
.then(
function (topic) {
if (topic === rule.topic) {
resolve(rule);
} else {
reject();
}
},
function () {
reject();
});
});
},
hasNotVariable: function(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: function(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();
});
});
},
topicIncludes: function(rule, message) {
return new Promise(function (resolve, reject) {
var chatContext = message.chat();
when(chatContext.get('topic'))
.then(
function (topic) {
if (topic.indexOf(rule.topic) !== -1 ) {
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 = _(rules).first();
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 = _.rest(rules);
if (_.isEmpty(nextRules)) {
reject();
} else {
executeRules(nextRules, message, global, current + 1)
.then(
function(rule) {
resolve(rule);
},
function() {
reject();
}
);
}
}
);
});
}
module.exports = function(RED) {
function ChatBotRules(config) {
RED.nodes.createNode(this, config);
var node = this;
var global = this.context().global;
node.rules = config.rules;
this.on('input', function(msg) {
var rules = utils.extractValue('arrayOfObject', 'rules', node, msg, true);
executeRules(rules, msg, global)
.then(
function(rule) {
var result = new Array(rules.length);
result = _(result).map(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);
};