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 w. dummy data - 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

Hopefully this helps :+1:

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

1 Like

Hi @Jon,

Your workflow worked so well for my case and I thought that maybe you help me with one thing

The simple workflow that I applied:

  1. Reads google sheet
  2. Uses your function to loop through the items and return one json item
  3. Sends one email

One problem that I have is that I need names of the owners before list of the entries (only for the ones that apply to that owner) so in an email body it would look like:
Owner X
entry 1
entry 2
entry 3
Owner Y
entry 1
entry 2
Owner Z
entry 1
entry 2
entry 3
entry 4

I thought that maybe it would be possible to loop through the items when they meet condition where owner = “Peter”, and then loop again when owner is for example Susan, Bob, Mike etc.

I copied dummy data and added just one column - Owner instead of Date. As you can see there is one owner for x entries and then another owner for the next entires and so on. I want the email body to include their names before the list of their entires so it’s kind of organized in an email.
Copy of dummy data - my case

Do you think it might be possible to write a function for that? I don’t code in Javascript so it’s hard for me to even think if it’s something achievable

Hey @Bia,

Welcome to the community :cake:

In theory it is possible it would just be a case of working out the javascript.