Create an email with several data from a woocommerce cart

I have a website with Woocommerce.

When I have a new order, I receive a feed to N8N.

In all of the actions that are carried out I would like to send an email to different users detailing what is contained in the order.

The problem being that the number of products is not always the same and therefore I do not see how to combine the different products of the order in an email.

I do not know if I am clear in my request.
Do you have any idea how I might do this?

Best regards

Lionel

Can you post the data you receive so we can play with it?
You should be able to just loop over the array “line_items” and create a row for every entry, using the data you want to display (name, quantity, total?).

2 Likes

Yes quite. But I must admit that I have never performed this type of operation.

It is for this reason that I ask for some advice :slight_smile:

Post the data you have as screenshot as text in a

Blockquote

so it’s easy to copy and use. Or do you expect people to write it down by themselves from the screenshot? :smiley:

Probably also good to just read through the docs if you haven’t checked them yet!

1 Like

Sorry :slight_smile:

[

{

“order_details”: [

{

“id”: 3,

“name”: “Sac”,

“product_id”: 220,

“variation_id”: 0,

“quantity”: 1,

“tax_class”: “”,

“subtotal”: “37.19”,

“subtotal_tax”: “0.00”,

“total”: “37.19”,

“total_tax”: “0.00”,

“taxes”: [

],

“meta_data”: [

{

“id”: 39,

“key”: “_reduced_stock”,

“value”: “1”,

“display_key”: “_reduced_stock”,

“display_value”: “1”

}

],

“sku”: “”,

“price”: 37.19,

“parent_name”: null

},

{

“id”: 4,

“name”: “Veste”,

“product_id”: 214,

“variation_id”: 0,

“quantity”: 1,

“tax_class”: “”,

“subtotal”: “150.03”,

“subtotal_tax”: “0.00”,

“total”: “150.03”,

“total_tax”: “0.00”,

“taxes”: [

],

“meta_data”: [

{

“id”: 40,

“key”: “_reduced_stock”,

“value”: “1”,

“display_key”: “_reduced_stock”,

“display_value”: “1”

}

],

“sku”: “”,

“price”: 150.03,

“parent_name”: null

}

]

}

]

1 Like

Many thanks for sharing @Lyoto!

I’ve put a quick example workflow together that uses your example data and writes it into a single string field (which you can then send out via email). It uses some JavaScript logic:

  • The initial Function node converts the example dataset you have provided in a valid n8n data structure consisting of multiple items (one for each of your line items).
  • In the second Function node, we’re building a single string which you can use in your email. This script essentially just iterates over all input items and appends to our result string message.
