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

169 lines (160 loc) 5.9 kB
const _ = require('underscore'); const MessageTemplate = require('../lib/message-template-async'); const validators = require('../lib/helpers/validators'); const RegisterType = require('../lib/node-installer'); const { ChatExpress } = require('chat-platform'); const { isValidMessage, getChatId, getMessageId, getTransport, extractValue } = require('../lib/helpers/utils'); const GlobalContextHelper = require('../lib/helpers/global-context-helper'); module.exports = function(RED) { const registerType = RegisterType(RED); const globalContextHelper = GlobalContextHelper(RED); function ChatBotMessengerTemplate(config) { RED.nodes.createNode(this, config); var node = this; globalContextHelper.init(this.context().global); this.name = config.name; this.templateType = config.templateType; this.text = config.text; this.json = config.json; this.buttons = config.buttons; this.title = config.title; this.subtitle = config.subtitle; this.imageUrl = config.imageUrl; this.mediaUrl = config.mediaUrl; this.mediaType = config.mediaType; this.attachmentId = config.attachmentId; this.productId = config.productId; this.on('input', async function(msg, send, done) { // send/done compatibility for node-red < 1.0 send = send || function() { node.send.apply(node, arguments) }; done = done || function(error) { node.error.call(node, error, msg) }; // check if valid message if (!isValidMessage(msg, node)) { return; } const chatId = getChatId(msg); const messageId = getMessageId(msg); const template = MessageTemplate(msg, node); const transport = getTransport(msg); // check transport compatibility if (!ChatExpress.isSupported(transport, 'template')) { done(`Node "template" is not supported by ${transport} transport`); return; } // get values from config const buttons = extractValue('buttons', 'buttons', node, msg); const title = extractValue('string', 'title', node, msg); let templateType = extractValue('string', 'templateType', node, msg); const text = extractValue('string', 'text', node, msg); const json = extractValue(['string', 'hash'], 'json', node, msg); const subtitle = extractValue('string', 'subtitle', node, msg); const imageUrl = extractValue('string', 'imageUrl', node, msg); const mediaUrl = extractValue('string', 'mediaUrl', node, msg); const mediaType = extractValue('string', 'mediaType', node, msg); const attachmentId = extractValue('string', 'attachmentId', node, msg); const productId = extractValue('string', 'productId', node, msg); let elements = extractValue('arrayOfFacebookTemplateElements', 'elements', node, msg); elements = elements != null ? elements : []; // infer the templateType from a list of elements defined upstream if (!_.isEmpty(elements) && ['generic', 'product'].includes(elements[0].templateType) ) { templateType = elements[0].templateType; } //let elements = []; let payload; // if inbound is another message from a generic template, then push them toghether to create a carousel if (msg.payload != null && msg.payload.type === 'template') { if (msg.payload.templateType === 'generic') { if (validators.genericTemplateElements(msg.payload.elements)) { elements = _.union(elements, msg.payload.elements); } else { done('Some element in the generic template is not valid'); return; } } else if (msg.payload.templateType === 'product') { if (validators.productTemplateElements(msg.payload.elements)) { elements = _.union(elements, msg.payload.elements); } else { done('Some element in the product template is not valid'); return; } } else { done('It\'s not possible to combine different template types'); return; } } const translated = await template({ title, subtitle, imageUrl, mediaUrl, mediaType, attachmentId, productId, buttons, text }); // add the current one if not empty let jsonPayload; if (_.isString(json)) { try { jsonPayload = JSON.parse(json); } catch(e) { done('Invalid JSON in Messenger template'); return; } } else { jsonPayload = json; } switch (templateType) { case 'generic': // skip if empty if (!_.isEmpty(title)) { elements.push({ title: translated.title, subtitle: translated.subtitle, imageUrl: translated.imageUrl, buttons: translated.buttons }); } break; case 'button': payload = { text: translated.text, buttons: translated.buttons }; break; case 'customer_feedback': case 'receipt': payload = { json: jsonPayload }; break; case 'media': payload = { mediaUrl: translated.mediaUrl, mediaType: translated.mediaType, attachmentId: translated.attachmentId }; break; case 'product': // skip if empty if (!_.isEmpty(translated.productId)) { elements.push({ id: translated.productId }); } break; } send({ ...msg, payload: { type: 'template', templateType, ...payload, elements, chatId, messageId } }) done(); }); } registerType('chatbot-messenger-template', ChatBotMessengerTemplate); };