The email content node renders personalized email messages (html, text, eml). The generated content is stored in the Connect File Store. The node does not send the actual messages for this you need to add a node like node-red-contrib-sendgrid. The approach is similar to the Render Email Content task in OL Connect Workflow.
As the personalized messages sit on the Connect Server they need to downloaded in the flow. For this the email-content node returns an array of the messages created (and the ones that encountered an issue) in msg.payload. We are working on a our own sendgrid node to simplify the integration, for now you can follow the recipe below.
As stated, after creating email content you’ll find an array of message information in msg.payload.
Messages need to be downloaded one by one. This can be achieved by adding a split node (similar to the splitters in Workflow). The split node works on arrays stored in the root of msg.payload. As our messages are stored in msg.payload.message one first need to move the messages array to msg.payload. The easiest way to achieve that is by adding a change node as shown below.
The Working with messages page in the Node-RED help provides some useful tips on how to operate on data in the msg object.
The split node splits the array into a sequence of messages. It starts an iteration over the messages array that was copied to msg.payload. It generates a msg.payload for each message, this msg holds the to, subject etc as define by the rendering process in Connect. It also holds information on the content in Connect’s file store (this we will use to download the messages downstream).
In my example I’ll be using the node-red-contrib-sengrid node to send the email messages. Following the help of that node we to set certain properties on the msg object.
- msg.to, the recipient of the message
- msg.topic, the subject of the email
- msg.from, the sender email (could also be hardcoded/set in properties of the sendgrid node)
- msg.payload, the body of the message (in our case HTML generated by Connect).
Use the change node to copy information from the msg to the set the required properties. Again I’ll use the change node to set this information but when you are into coding you could use a function node too ;). In this case msg.payload.subject is copies to msg.topic and the msg.payload.to is copied to msg.to. Msg.from is set to a static string, the email address of the sender.
As the personalized content (and possible attachments) sit in Connect’s files store we need to download it to the flow. We do this one by one within the split sequence.For this the folder id and name of the resources need to be concatenated and provided to the file download node.
The result of this concatenation is stored in msg.managedFileId and allows the file download node to retrieve the HTML from the Connect File Store. The file download node stores the result in msg.payload, which is the place where the sendgrid node expects the body for the message. If this wasn’t the correct location the change node could be used to move it to the required property.
The sendgrid node is setup with an API key (for more info on this see the sendgrid online help). The format is set to html (hence the fact we are sending personalized HTML generated by Connect).
This basically wraps up the flow. The complete flow looks something like this:
As mentioned this is the current recipe that can be used today. We are working on our own sendgrid node to simplify the process (similar to the sendgrid task for OL Connect Workflow). In the example I’m injecting the data for the flow using the inject node. It writes an array of objects holding information on the recipients like first name and the email address. This array is writen to msg.payload. In your environment you could trigger the process with an http in (e.g. submit data from an lob to the flow) or read data from disk.
Hope this will get you going,
Erik
[
{
"id": "17a938e48825ee27",
"type": "comment",
"z": "5d4c388b3102d347",
"name": "Render email",
"info": "",
"x": 130,
"y": 100,
"wires": []
},
{
"id": "b86316458210ed02",
"type": "inject",
"z": "5d4c388b3102d347",
"name": "",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "[{\"first\":\"Peter\",\"email\":\"peterparker@localhost.com\"}]",
"payloadType": "json",
"x": 110,
"y": 140,
"wires": [
[
"cb7e3318f17352eb"
]
]
},
{
"id": "cb7e3318f17352eb",
"type": "olcnr-email-content",
"z": "5d4c388b3102d347",
"connect_server": "",
"template": "email.OL-template",
"section": "",
"outputFormat": "html",
"name": "",
"x": 270,
"y": 140,
"wires": [
[
"2d09f51506d92915"
]
]
},
{
"id": "823204ec92e11fc7",
"type": "split",
"z": "5d4c388b3102d347",
"name": "",
"splt": "\\n",
"spltType": "str",
"arraySplt": 1,
"arraySpltType": "len",
"stream": false,
"addname": "",
"x": 610,
"y": 140,
"wires": [
[
"88da7f0454f279f7"
]
]
},
{
"id": "2d09f51506d92915",
"type": "change",
"z": "5d4c388b3102d347",
"name": "",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "payload.messages",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 460,
"y": 140,
"wires": [
[
"823204ec92e11fc7"
]
]
},
{
"id": "88da7f0454f279f7",
"type": "change",
"z": "5d4c388b3102d347",
"name": "",
"rules": [
{
"t": "set",
"p": "managedFileId",
"pt": "msg",
"to": "payload.folder & '/' & payload.body",
"tot": "jsonata"
},
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "payload.subject",
"tot": "msg"
},
{
"t": "set",
"p": "to",
"pt": "msg",
"to": "payload.to",
"tot": "msg"
},
{
"t": "set",
"p": "from",
"pt": "msg",
"to": "vandenheuvele@eu.objectiflune.com",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 580,
"y": 220,
"wires": [
[
"dc97983152fc3e6e"
]
]
},
{
"id": "dc97983152fc3e6e",
"type": "olcnr-file-download",
"z": "5d4c388b3102d347",
"connect_server": "",
"managedFileId": "",
"name": "",
"outputType": "UTF-8",
"x": 750,
"y": 220,
"wires": [
[
"fea4a2d82f4991d6"
]
]
},
{
"id": "fea4a2d82f4991d6",
"type": "sendgrid",
"z": "5d4c388b3102d347",
"from": "",
"multiple": false,
"to": "",
"name": "",
"content": "html",
"templateId": "",
"templateData": "",
"x": 900,
"y": 220,
"wires": []
}
]