Example Workflow
{
  "nodes": [
    {
      "parameters": {
        "fromEmail": "[email protected]",
        "toEmail": "[email protected]",
        "subject": "Your Example Order",
        "text": "={{$json[\"message\"]}}",
        "options": {}
      },
      "name": "Send Email",
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 1,
      "position": [
        850,
        300
      ],
      "credentials": {
        "smtp": {
          "id": "14",
          "name": "SMTP Account"
        }
      }
    },
    {
      "parameters": {},
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        250,
        300
      ]
    },
    {
      "parameters": {
        "functionCode": "let example = [{\n    \"order_details\": [{\n            \"id\": 3,\n            \"name\": \"Sac\",\n            \"product_id\": 220,\n            \"variation_id\": 0,\n            \"quantity\": 1,\n            \"tax_class\": \"\",\n            \"subtotal\": \"37.19\",\n            \"subtotal_tax\": \"0.00\",\n            \"total\": \"37.19\",\n            \"total_tax\": \"0.00\",\n            \"taxes\": [],\n            \"meta_data\": [{\n                \"id\": 39,\n                \"key\": \"_reduced_stock\",\n                \"value\": \"1\",\n                \"display_key\": \"_reduced_stock\",\n                \"display_value\": \"1\"\n            }],\n            \"sku\": \"\",\n            \"price\": 37.19,\n            \"parent_name\": null\n        },\n        {\n            \"id\": 4,\n            \"name\": \"Veste\",\n            \"product_id\": 214,\n            \"variation_id\": 0,\n            \"quantity\": 1,\n            \"tax_class\": \"\",\n            \"subtotal\": \"150.03\",\n            \"subtotal_tax\": \"0.00\",\n            \"total\": \"150.03\",\n            \"total_tax\": \"0.00\",\n            \"taxes\": [],\n            \"meta_data\": [{\n                \"id\": 40,\n                \"key\": \"_reduced_stock\",\n                \"value\": \"1\",\n                \"display_key\": \"_reduced_stock\",\n                \"display_value\": \"1\"\n            }],\n            \"sku\": \"\",\n            \"price\": 150.03,\n            \"parent_name\": null\n        }\n    ]\n}];\n\nreturn example[0].order_details.map(e => { return { json: e } });"
      },
      "name": "Set Example Data",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        450,
        300
      ]
    },
    {
      "parameters": {
        "functionCode": "let message = `Hello,\n\nhere are your line items:\n`;\n\nfor (item of items) {\n  message += `${item.json.quantity} x ${item.json.name} ($${item.json.price} each): ${item.json.total}\n`;\n}\n\nreturn [{\n  json: {\n    message: message\n  }\n}]"
      },
      "name": "Build Email Text",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        650,
        300
      ]
    },
    {
      "parameters": {
        "fromEmail": "[email protected]",
        "toEmail": "[email protected]",
        "subject": "Your Example Order",
        "text": "={{$json[\"message\"]}}",
        "options": {}
      },
      "name": "Send Email",
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 1,
      "position": [
        850,
        300
      ],
      "credentials": {
        "smtp": {
          "id": "14",
          "name": "SMTP Account"
        }
      }
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "Set Example Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Example Data": {
      "main": [
        [
          {
            "node": "Build Email Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Email Text": {
      "main": [
        [
          {
            "node": "Send Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

And this is the resulting email:
image

Is this what you had in mind?

Edit: This would work fine while your workflow only processes a single cart at a time. If there are multiple carts we might need to adjust our logic slightly. It would actually become simpler, since we could just iterate over each line item directly and wouldn’t need to convert the line items into n8n items beforehand (but the data structure would be harder to read).

1 Like

Thank you, this is the solution!
I’m looking at how I know how to implement this in my system.

A big thanks

1 Like

Awesome, glad to hear this works for you, thanks so much for confirming :slight_smile:

Have a nice day and please do let us know if you run into any trouble down the line!

I just tried to implement this in my workflow but I’m stuck on one last element.

How do I get the data I have in a set to automatically fit into function.
I have a SET with a STRING which has the name order_details.

Sorry, definitely a silly question :stuck_out_tongue:

So the Function node can access items through the $item() method or the items array.

So if you set order_details in a workflow like this:
image

You could refer to order_details in your Function node using items[0].json.order_details.

Example Workflow
{
  "nodes": [
    {
      "parameters": {},
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        240,
        300
      ]
    },
    {
      "parameters": {
        "values": {
          "string": [
            {
              "name": "order_details",
              "value": "foo"
            }
          ]
        },
        "options": {}
      },
      "name": "Set",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        460,
        300
      ]
    },
    {
      "parameters": {
        "functionCode": "return [{\n  json: {\n    value: items[0].json.order_details\n  }\n}];\n"
      },
      "name": "Function",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        680,
        300
      ]
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "Set",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set": {
      "main": [
        [
          {
            "node": "Function",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Perfect, thanks for taking over @MutedJam !
And now I know the preformatted text is better than the blockquote for sharing code.

1 Like

Ah yes, I think that might have been some mixup earlier :smiley:

I definitely prefer the preformatted text as it will prevent all formatting from being applied. Either using this button or by manually putting three backticks ``` before and after my code:
image

1 Like