{
  "id": "sk4jFfn1mNiek9UM",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "2025 Nov - Workflow sending weekly promos for Algolia-based e-commerce (No AI)",
  "tags": [],
  "nodes": [
    {
      "id": "78ab8125-5275-4a17-8352-d466a5c7ea30",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -560,
        -176
      ],
      "parameters": {
        "color": 4,
        "height": 192,
        "content": "## Every Week\nSends a weekly newsletter on Sundays at 8.00 am containing discounted products for the coming week"
      },
      "typeVersion": 1
    },
    {
      "id": "4d2975d0-1b9d-4453-82f8-753383b97c3f",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2768,
        -208
      ],
      "parameters": {
        "color": 4,
        "width": 256,
        "height": 208,
        "content": "## Send Newsletter to subscribers\nSend the the answer to the customer"
      },
      "typeVersion": 1
    },
    {
      "id": "1847023a-0a17-4adf-b110-dfc84065ce01",
      "name": "Get row(s) in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2480,
        -16
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/182rAYznmXwoxJQ9cIoRtGDcjocbRaj6_yu6_pFPpCn0/edit#gid=0",
          "cachedResultName": "Feuille 1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "182rAYznmXwoxJQ9cIoRtGDcjocbRaj6_yu6_pFPpCn0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/182rAYznmXwoxJQ9cIoRtGDcjocbRaj6_yu6_pFPpCn0/edit?usp=drivesdk",
          "cachedResultName": "2025 Nov - workflow n8n dogtreats.com - newsletter subscribers"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "f215c68b-e806-4689-8153-901b99b22ef9",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2400,
        -208
      ],
      "parameters": {
        "color": 4,
        "width": 256,
        "height": 208,
        "content": "## Get Newsletter subscribers\nSheet containing the updated list of all subscribers to this newsletter."
      },
      "typeVersion": 1
    },
    {
      "id": "d06262e7-896f-478a-b6e9-4b0f3d7651c4",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1952,
        -272
      ],
      "parameters": {
        "color": 4,
        "width": 304,
        "height": 272,
        "content": "## Load HTML Template\n\nThis node contains the HTML newsletter template for Dog Treats.  \nThe template includes placeholders for products which are dynamically injected by this node. \n\nIn this case, the HTML Code was generated using Claude Sonnet 4.5. "
      },
      "typeVersion": 1
    },
    {
      "id": "4f332fed-93fd-4670-9634-b25fa86ace59",
      "name": "Request products from Algolia",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -112,
        0
      ],
      "parameters": {
        "url": "https://Q2OJ96OC70-dsn.algolia.net/1/indexes/dogtreats_prod_products/query",
        "method": "POST",
        "options": {},
        "jsonBody": "{\n  \"filters\": \"on_sale:true\",\n  \"hitsPerPage\": 6,\n  \"attributesToRetrieve\": [\"name\",\"original_price_eur\", \"price_eur\", \"description\", \"image\"]\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpCustomAuth"
      },
      "credentials": {
        "httpCustomAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "05f7d1a1-f2a1-453d-b6fa-8c339960beb6",
      "name": "Extract Discounted Products",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        96,
        0
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "hits"
      },
      "typeVersion": 1
    },
    {
      "id": "5c23ae0c-db7b-4dd3-afde-14a0148cc322",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -208,
        -176
      ],
      "parameters": {
        "color": 4,
        "width": 864,
        "height": 144,
        "content": "## Gather products currently in promotion from Algolia\n\nGet from Algolia all the products currently in promotion and clean the API response to keep only the product Data needed to populate the newsletter. "
      },
      "typeVersion": 1
    },
    {
      "id": "38b12246-3725-4055-b6ca-ae8d370b1b76",
      "name": "On sundays 8.00 am",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -496,
        0
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtHour": 8
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "bf0a55ac-5c28-4475-9508-4fe4ce82b850",
      "name": "What day are we ?",
      "type": "n8n-nodes-base.set",
      "position": [
        -176,
        -496
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "61ed8a87-839e-4f1d-80f3-6bed331b6adc",
              "name": "Day of week",
              "type": "string",
              "value": "={{ $json[\"Day of week\"] }}"
            },
            {
              "id": "3253776a-9c2c-4616-8a56-e6823b738381",
              "name": "Day of the month",
              "type": "string",
              "value": "={{ $json[\"Day of month\"] }}"
            },
            {
              "id": "08f2338b-cff4-44c8-b250-75974d826e9f",
              "name": "Month",
              "type": "string",
              "value": "={{ $json.Month }}"
            },
            {
              "id": "0c89c6b5-0fd2-4876-a942-14e8c3a53ffe",
              "name": "Year",
              "type": "string",
              "value": "={{ $json.Year }}"
            },
            {
              "id": "fc9fd0c6-5b87-4e72-a5a4-c02a2d705a73",
              "name": "timestamp",
              "type": "string",
              "value": "={{ $json.timestamp }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "c8121488-e448-4837-ab00-bfc98aa8ba04",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -224,
        -944
      ],
      "parameters": {
        "color": 4,
        "width": 1568,
        "height": 656,
        "content": "## Determine the valid date range for the promotion (strictly no-code)\n\nThis branch determines the current day of the week and dynamically computes the valid date range that will appear on the newsletter.\nThat range corresponds to the promotional week(from Sunday to Saturday).\n\nNormally, this workflow is scheduled to execute every Sunday, since that\u2019s when the new promotion week begins.\n\nHowever, the logic here is designed to be slightly smarter: it also supports manual runs during the week.\n\nThis makes it easier for users and testers to run this workflow manually in staging or pre-production\n\nand still generate a realistic week range for the newsletter (without needing to wait until Sunday)."
      },
      "typeVersion": 1
    },
    {
      "id": "53c14d3e-79c7-4ade-b5b9-7c5990320239",
      "name": "Sunday ?",
      "type": "n8n-nodes-base.if",
      "position": [
        0,
        -496
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "813258e9-5043-456f-8d60-e6856f6d2b08",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json[\"Day of week\"] }}",
              "rightValue": "Sunday"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "d01e06f8-8421-4f04-b1d9-e653cdc37698",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -224,
        -1376
      ],
      "parameters": {
        "color": 6,
        "width": 1568,
        "height": 352,
        "content": "## \"Low Code\" alternative of the below branch in just one node\n\nUses n8n expressions to outpout the required format in one node, but needs a piece of code to do so. \nIn this very case, it was generated easily with the help of ChatGPT."
      },
      "typeVersion": 1
    },
    {
      "id": "9470179b-0c7a-4c41-b902-20c436a45810",
      "name": "Date range generator (low code)",
      "type": "n8n-nodes-base.set",
      "position": [
        400,
        -1216
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "7215ffe4-998a-4640-9920-c1224ab7805b",
              "name": "dateRange",
              "type": "string",
              "value": "={{\n  (() => {\n    // Base: \"now\" (no upstream node needed)\n    const now = new Date();\n\n    // Work in UTC to avoid timezone edge cases\n    const today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));\n    const day = today.getUTCDay(); // 0=Sun ... 6=Sat\n\n    const shiftUTC = (base, days) => {\n      const d = new Date(base.getTime());\n      d.setUTCDate(d.getUTCDate() + days);\n      return d;\n    };\n\n    let start, end;\n    if (day === 0) {\n      // If today is Sunday (normally the schedule) \u2192 upcoming week\n      start = today;\n      end = shiftUTC(start, 6);\n    } else {\n      // Otherwise \u2192 current week from previous Sunday\n      start = shiftUTC(today, -day);\n      end = shiftUTC(start, 6);\n    }\n\n    // Format like \"Nov 9 \u2013 Nov 15, 2025\" without locale reliance\n    const mon = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];\n    const fmt = (d) => `${mon[d.getUTCMonth()]} ${d.getUTCDate()}`;\n    const year = start.getUTCFullYear();\n    return `${fmt(start)} \u2013 ${fmt(end)}, ${year}`;\n  })()\n}}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "b16c5649-3575-43e5-9c4d-ac6c07d32346",
      "name": "Test trigger for low-code branch",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -400,
        -1216
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtHour": 8
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "9ada22f5-f255-4c2c-9c0f-2694b64c6cac",
      "name": "Output date of today",
      "type": "n8n-nodes-base.set",
      "position": [
        400,
        -640
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "311741bd-1fd6-4275-8c76-21294fff18af",
              "name": "timestamp",
              "type": "string",
              "value": "={{ $json.timestamp }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a2647e9c-b2d7-4930-8b52-8e523e60be03",
      "name": "Calculate end of range",
      "type": "n8n-nodes-base.dateTime",
      "position": [
        800,
        -480
      ],
      "parameters": {
        "options": {},
        "duration": 6,
        "magnitude": "={{ $json[\"Previous sunday\"] }}",
        "operation": "addToDate"
      },
      "typeVersion": 2
    },
    {
      "id": "be244160-7466-49a8-8885-fcecc35c8bbd",
      "name": "Output Promo Validity Date Range",
      "type": "n8n-nodes-base.set",
      "position": [
        1184,
        -480
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "81ef7ab1-9d1a-4c15-ac5c-e9ed142d037a",
              "name": "validityRange",
              "type": "string",
              "value": "={{ $('Clean Promo start date').item.json.formattedDate }} to {{ $json.formattedDate }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "0b0bc1e9-e2df-424d-85c0-58b56bd6b964",
      "name": "Find last Monday's date",
      "type": "n8n-nodes-base.dateTime",
      "position": [
        208,
        -480
      ],
      "parameters": {
        "date": "={{ $json.timestamp }}",
        "options": {},
        "operation": "roundDate",
        "toNearest": "week",
        "outputFieldName": "lastMondayDate"
      },
      "typeVersion": 2
    },
    {
      "id": "4c7cab3f-1db9-4e97-b62d-21543e571cec",
      "name": "Find last Sunday's date",
      "type": "n8n-nodes-base.dateTime",
      "position": [
        400,
        -480
      ],
      "parameters": {
        "options": {},
        "duration": 1,
        "magnitude": "={{ $json.lastMondayDate }}",
        "operation": "subtractFromDate",
        "outputFieldName": "Previous sunday"
      },
      "typeVersion": 2
    },
    {
      "id": "15038e2d-02e2-4f2d-84c5-71f99277f1c1",
      "name": "Clean Promo start date",
      "type": "n8n-nodes-base.dateTime",
      "position": [
        608,
        -480
      ],
      "parameters": {
        "date": "={{ $json[\"Previous sunday\"] }}",
        "format": "custom",
        "options": {
          "includeInputFields": true
        },
        "operation": "formatDate",
        "customFormat": "LLL-d"
      },
      "typeVersion": 2
    },
    {
      "id": "9aa76aa8-9b88-4260-aa57-a16da58490c6",
      "name": "Clean Promo end date",
      "type": "n8n-nodes-base.dateTime",
      "position": [
        992,
        -480
      ],
      "parameters": {
        "date": "={{ $json.newDate }}",
        "format": "custom",
        "options": {},
        "operation": "formatDate",
        "customFormat": "LLL-d-y"
      },
      "typeVersion": 2
    },
    {
      "id": "0491ec95-0910-44c4-a815-a130416821a5",
      "name": "Put back all hits in one clean array",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        528,
        0
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData",
        "destinationFieldName": "hits"
      },
      "typeVersion": 1
    },
    {
      "id": "9365da8b-03e1-46b2-b90e-236e373e9fa5",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1072,
        272
      ],
      "parameters": {
        "width": 624,
        "height": 944,
        "content": "## Newsletter structure\n\n![Newsletter structure](https://gkfvbshnthawbcaugpwp.supabase.co/storage/v1/object/public/n8n-diagrams/2025%20Nov%2011%20-%20Newsletter%20structure%202.png \"Newsletter structure\")"
      },
      "typeVersion": 1
    },
    {
      "id": "888189cb-72ea-4c7a-a247-e1e03eea6e74",
      "name": "Send newsletter",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2848,
        -16
      ],
      "parameters": {
        "sendTo": "={{ $('Get row(s) in sheet').item.json.Email }}",
        "message": "={{ $('Newsletter Generation (HTML Format)').item.json.html }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "=Dogtreats - Promos of the week - {{ $('Output Promo Validity Date Range').item.json.validityRange }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "d7fccaa2-8238-4d44-a721-50c9e62e9674",
      "name": "Newsletter Generation (HTML Format)",
      "type": "n8n-nodes-base.html",
      "position": [
        2048,
        -16
      ],
      "parameters": {
        "html": "<!doctype html>\n<html lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:o=\"urn:schemas-microsoft-com:office:office\">\n  <head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"x-apple-disable-message-reformatting\">\n    <meta name=\"format-detection\" content=\"telephone=no, date=no, address=no, email=no\">\n    <title>Dog Treats \u2013 Weekly Promotions</title>\n    <!--[if mso]>\n    <style type=\"text/css\">\n      table {border-collapse:collapse;border-spacing:0;border:0;margin:0;}\n      div, td {padding:0;}\n      div {margin:0 !important;}\n    </style>\n    <noscript>\n      <xml>\n        <o:OfficeDocumentSettings>\n          <o:PixelsPerInch>96</o:PixelsPerInch>\n        </o:OfficeDocumentSettings>\n      </xml>\n    </noscript>\n    <![endif]-->\n    <style>\n      html, body { margin:0 !important; padding:0 !important; background:#fff8f0 !important; height:100% !important; width:100% !important; }\n      body { font-family: Arial, Helvetica, sans-serif !important; color:#3b2e2a !important; }\n      * { -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; }\n      table { border-spacing:0 !important; border-collapse:collapse !important; mso-table-lspace:0pt !important; mso-table-rspace:0pt !important; }\n      table td { border-collapse: collapse; mso-line-height-rule: exactly; }\n      img { border:0; height:auto; line-height:100%; outline:none; text-decoration:none; -ms-interpolation-mode: bicubic; }\n      a { color:#c2702d !important; text-decoration:none !important; }\n      a img { border:none; }\n      h1,h2,h3 { color:#4b2d1f !important; margin:0 !important; }\n      p { margin: 0 !important; }\n      \n      /* Prevent Gmail from changing link colors */\n      a[x-apple-data-detectors] { color: inherit !important; text-decoration: none !important; }\n      \n      @media screen and (max-width:900px){\n        .container { width:100% !important; max-width:100% !important; }\n        .header, .hero, .grid, .footer { padding-left:16px !important; padding-right:16px !important; }\n        .mobile-hide { display:none !important; }\n        .card-img { height:auto !important; }\n      }\n    </style>\n  </head>\n  <body style=\"margin:0; padding:0; background-color:#fff8f0; font-family:Arial, Helvetica, sans-serif; color:#3b2e2a;\">\n    <table role=\"presentation\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"margin:0; padding:0; width:100%; background-color:#fff8f0;\">\n      <tr>\n        <td align=\"center\" style=\"padding:0;\">\n          <table role=\"presentation\" width=\"900\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"width:900px; max-width:900px; margin:24px auto; background-color:#fffaf3; border-radius:12px;\">\n            \n            <!-- Header -->\n            <tr>\n              <td style=\"background-color:#f1e0c6; padding:20px 32px; border-bottom:2px solid #e3c18e; color:#4b2d1f;\">\n                <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n                  <tr>\n                    <td style=\"vertical-align:top;\">\n                      <div style=\"font-size:22px; font-weight:700; color:#4b2d1f; line-height:28px; margin:0;\">\n                        <img src=\"https://em-content.zobj.net/source/apple/391/bone_1f9b4.png\" alt=\"\ud83e\uddb4\" style=\"width:24px; height:24px; display:inline-block; vertical-align:middle; margin-right:4px;\"> Dog Treats\n                      </div>\n                      <div style=\"font-size:12px; color:#6e5239; line-height:18px; margin:4px 0 0 0;\">Trusted treats since 2012</div>\n                    </td>\n                    <td align=\"right\" style=\"vertical-align:top;\">\n                      <div style=\"color:#6e5239; font-size:14px; font-weight:bold; line-height:20px;\">Week of {{ $json.dataForNewsletter[0].validityRange }}</div>\n                    </td>\n                  </tr>\n                </table>\n              </td>\n            </tr>\n\n            <!-- Hero Section - Cleaned Up -->\n            <tr>\n              <td style=\"padding:24px 32px; background-color:#fffaf3;\">\n                <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n                  <tr>\n                    <td style=\"padding:0 0 20px 0;\">\n                      <h1 style=\"margin:0; padding:0; font-size:28px; color:#4b2d1f; line-height:36px; font-weight:700;\">Weekly Promotions</h1>\n                    </td>\n                  </tr>\n                  <tr>\n                    <td style=\"padding:0;\">\n                      <p style=\"margin:0; padding:0; font-size:15px; color:#6e5239; line-height:24px;\">All products below are on special promotion this week. Limited stock available.</p>\n                    </td>\n                  </tr>\n                </table>\n              </td>\n            </tr>\n\n            <!-- Grid 3 columns -->\n            <tr>\n              <td style=\"padding:16px 32px 24px;\">\n                <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n                  <!-- Row 1 -->\n                  <tr>\n                    <!-- Item 0 -->\n                    <td width=\"33%\" valign=\"top\" style=\"padding:6px;\">\n                      <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"border:1px solid #f0e0c7; border-radius:10px; background-color:#fff; overflow:hidden;\">\n                        <tr>\n                          <td>\n                            <img src=\"{{ $json.dataForNewsletter[1].hits[0].image }}\" alt=\"{{ $json.dataForNewsletter[1].hits[0].name }}\" style=\"width:100%; height:200px; display:block; object-fit:cover;\">\n                          </td>\n                        </tr>\n                        <tr>\n                          <td style=\"padding:12px;\">\n                            <div style=\"font-size:14px; font-weight:bold; color:#4b2d1f; margin:0 0 6px 0; line-height:18px;\">{{ $json.dataForNewsletter[1].hits[0].name }}</div>\n                            <div style=\"font-size:12px; color:#6e5239; margin:0 0 8px 0; line-height:18px; height:36px; overflow:hidden;\">{{ $json.dataForNewsletter[1].hits[0].description }}</div>\n                            <div style=\"margin:8px 0;\">\n                              <span style=\"font-weight:bold; font-size:15px; color:#4b2d1f;\">{{ $json.dataForNewsletter[1].hits[0].price_eur }} EUR</span>\n                              <span style=\"text-decoration:line-through; color:#b28e69; margin-left:8px; font-size:12px;\">{{ $json.dataForNewsletter[1].hits[0].original_price_eur }} EUR</span>\n                            </div>\n                            <a href=\"https://www.google.com/search?q=dog+treats\" style=\"display:inline-block; background-color:#d48b39 !important; color:#ffffff !important; padding:8px 14px; border-radius:6px; font-size:13px; font-weight:600; text-decoration:none !important; margin-top:8px;\">View deal</a>\n                          </td>\n                        </tr>\n                      </table>\n                    </td>\n                    \n                    <!-- Item 1 -->\n                    <td width=\"33%\" valign=\"top\" style=\"padding:6px;\">\n                      <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"border:1px solid #f0e0c7; border-radius:10px; background-color:#fff; overflow:hidden;\">\n                        <tr>\n                          <td>\n                            <img src=\"{{ $json.dataForNewsletter[1].hits[1].image }}\" alt=\"{{ $json.dataForNewsletter[1].hits[1].name }}\" style=\"width:100%; height:200px; display:block; object-fit:cover;\">\n                          </td>\n                        </tr>\n                        <tr>\n                          <td style=\"padding:12px;\">\n                            <div style=\"font-size:14px; font-weight:bold; color:#4b2d1f; margin:0 0 6px 0; line-height:18px;\">{{ $json.dataForNewsletter[1].hits[1].name }}</div>\n                            <div style=\"font-size:12px; color:#6e5239; margin:0 0 8px 0; line-height:18px; height:36px; overflow:hidden;\">{{ $json.dataForNewsletter[1].hits[1].description }}</div>\n                            <div style=\"margin:8px 0;\">\n                              <span style=\"font-weight:bold; font-size:15px; color:#4b2d1f;\">{{ $json.dataForNewsletter[1].hits[1].price_eur }} EUR</span>\n                              <span style=\"text-decoration:line-through; color:#b28e69; margin-left:8px; font-size:12px;\">{{ $json.dataForNewsletter[1].hits[1].original_price_eur }} EUR</span>\n                            </div>\n                            <a href=\"https://www.google.com/search?q=dog+treats\" style=\"display:inline-block; background-color:#d48b39 !important; color:#ffffff !important; padding:8px 14px; border-radius:6px; font-size:13px; font-weight:600; text-decoration:none !important; margin-top:8px;\">View deal</a>\n                          </td>\n                        </tr>\n                      </table>\n                    </td>\n                    \n                    <!-- Item 2 -->\n                    <td width=\"33%\" valign=\"top\" style=\"padding:6px;\">\n                      <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"border:1px solid #f0e0c7; border-radius:10px; background-color:#fff; overflow:hidden;\">\n                        <tr>\n                          <td>\n                            <img src=\"{{ $json.dataForNewsletter[1].hits[2].image }}\" alt=\"{{ $json.dataForNewsletter[1].hits[2].name }}\" style=\"width:100%; height:200px; display:block; object-fit:cover;\">\n                          </td>\n                        </tr>\n                        <tr>\n                          <td style=\"padding:12px;\">\n                            <div style=\"font-size:14px; font-weight:bold; color:#4b2d1f; margin:0 0 6px 0; line-height:18px;\">{{ $json.dataForNewsletter[1].hits[2].name }}</div>\n                            <div style=\"font-size:12px; color:#6e5239; margin:0 0 8px 0; line-height:18px; height:36px; overflow:hidden;\">{{ $json.dataForNewsletter[1].hits[2].description }}</div>\n                            <div style=\"margin:8px 0;\">\n                              <span style=\"font-weight:bold; font-size:15px; color:#4b2d1f;\">{{ $json.dataForNewsletter[1].hits[2].price_eur }} EUR</span>\n                              <span style=\"text-decoration:line-through; color:#b28e69; margin-left:8px; font-size:12px;\">{{ $json.dataForNewsletter[1].hits[2].original_price_eur }} EUR</span>\n                            </div>\n                            <a href=\"https://www.google.com/search?q=dog+treats\" style=\"display:inline-block; background-color:#d48b39 !important; color:#ffffff !important; padding:8px 14px; border-radius:6px; font-size:13px; font-weight:600; text-decoration:none !important; margin-top:8px;\">View deal</a>\n                          </td>\n                        </tr>\n                      </table>\n                    </td>\n                  </tr>\n\n                  <!-- Row 2 -->\n                  <tr>\n                    <!-- Item 3 -->\n                    <td width=\"33%\" valign=\"top\" style=\"padding:6px;\">\n                      <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"border:1px solid #f0e0c7; border-radius:10px; background-color:#fff; overflow:hidden;\">\n                        <tr>\n                          <td>\n                            <img src=\"{{ $json.dataForNewsletter[1].hits[3].image }}\" alt=\"{{ $json.dataForNewsletter[1].hits[3].name }}\" style=\"width:100%; height:200px; display:block; object-fit:cover;\">\n                          </td>\n                        </tr>\n                        <tr>\n                          <td style=\"padding:12px;\">\n                            <div style=\"font-size:14px; font-weight:bold; color:#4b2d1f; margin:0 0 6px 0; line-height:18px;\">{{ $json.dataForNewsletter[1].hits[3].name }}</div>\n                            <div style=\"font-size:12px; color:#6e5239; margin:0 0 8px 0; line-height:18px; height:36px; overflow:hidden;\">{{ $json.dataForNewsletter[1].hits[3].description }}</div>\n                            <div style=\"margin:8px 0;\">\n                              <span style=\"font-weight:bold; font-size:15px; color:#4b2d1f;\">{{ $json.dataForNewsletter[1].hits[3].price_eur }} EUR</span>\n                              <span style=\"text-decoration:line-through; color:#b28e69; margin-left:8px; font-size:12px;\">{{ $json.dataForNewsletter[1].hits[3].original_price_eur }} EUR</span>\n                            </div>\n                            <a href=\"https://www.google.com/search?q=dog+treats\" style=\"display:inline-block; background-color:#d48b39 !important; color:#ffffff !important; padding:8px 14px; border-radius:6px; font-size:13px; font-weight:600; text-decoration:none !important; margin-top:8px;\">View deal</a>\n                          </td>\n                        </tr>\n                      </table>\n                    </td>\n                    \n                    <!-- Item 4 -->\n                    <td width=\"33%\" valign=\"top\" style=\"padding:6px;\">\n                      <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"border:1px solid #f0e0c7; border-radius:10px; background-color:#fff; overflow:hidden;\">\n                        <tr>\n                          <td>\n                            <img src=\"{{ $json.dataForNewsletter[1].hits[4].image }}\" alt=\"{{ $json.dataForNewsletter[1].hits[4].name }}\" style=\"width:100%; height:200px; display:block; object-fit:cover;\">\n                          </td>\n                        </tr>\n                        <tr>\n                          <td style=\"padding:12px;\">\n                            <div style=\"font-size:14px; font-weight:bold; color:#4b2d1f; margin:0 0 6px 0; line-height:18px;\">{{ $json.dataForNewsletter[1].hits[4].name }}</div>\n                            <div style=\"font-size:12px; color:#6e5239; margin:0 0 8px 0; line-height:18px; height:36px; overflow:hidden;\">{{ $json.dataForNewsletter[1].hits[4].description }}</div>\n                            <div style=\"margin:8px 0;\">\n                              <span style=\"font-weight:bold; font-size:15px; color:#4b2d1f;\">{{ $json.dataForNewsletter[1].hits[4].price_eur }} EUR</span>\n                              <span style=\"text-decoration:line-through; color:#b28e69; margin-left:8px; font-size:12px;\">{{ $json.dataForNewsletter[1].hits[4].original_price_eur }} EUR</span>\n                            </div>\n                            <a href=\"https://www.google.com/search?q=dog+treats\" style=\"display:inline-block; background-color:#d48b39 !important; color:#ffffff !important; padding:8px 14px; border-radius:6px; font-size:13px; font-weight:600; text-decoration:none !important; margin-top:8px;\">View deal</a>\n                          </td>\n                        </tr>\n                      </table>\n                    </td>\n                    \n                    <!-- Item 5 -->\n                    <td width=\"33%\" valign=\"top\" style=\"padding:6px;\">\n                      <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"border:1px solid #f0e0c7; border-radius:10px; background-color:#fff; overflow:hidden;\">\n                        <tr>\n                          <td>\n                            <img src=\"{{ $json.dataForNewsletter[1].hits[5].image }}\" alt=\"{{ $json.dataForNewsletter[1].hits[5].name }}\" style=\"width:100%; height:200px; display:block; object-fit:cover;\">\n                          </td>\n                        </tr>\n                        <tr>\n                          <td style=\"padding:12px;\">\n                            <div style=\"font-size:14px; font-weight:bold; color:#4b2d1f; margin:0 0 6px 0; line-height:18px;\">{{ $json.dataForNewsletter[1].hits[5].name }}</div>\n                            <div style=\"font-size:12px; color:#6e5239; margin:0 0 8px 0; line-height:18px; height:36px; overflow:hidden;\">{{ $json.dataForNewsletter[1].hits[5].description }}</div>\n                            <div style=\"margin:8px 0;\">\n                              <span style=\"font-weight:bold; font-size:15px; color:#4b2d1f;\">{{ $json.dataForNewsletter[1].hits[5].price_eur }} EUR</span>\n                              <span style=\"text-decoration:line-through; color:#b28e69; margin-left:8px; font-size:12px;\">{{ $json.dataForNewsletter[1].hits[5].original_price_eur }} EUR</span>\n                            </div>\n                            <a href=\"https://www.google.com/search?q=dog+treats\" style=\"display:inline-block; background-color:#d48b39 !important; color:#ffffff !important; padding:8px 14px; border-radius:6px; font-size:13px; font-weight:600; text-decoration:none !important; margin-top:8px;\">View deal</a>\n                          </td>\n                        </tr>\n                      </table>\n                    </td>\n                  </tr>\n                </table>\n              </td>\n            </tr>\n\n            <!-- Footer -->\n            <tr>\n              <td style=\"padding:24px 32px; background-color:#fff3e0; font-size:12px; color:#7a5b42; text-align:center; border-top:1px solid #f0e0c7;\">\n                <div style=\"margin:0 0 16px 0; line-height:18px;\">\n                  Dog Treats - 123 Bone Street, Paris 75000<br>\n                  <a href=\"mailto:user@example.com\" style=\"color:#7a5b42; text-decoration:underline;\">user@example.com</a>\n                </div>\n                \n                <!-- Social Icons with PNG images -->\n                <table role=\"presentation\" align=\"center\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"margin:16px auto;\">\n                  <tr>\n                    <td style=\"padding:0 8px;\">\n                      <a href=\"https://instagram.com/dogtreats\" title=\"Instagram\" style=\"display:inline-block;\">\n                        <img src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Instagram_logo_2016.svg/132px-Instagram_logo_2016.svg.png\" alt=\"Instagram\" style=\"width:40px; height:40px; display:block; border:0;\">\n                      </a>\n                    </td>\n                    <td style=\"padding:0 8px;\">\n                      <a href=\"https://facebook.com/dogtreats\" title=\"Facebook\" style=\"display:inline-block;\">\n                        <img src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b9/2023_Facebook_icon.svg/100px-2023_Facebook_icon.svg.png\" alt=\"Facebook\" style=\"width:40px; height:40px; display:block; border:0;\">\n                      </a>\n                    </td>\n                    <td style=\"padding:0 8px;\">\n                      <a href=\"https://tiktok.com/@dogtreats\" title=\"TikTok\" style=\"display:inline-block;\">\n                        <img src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/3/34/Ionicons_logo-tiktok.svg/512px-Ionicons_logo-tiktok.svg.png\" alt=\"TikTok\" style=\"width:40px; height:40px; display:block; border:0;\">\n                      </a>\n                    </td>\n                  </tr>\n                </table>\n                \n                <p style=\"margin:16px 0 0 0; line-height:18px;\"><a href=\"https://tiktok.com/@dogtreats\" style=\"color:#7a5b42; text-decoration:underline;\">Follow us on TikTok</a></p>\n                \n                <div style=\"margin:12px 0 0 0; font-size:11px; line-height:16px;\">\n                  <p style=\"margin:0; line-height:16px;\">You're receiving this because you subscribed to Weekly Promotions.<br>\n                  <a href=\"https://dogtreats.example/preferences\" style=\"color:#6e5b42; text-decoration:underline;\">Manage preferences</a> - <a href=\"https://dogtreats.example/unsubscribe\" style=\"color:#6e5b42; text-decoration:underline;\">Unsubscribe</a></p>\n                </div>\n              </td>\n            </tr>\n\n          </table>\n        </td>\n      </tr>\n    </table>\n  </body>\n</html>"
      },
      "typeVersion": 1.2
    },
    {
      "id": "2a69aa11-d8d8-4a1d-81c8-28d5364e775c",
      "name": "Merge data for newsletter",
      "type": "n8n-nodes-base.merge",
      "position": [
        1440,
        -16
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "11c48185-b60a-43b1-be2b-341c54fbb1da",
      "name": "Aggregate data for Newsletter",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        1728,
        -16
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData",
        "destinationFieldName": "dataForNewsletter"
      },
      "typeVersion": 1
    },
    {
      "id": "29c0a766-9582-4bb1-9851-10626218ff26",
      "name": "Keep only useful product data",
      "type": "n8n-nodes-base.set",
      "position": [
        304,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "f8d48366-a7f1-4f86-815d-0bae70594832",
              "name": "name",
              "type": "string",
              "value": "={{ $json.name }}"
            },
            {
              "id": "8bc85a37-a248-4250-9d70-f619a6823a08",
              "name": "price_eur",
              "type": "string",
              "value": "={{ $json.price_eur }}"
            },
            {
              "id": "9ef3edc3-cca6-4018-a2e1-dabba5ae91ca",
              "name": "description",
              "type": "string",
              "value": "={{ $json.description }}"
            },
            {
              "id": "a1071970-c266-4327-812d-ad21e3470842",
              "name": "objectID",
              "type": "string",
              "value": "={{ $json.objectID }}"
            },
            {
              "id": "866cbd89-5b47-4093-8dfe-ab74afbcae54",
              "name": "image",
              "type": "string",
              "value": "={{ $json.image }}"
            },
            {
              "id": "4996a32d-3a3b-4e34-b5a4-cb7e98f57a44",
              "name": "original_price_eur",
              "type": "number",
              "value": "={{ $json.original_price_eur }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "1b01a692-31cf-4903-bf7e-fcf45358b3f2",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1824,
        272
      ],
      "parameters": {
        "width": 624,
        "height": 944,
        "content": "## Newsletter prepared\n\n![Newsletter structure](https://gkfvbshnthawbcaugpwp.supabase.co/storage/v1/object/public/n8n-diagrams/2025%20Nov%2011%20-%20Newsletter%20full.png \"Newsletter structure\")"
      },
      "typeVersion": 1
    },
    {
      "id": "bea4b20e-885c-4f0d-a5e0-68294ad346ac",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1200,
        80
      ],
      "parameters": {
        "color": 6,
        "width": 198,
        "height": 80,
        "content": "### Product tiles (Thumbnails + Infos)"
      },
      "typeVersion": 1
    },
    {
      "id": "93b83118-a005-4140-bdbd-33e36d48342e",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1152,
        -176
      ],
      "parameters": {
        "color": 6,
        "width": 192,
        "height": 80,
        "content": "### Promo Validity Date (date range)"
      },
      "typeVersion": 1
    },
    {
      "id": "842d183f-d094-4cd7-9dad-ce8bcc6cf0b0",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1376,
        -1312
      ],
      "parameters": {
        "width": 624,
        "height": 1328,
        "content": "## Automated Weekly Newsletter for E-commerce Promotions (based on Algolia)\n\nThis workflow automatically sends a beautifully designed HTML newsletter every Sunday at 8 AM, featuring products currently on sale from your Algolia-powered e-commerce store.\n\n## Who's it for\n\nPerfect for e-commerce store owners, marketing teams, and anyone running promotional campaigns who wants to automate their weekly newsletter without relying on expensive email marketing platforms.\n\n## How it works\n\n1. **Triggers every Sunday at 8:00 AM** - Scheduled to start each new promotion week\n2. **Fetches discounted products** - Queries your Algolia index for 6 products marked with `on_sale:true`\n3. **Calculates promotion dates** - Automatically generates the week's date range (Sunday to Saturday)\n4. **Builds HTML newsletter** - Populates a responsive email template with product images, prices, and descriptions\n5. **Retrieves subscribers** - Pulls the latest subscriber list from your Google Sheets\n6. **Sends personalized emails** - Delivers the newsletter to all subscribers via Gmail\n\n## Set up steps\n\n**Setup time: ~15 minutes**\n\n1. Connect your **Algolia credentials** (Search API key + Application ID)\n2. Update the **Algolia index name** to match your store (currently set to `dogtreats_prod_products`)\n3. Create a **Google Sheet** with subscriber emails (column named \"Email\")\n4. Connect your **Google Sheets** and **Gmail** accounts\n5. (Optional) Customize the HTML template colors and branding to match your store\n\n## Requirements\n\n- Algolia account with a product index containing `on_sale`, `price_eur`, `original_price_eur`, `image`, `name`, and `description` fields\n- Google Sheets with subscriber list\n- Gmail account for sending emails\n\n## How to customize\n\n- **Change promotion criteria**: Modify the filter in \"Request products from Algolia\" node (e.g., `category:shoes` instead of `on_sale:true`)\n- **Adjust product count**: Change `hitsPerPage` value (currently 6)\n- **Modify schedule**: Update the trigger node to run on different days/times\n- **Personalize email design**: Edit the HTML template node to match your brand colors and style\n- **Add unsubscribe logic**: Extend the workflow to handle unsubscribe requests\n\n\ud83d\udca1 **Pro tip**: Use the manual execution button to test the workflow mid-week - it's \"smart\" enough to calculate the current promotion week even when not running on Sunday."
      },
      "typeVersion": 1
    },
    {
      "id": "60c88e0e-ed1b-432d-ab67-3b1be3734d4d",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3120,
        -48
      ],
      "parameters": {
        "width": 320,
        "height": 144,
        "content": "## Questions or Feedback?\n\n\ud83d\udce7 emir.belkahia@gmail.com  \n\ud83d\udcbc [linkedin.com/in/emirbelkahia](https://www.linkedin.com/in/emirbelkahia/)"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "ea87058c-b2d3-4694-a001-8453364005e4",
  "connections": {
    "Sunday ?": {
      "main": [
        [
          {
            "node": "Output date of today",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Find last Monday's date",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "What day are we ?": {
      "main": [
        [
          {
            "node": "Sunday ?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "On sundays 8.00 am": {
      "main": [
        [
          {
            "node": "Request products from Algolia",
            "type": "main",
            "index": 0
          },
          {
            "node": "What day are we ?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get row(s) in sheet": {
      "main": [
        [
          {
            "node": "Send newsletter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clean Promo end date": {
      "main": [
        [
          {
            "node": "Output Promo Validity Date Range",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Output date of today": {
      "main": [
        [
          {
            "node": "Clean Promo start date",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate end of range": {
      "main": [
        [
          {
            "node": "Clean Promo end date",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clean Promo start date": {
      "main": [
        [
          {
            "node": "Calculate end of range",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find last Monday's date": {
      "main": [
        [
          {
            "node": "Find last Sunday's date",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find last Sunday's date": {
      "main": [
        [
          {
            "node": "Clean Promo start date",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge data for newsletter": {
      "main": [
        [
          {
            "node": "Aggregate data for Newsletter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Discounted Products": {
      "main": [
        [
          {
            "node": "Keep only useful product data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate data for Newsletter": {
      "main": [
        [
          {
            "node": "Newsletter Generation (HTML Format)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Keep only useful product data": {
      "main": [
        [
          {
            "node": "Put back all hits in one clean array",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Request products from Algolia": {
      "main": [
        [
          {
            "node": "Extract Discounted Products",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Output Promo Validity Date Range": {
      "main": [
        [
          {
            "node": "Merge data for newsletter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Test trigger for low-code branch": {
      "main": [
        [
          {
            "node": "Date range generator (low code)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Newsletter Generation (HTML Format)": {
      "main": [
        [
          {
            "node": "Get row(s) in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Put back all hits in one clean array": {
      "main": [
        [
          {
            "node": "Merge data for newsletter",
            "type": "main",
            "index": 1
          }
        ]
      ]
    }
  }
}