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

324 lines (288 loc) 11.2 kB
var _ = require('underscore'); var _s = require('underscore.string'); var URL = require('url'); var mime = require('mime-types') var validators = { platform: { discord: function(config) { config = config || {}; var result = {}; if (config.authorizedUsernames != null && !_.isString(config.authorizedUsernames)) { result.authorizedUsernames = 'Must be a comma separated list of chatIds'; } if (config.logfile != null && !_.isString(config.logfile)) { result.logfile = 'Must be a valid filename'; } _.extend(result, validators.platform.contextProvider(config)); return _.keys(result).length === 0 ? null : result; }, alexa: function(config) { config = config || {}; var result = {}; if (config.authorizedUsernames != null && !_.isString(config.authorizedUsernames)) { result.authorizedUsernames = 'Must be a comma separated list of chatIds'; } if (config.logfile != null && !_.isString(config.logfile)) { result.logfile = 'Must be a valid filename'; } _.extend(result, validators.platform.contextProvider(config)); return _.keys(result).length === 0 ? null : result; }, twilio: function(config) { config = config || {}; var result = {}; if (!_.isString(config.authToken) || _.isEmpty(config.authToken)) { result.token = 'Missing or invalid auth token'; } if (!_.isString(config.accountSid) || _.isEmpty(config.accountSid)) { result.token = 'Missing or invalid account Sid'; } if (!_.isString(config.fromNumber) || _.isEmpty(config.fromNumber)) { result.token = 'Missing or invalid Twilio number'; } if (config.authorizedUsernames != null && !_.isString(config.authorizedUsernames)) { result.authorizedUsernames = 'Must be a comma separated list of chatIds'; } if (config.logfile != null && !_.isString(config.logfile)) { result.logfile = 'Must be a valid filename'; } _.extend(result, validators.platform.contextProvider(config)); return _.keys(result).length === 0 ? null : result; }, universal: function(/*config*/) { //config = config || {}; var result = {}; // todo verify config return _.keys(result).length === 0 ? null : result; }, viber: function(config) { config = config || {}; var result = {}; if (!_.isString(config.token) || _.isEmpty(config.token)) { result.token = 'Missing or invalid access token'; } if (!_.isString(config.webhook) || !validators.url(config.webhook)) { result.webhook = 'Missing or invalid webhook'; } return _.keys(result).length === 0 ? null : result; }, slack: function(config) { config = config || {}; var result = {}; if (!_.isString(config.botname) || _.isEmpty(config.botname)) { result.token = 'Missing or invalid access bot name'; } if (!_.isString(config.token) || _.isEmpty(config.token)) { result.token = 'Missing or invalid access token'; } if (config.authorizedUsernames != null && !_.isString(config.authorizedUsernames)) { result.authorizedUsernames = 'Must be a comma separated list of chatIds'; } if (config.logfile != null && !_.isString(config.logfile)) { result.logfile = 'Must be a valid filename'; } _.extend(result, validators.platform.contextProvider(config)); return _.keys(result).length === 0 ? null : result; }, facebook: function(config) { config = config || {}; var result = {}; if (!_.isString(config.token) || _.isEmpty(config.token)) { result.token = 'Missing or invalid access token'; } if (!_.isString(config.verifyToken)) { result.token = 'Missing or invalid access verify token'; } if (config.profileFields != null && !_.isString(config.profileFields)) { result.profileFields = 'Invalid list of profile fields'; } if (!_.isString(config.appSecret) || _.isEmpty(config.appSecret)) { result.appSecret = 'Missing or invalid app secret'; } if (config.authorizedUsernames != null && !_.isString(config.authorizedUsernames)) { result.authorizedUsernames = 'Must be a comma separated list of chatIds'; } if (config.logfile != null && !_.isString(config.logfile)) { result.logfile = 'Must be a valid filename'; } _.extend(result, validators.platform.contextProvider(config)); return _.keys(result).length === 0 ? null : result; }, telegram: function(config) { config = config || {}; var result = {}; if (!_.isString(config.token) || _.isEmpty(config.token)) { result.token = 'Missing or invalid access token'; } if (config.polling != null && !_.isNumber(config.polling)) { result.polling = 'Must be a number'; } if (config.authorizedUsernames != null && !_.isString(config.authorizedUsernames)) { result.authorizedUsernames = 'Must be a comma separated list of username or chatIds'; } if (config.logfile != null && !_.isString(config.logfile)) { result.logfile = 'Must be a valid filename'; } if (!_(['none', 'html', 'markdown']).contains(config.parseMode)) { result.parseMode = 'Must be one of: none, html, markdown'; } if (config.connectMode != null && !_(['polling', 'webHook']).contains(config.connectMode)) { result.connectMode = 'Must be one of: polling, webHook'; } if (config.connectMode === 'webHook' && !validators.url(config.webHook)) { result.webHook = 'Invalid Url'; } if (config.connectMode === 'webHook' && !validators.secureUrl(config.webHook)) { result.webHook = 'Webhook Url must be secure (https)'; } _.extend(result, validators.platform.contextProvider(config)); return _.keys(result).length === 0 ? null : result; }, contextProvider: function(config) { config = config || {}; var result = {}; var allowedContextProviders = ['memory', 'plain-file']; if (config.contextProvider != null && !_(allowedContextProviders).contains(config.contextProvider)) { result.contextProvider = 'Invalid context provider, must one of: ' + allowedContextProviders.join(', '); } if (config.contextParams != null && !_.isObject(config.contextParams)) { result.contextProvider = 'Must be a object'; } return _.keys(result).length === 0 ? null : result; } }, number: function(value) { return _.isNumber(value); }, numberOrVariable: function(value) { return _.isNumber(value) || (!_.isEmpty(value) && !isNaN(parseFloat(value))) || (!_.isEmpty(value) && validators.isVariable(value)); }, shippingOption: function(element) { return _.isObject(element) && _.isString(element.id) && !_.isEmpty(element.id) && _.isString(element.label) && !_.isEmpty(element.label) && validators.numberOrVariable(element.amount); }, shippingOptions: function(elements) { return _.isArray(elements) && !_.isEmpty(elements) && _(elements).all(function(element) { return validators.shippingOption(element); }); }, variable: function(element) { return _.isString(element) && element.match(/^\{\{[A-Za-z0-9_-]*\}\}$/) != null; }, isVariable: function(value) { return validators.variable(value); // legacy }, invoiceItem: function(element) { return _.isObject(element) && _.isString(element.label) && !_.isEmpty(element.label) && validators.numberOrVariable(element.amount); }, invoiceItems: function(elements) { return _.isArray(elements) && !_.isEmpty(elements) && _(elements).all(function(element) { return validators.invoiceItem(element); }); }, invoice: function(invoice) { var result = validators.string(invoice.title) && validators.string(invoice.description) && validators.string(invoice.payload) && validators.string(invoice.currency) && validators.invoiceItems(invoice.prices); if (!_.isEmpty(invoice.photoUrl)) { result = result && validators.integer(invoice.photoWidth) && validators.integer(invoice.photoHeight); } return result; }, float: function(value) { return !isNaN(parseFloat(value)); }, button: function(button) { return _.isObject(button) && (button.type != null || validators.buttons(button.items)); }, buttons: function(buttons) { return _.isArray(buttons) && !_.isEmpty(buttons) && _(buttons).all(function(button) { return validators.button(button); }); }, genericTemplateElements: function(elements) { return _.isArray(elements) && !_.isEmpty(elements) && _(elements).all(function(element) { return validators.genericTemplateElement(element); }); }, genericTemplateElement: function(element) { return _.isObject(element) && !_.isEmpty(element.title) && _.isString(element.title) && _.isArray(element.buttons) && (element.buttons.length === 0 || validators.buttons(element.buttons)); }, filepath: function(filepath) { return _s.startsWith(filepath, './') || _s.startsWith(filepath, '../') || _s.startsWith(filepath, '/'); }, url: function(url) { if (!_.isString(url)) { return false; } var myUrl = URL.parse(url); return _.isString(url) && !_.isEmpty(myUrl.host) && !_.isEmpty(myUrl.hostname) && !_.isEmpty(myUrl.protocol) && myUrl.hostname.indexOf('.') !== -1; }, secureUrl: function(url) { return validators.url(url) && url.toLowerCase().startsWith('https'); }, buffer: function(buffer) { return buffer instanceof Buffer; }, string: function(value) { return _.isString(value) && !_.isEmpty(value); }, boolean: function(value) { return _.isBoolean(value); }, array: function(value) { return _.isArray(value) && !_.isEmpty(value); }, nlpToken: function(token) { return token != null && token.match(/^([a-zA-Z0-9%$£# ]{1,}){0,1}(\[[a-zA-Z0-9]{1,}\]){0,1}(->[a-zA-Z0-9_]{1,}){0,1}$/) != null; }, nlpTokens: function(tokens) { return !_.isEmpty(tokens) && _(tokens.split(',')).all(function(token) { return validators.nlpToken(token); }); }, integer: function(value) { return !isNaN(parseInt(value, 10)); }, messages: function(value) { return !_.isEmpty(value) && _.isArray(value) && _(value).all(function(message) { // in node config elements are object, in payload are just strings return _.isObject(message) ? !_.isEmpty(message.message) : !_.isEmpty(message); }); }, arrayOfMessage: function(value) { return _.isArray(value) && _(value).all(function(item) { return _.isObject(item) && !_.isEmpty(item.type); }); }, filenameIsImage: function(str) { if (!_.isEmpty(str)) { var mimeType = mime.lookup(str); return mimeType.indexOf('image') !== -1; } return false; } }; module.exports = validators;