Grouping outputs from one node into one html message

Hey!

I am currently trying to make a workflow that reads a google sheet, takes entries that meet certain criteria (dates matching), and then sends an email that includes html including all of the entries that match the date.

At present, it creates a separate email for each matching entry. Does anyone know how to make it so that I can have a list of matching entries in one message?

Hey @Sarah_Strickland,

I tend to use a function node for that, if you look at the workflow example below you can get an idea of how to do it. Ignore the Zendesk bit and just copy the function node and it may clear things up for you.

https://n8n.io/workflows/1265

Thank you - this is definitely what I need to do, it is just hard for me to write the code (as someone who can’t really code) without being able to see the inputs from the zendesk node (due to authorisation). Do you happen to have a pro forma of this function by any chance, please?

I don’t really have another example, if you can share your workflow and a basic example of your sheet data (with nothing sensitive) I can put a workflow example together for you tomorrow that is closer to what you are after.

Thank you - that would really save my life! Once question mark is how to make the Name linked to the linkedin URL if I merge the inputs. Another is how to incorporate the merged inputs into my html (I deleted most of a much longer email, of which the grouped inputs need to go in the middle)

{
  "nodes": [
    {
      "parameters": {},
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        120,
        170
      ]
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "range": "A:E",
        "options": {
          "continue": true,
          "valueRenderMode": "FORMATTED_VALUE"
        }
      },
      "name": "Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 1,
      "position": [
        -299,
        511
      ],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "57",
          "name": "Sarah"
        }
      }
    },
    {
      "parameters": {
        "functionCode": "var date = new Date().toISOString();\n\nitems[0].json.date_today = date;\n\nreturn items;\n \n"
      },
      "name": "Today's date",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        -299,
        291
      ]
    },
    {
      "parameters": {
        "value": "={{$json[\"date_today\"]}}",
        "dataPropertyName": "Today_formatted",
        "options": {}
      },
      "name": "Reformat",
      "type": "n8n-nodes-base.dateTime",
      "typeVersion": 1,
      "position": [
        -109,
        291
      ]
    },
    {
      "parameters": {
        "value": "={{$json[\"Date to send\"]}}",
        "dataPropertyName": "Date to send_formatted",
        "options": {
          "fromFormat": "DD/MM/YYYY"
        }
      },
      "name": "Reformat1",
      "type": "n8n-nodes-base.dateTime",
      "typeVersion": 1,
      "position": [
        -99,
        511
      ]
    },
    {
      "parameters": {
        "mode": "multiplex"
      },
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 1,
      "position": [
        121,
        411
      ]
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{$json[\"Date to send_formatted\"]}}",
              "value2": "={{$json[\"Today_formatted\"]}}"
            }
          ]
        }
      },
      "name": "IF",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        320,
        330
      ],
      "alwaysOutputData": false,
      "continueOnFail": true
    },
    {
      "parameters": {
        "resource": "message",
        "subject": "={{$json[\"Date to send\"]}} | Hot Candidates",
        "includeHtml": true,
        "htmlMessage": "=<p>Hi xxxxxx!</p>\n<p>Our <strong>🌶️ </strong>xxxxxxxx this week:</p>\n<p>🤖 <a href=\"{{$json[\"LinkedIn\"]}}\">{{$json[\"Name \"]}}</a>&nbsp; - {{$json[\"Function\"]}}: {{$json[\"Notes\"]}}<br /></p>",
        "message": "={{$parameter[\"htmlMessage\"]}}",
        "toList": [
          "[email protected]"
        ],
        "additionalFields": {}
      },
      "name": "Gmail",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 1,
      "position": [
        520,
        270
      ],
      "credentials": {
        "gmailOAuth2": {
          "id": "11",
          "name": "sarah gmail"
        }
      }
    }
  ],
  "connections": {
    "Google Sheets": {
      "main": [
        [
          {
            "node": "Reformat1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Today's date": {
      "main": [
        [
          {
            "node": "Reformat",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Reformat": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Reformat1": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "IF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF": {
      "main": [
        [
          {
            "node": "Gmail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}```

Hey @jon - have you had the chance to look at this at all? No worries if not!

Sarah

Hey @Sarah_Strickland,

I missed this one today, Are you able to share the structure of your google sheet as well or share one with me that has the same fields but contains dummy data.

Of course - here you go: Copy of Hot Candidates - Google Tabellen

Hey @Sarah_Strickland,

Example workflow is below, What I have done is added the function node and built out the entire email body there so if you wanted to change the XXXXX bits you would do it there.

Then for the GMail node I have used the output of the function, I also changed the subject to directly reference the output of “Reformat1”.

I have given it a quick test and with the data provided it provides what I assume to be the correct output.

image

Example Workflow
{
  "nodes": [
    {
      "parameters": {},
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        260,
        420
      ]
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "sheetId": "13EXytTILm1rxuiAm-aSFh-WkYqjrpk-8gZ5CNL7r9xA",
        "range": "A:E",
        "options": {
          "continue": true,
          "valueRenderMode": "FORMATTED_VALUE"
        }
      },
      "name": "Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 1,
      "position": [
        480,
        520
      ],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "8",
          "name": "Sheets"
        }
      }
    },
    {
      "parameters": {
        "functionCode": "var date = new Date().toISOString();\n\nitems[0].json.date_today = date;\n\nreturn items;\n \n"
      },
      "name": "Today's date",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        480,
        300
      ]
    },
    {
      "parameters": {
        "value": "={{$json[\"date_today\"]}}",
        "dataPropertyName": "Today_formatted",
        "options": {}
      },
      "name": "Reformat",
      "type": "n8n-nodes-base.dateTime",
      "typeVersion": 1,
      "position": [
        660,
        300
      ]
    },
    {
      "parameters": {
        "value": "={{$json[\"Date to send\"]}}",
        "dataPropertyName": "Date to send_formatted",
        "options": {
          "fromFormat": "DD/MM/YYYY"
        }
      },
      "name": "Reformat1",
      "type": "n8n-nodes-base.dateTime",
      "typeVersion": 1,
      "position": [
        660,
        520
      ]
    },
    {
      "parameters": {
        "mode": "multiplex"
      },
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 1,
      "position": [
        900,
        420
      ]
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{$json[\"Date to send_formatted\"]}}",
              "value2": "={{$json[\"Today_formatted\"]}}"
            }
          ]
        }
      },
      "name": "IF",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        1100,
        340
      ],
      "alwaysOutputData": false,
      "continueOnFail": true
    },
    {
      "parameters": {
        "resource": "message",
        "subject": "={{$node[\"Reformat1\"].json[\"Date to send\"]}} | Hot Candidates",
        "includeHtml": true,
        "htmlMessage": "={{$json[\"emailBody\"]}}",
        "message": "={{$parameter[\"htmlMessage\"]}}",
        "toList": [
          "[email protected]"
        ],
        "additionalFields": {}
      },
      "name": "Gmail",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 1,
      "position": [
        1540,
        320
      ],
      "credentials": {
        "gmailOAuth2": {
          "id": "25",
          "name": "GMAIL (fps)"
        }
      }
    },
    {
      "parameters": {
        "functionCode": "let emailBody = '<p>Hi xxxxxx!</p>'\n  + '<p>Our <strong>🌶️ </strong>xxxxxxxx this week:</p>';\n\n// Add the extra lines to the email body\nfor (item of items) {\n  emailBody += '<p>🤖 <a href=\"' + item.json.LinkedIn + '\"> ' + item.json[\"Name \"] + '</a>&nbsp; - ' + item.json.Function + ' : ' + item.json.Notes + '<br /></p>';  \n}\n\n// Return just one field that contains our email\nreturn [{json: {emailBody}}];"
      },
      "name": "Function",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        1320,
        320
      ]
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "Today's date",
            "type": "main",
            "index": 0
          },
          {
            "node": "Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets": {
      "main": [
        [
          {
            "node": "Reformat1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Today's date": {
      "main": [
        [
          {
            "node": "Reformat",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Reformat": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Reformat1": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "IF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF": {
      "main": [
        [
          {
            "node": "Function",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Function": {
      "main": [
        [
          {
            "node": "Gmail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Hopefully this helps :+1:

Thank you so much - this has helped so much you can’t imagine!

1 Like