The Universal Connector node allows to connect the the RedBot ecosystem any kind of messaging service (like email, an SMS gateway, a testing stub, etc). It’s an advanced component, a good kwowledge of JavaScript and Promises is required in order to use it.

Unlike other receiver nodes the Universal Connector node has an input pin, this is where the external service will send the payload in order to be translated and injected in the RedBot flow. The Universal Connector node takes care of providing the chat context, the pass thru and track features, the production/development configuration, etc; while the implementation detail about how the incoming message is implemented is left to the user and must be implemented with an Extend node .

In order to properly translate an incoming message the implementation in the Universal Connector node must:

  1. Extract a chatId from the payload: it’s a unique identifier of the conversation in the connected platform (for example the mobile number for a SMS gateway, the email for an email system, etc)

  2. Extract or infer the message type. Some messaging platform support different type of messages (for example Telegrams supports message, audio, photo, etc) while a service like a SMS gateway just support one type of message.

  3. Extract the message content it also should (but is not mandatory)

  4. Extract the timestamp of the message

  5. Extract a messageId to properly reference inbound and outbound messages in the external service timeline

Like explained in Extend node a connector handles inbound messages with a chain of middlewares: chunk of codes executed sequentially in order to accomplish steps 1 to 3. In order to keep the code simple and maintainable is a good practice to let middleware takes care of detecting and translating one kind of message in each middleware, as soon as a message has been resolved (means that a message type is assigned to the incoming message), the rest of middlewares chain is skipped and the message is injected in the RedBot’s flow.

For example suppose that a SMS gateway calls the Node-RED instance web-hook with this payload

{  
	sms: {    
		from: '+39347123456',    
		to: '+39338654321',    
		id: '_xyz',    
		text: 'Hello there!',    
		sender_name: 'Alan Turing'  
	}
}

The from key is a good candidate for the chatId while the content of the message is in the text key. the code in the Extend node to handle this

// initial stage of the process, here the message is still not enriched with all the helpers and
// variables of a RedBot message like .api(), .chat(), chatId, etc
node.chat.onChatId(message => message.sms.from);
node.chat.onMessageId(message => message.sms.id);
node.chat.in(message => {  
	return new Promise((resolve, reject) => {    
		// check that the incoming payload is an actual "text" message    
		if (message.originalMessage.sms != null && message.originalMessage.sms.text != '') {
      message.payload.type = 'message';      
			message.payload.content = message.originalMessage.sms.text;    
		}    
		resolve(message);  
	});
});

When a new payload arrives to the input pin the chatId value is extracted from the callback .onChatId() (there are callbacks for other information like messageId, timestamp, language, etc) and a neutral version of the RedBot message is passed to the middlewares. A neutral message is a regular RedBot message (the messages that flow out of a receiver node) except the type and content key are left blank: is up to the developer to fill in this keys using the information contained in originalMessage, all values needed to build a neutral message (chatId, messageId, timestamp, language) are extracted using callbacks. If the callback in .onChatId() fails to extract the chatId then an exception is raised and the message will never go through the middlewares.

In the example above there is additional information in the payload, it’s a good practice to use the chat context for storing this information, for example