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

175 lines (156 loc) 5.56 kB
var _ = require('underscore'); var utils = require('../lib/helpers/utils'); var lcd = require('../lib/helpers/lcd'); var dialogflow = require('dialogflow'); var when = utils.when; function parseFields(fields) { var variables = {}; _(fields).each(function(value, key) { if (value.kind === 'stringValue') { if (!_.isEmpty(value.stringValue)) { variables[key] = value.stringValue; } } else if (value.kind === 'numberValue') { variables[key] = value.numberValue; } else if (value.kind === 'structValue' ) { variables[key] = parseFields(value.structValue.fields); } else { // eslint-disable-next-line no-console console.log('Warning: incorrectly handled dialogflow.com response type:'); // eslint-disable-next-line no-console console.log(value); } }); return variables; } module.exports = function(RED) { function ChatBotDialogflow(config) { RED.nodes.createNode(this, config); var node = this; node.dialogflow = config.dialogflow; node.language = config.language; node.debug = config.debug; node.variable = config.variable; this.on('input', function (msg) { var chatContext = msg.chat(); var dialogFlowNode = RED.nodes.getNode(node.dialogflow); var language = utils.extractValue('string', 'language', node, msg, false); var variable = utils.extractValue('string', 'variable', node, msg, false); var debug = utils.extractValue('boolean', 'debug', node, msg, false); var chatId = utils.getChatId(msg); // exit if empty credentials if (dialogFlowNode == null || dialogFlowNode.credentials == null) { lcd.warn('Dialogflow.ai credentials are missing.'); return; } // error if no language at all if (_.isEmpty(language)) { node.error('Language param is empty in Dialogflow node'); return; } // exit if not message if (!utils.message.isMessage(msg)) { node.send([null, msg]); return; } var email = dialogFlowNode.credentials.email; var privateKey = dialogFlowNode.credentials.privateKey; var projectId = dialogFlowNode.credentials.projectId; var sessionClient = new dialogflow.SessionsClient({ credentials: { private_key: privateKey, client_email: email } }); /* POST https://language.googleapis.com/v1/documents:analyzeEntities?key=API_KEY */ var sessionPath = sessionClient.sessionPath(projectId, String(chatId)); var request = { session: sessionPath, queryInput: { text: { text: msg.payload.content, languageCode: language.toLowerCase() } } }; var isFallback = null; var intent = null; var variables = {}; var answer = null; var body = null; when(chatContext.set('pending', true)) .then(function() { return sessionClient.detectIntent(request); }) .then(function(response) { body = response; return when(chatContext.set('pending', false)); }) .then(function() { // extract variables if (body == null || !_.isArray(body) || _.isEmpty(body)) { return Promise.reject('Error on api.dialogflow.com'); } // parse answer if (body[0].queryResult.intent != null && body[0].queryResult.intent.displayName) { intent = body[0].queryResult.intent.displayName; } else if (!_.isEmpty(body[0].queryResult.action) && body[0].queryResult.action.indexOf('smalltalk.') !== -1) { intent = body[0].queryResult.action; } isFallback = body[0].queryResult.intent != null && body[0].queryResult.intent.isFallback ? body[0].queryResult.intent.isFallback : null; answer = !_.isEmpty(body[0].queryResult.fulfillmentText) ? body[0].queryResult.fulfillmentText : null; // get fields if (body[0].queryResult.parameters != null && body[0].queryResult.parameters.fields) { variables = parseFields(body[0].queryResult.parameters.fields); } // if empty, exit from second output and stop here if (intent == null) { // if didn't matched any intent node.send([null, msg]); return Promise.reject(); } else { // if found, store the intent in the context and go on return when(!_.isEmpty(variable) ? chatContext.set(variable, intent) : true); } }) .then(function() { msg.payload = { type: 'intent', isFallback: isFallback, intent: intent, variables: !_.isEmpty(variables) ? variables : null, answer: answer }; if (debug) { lcd.node(msg.payload, { node: node, title: 'Dialogflow.com' }); } node.send([msg, null]); }) .catch(function(error) { if (error != null) { node.error(error, msg); } }); }); } RED.nodes.registerType('chatbot-dialogflow', ChatBotDialogflow); function DialogflowToken(n) { RED.nodes.createNode(this, n); } RED.nodes.registerType('chatbot-dialogflow-token', DialogflowToken, { credentials: { email: { type: 'text' }, privateKey: { type: 'text' }, projectId: { type: 'text' } } }); };