AutomationFlowsEmail & Gmail › Quotation Workflow

Quotation Workflow

Quotation-Workflow. Uses httpRequest, googleDrive, gmail. Webhook trigger; 23 nodes.

Webhook trigger★★★★☆ complexity23 nodesHTTP RequestGoogle DriveGmail
Email & Gmail Trigger: Webhook Nodes: 23 Complexity: ★★★★☆ Added:

This workflow follows the Gmail → Google Drive recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "dc",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "5b641254-75ab-43c0-bb5b-520904aa461e",
      "name": "Webhook Form",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        -848,
        480
      ]
    },
    {
      "parameters": {
        "language": "python",
        "pythonCode": "# n8n Code node: Other Services & GST (Dahi Cheeni)\nbody = _input.all()[0].json.get(\"body\", {})\n\n\ndef extract_number(val):\n    if not val or isinstance(val, (int, float)):\n        return val or 0\n    import re\n    match = re.search(r\"[\\d.]+\", str(val).strip())\n    if not match:\n        return 0\n    try:\n        return float(match.group())\n    except Exception:\n        return 0\n\n\nitems = body.get(\"Items\", [])\nif items and isinstance(items, list):\n    sub_val = sum(extract_number(it.get(\"Amount\", 0)) for it in items)\nelse:\n    sub_val = extract_number(body.get(\"Total\", 0))\n\nchef_val = extract_number(body.get(\"ChefServers\", 0))\ndecor_val = extract_number(body.get(\"TableDecor\", 0))\ncutlery_val = extract_number(body.get(\"Cutlery\", 0))\nchaffing_val = extract_number(body.get(\"Chaffing\", 0))\nconv_val = extract_number(body.get(\"Conveyance\", 0))\nvenue_val = extract_number(body.get(\"VenueCharges\", 0))\n\nsubtotal_with_services = sub_val + chef_val + decor_val + cutlery_val + chaffing_val + conv_val + venue_val\ngst_amount = subtotal_with_services * 0.05\ntotal_amount = subtotal_with_services + gst_amount\n\nreturn [\n    {\"Other Services\": \"Subtotal (Items)\", \"Amount\": sub_val},\n    {\"Other Services\": \"Chef + Servers + Helper\", \"Amount\": body.get(\"ChefServers\", 0)},\n    {\"Other Services\": \"Table D\u00e9cor (As Per Theme)\", \"Amount\": body.get(\"TableDecor\", 0)},\n    {\"Other Services\": \"Cutlery & Crockery\", \"Amount\": body.get(\"Cutlery\", 0)},\n    {\"Other Services\": \"Chaffing Dishes & Snack Warmers\", \"Amount\": body.get(\"Chaffing\", 0)},\n    {\"Other Services\": \"Conveyance\", \"Amount\": body.get(\"Conveyance\", 0)},\n    {\"Other Services\": \"Venue Charges\", \"Amount\": body.get(\"VenueCharges\", 0)},\n    {\"Other Services\": \"Subtotal (With Services)\", \"Amount\": subtotal_with_services},\n    {\"Other Services\": \"GST 5%\", \"Amount\": round(gst_amount, 2)},\n    {\"Other Services\": \"TOTAL AMOUNT\", \"Amount\": round(total_amount, 2)},\n]\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -448,
        560
      ],
      "id": "a05eaf23-7a12-4726-8cf5-0803488fb528",
      "name": "Code in Python (Beta)"
    },
    {
      "parameters": {
        "language": "python",
        "pythonCode": "return []"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -448,
        752
      ],
      "id": "dbc43f23-e157-4676-95f0-98d6a22f02f4",
      "name": "Code in Python (Beta)13"
    },
    {
      "parameters": {
        "language": "python",
        "pythonCode": "# n8n Code node: Customer Details (Dahi Cheeni)\nbody = _input.all()[0].json.get(\"body\", {})\n\nreturn [{\n    \"Event Date\": body.get(\"EventDate\", \"N/A\"),\n    \"Host Name\": body.get(\"HostName\", \"N/A\"),\n    \"Mobile No\": body.get(\"MobileNo\", \"N/A\"),\n    \"Time\": body.get(\"Time\", \"N/A\"),\n    \"Pax\": body.get(\"Pax\", \"N/A\"),\n    \"Location\": body.get(\"Location\", \"N/A\"),\n    \"Quote ID\": body.get(\"QuotationId\", \"\"),\n}]\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -448,
        176
      ],
      "id": "b707f219-c2e8-48d4-80d2-7142ca39d1c2",
      "name": "Customer Details"
    },
    {
      "parameters": {
        "content": "## PDF Generation",
        "height": 384,
        "width": 960
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        16,
        336
      ],
      "id": "e107f2aa-623b-46b2-9848-fa12d302483c",
      "name": "Sticky Note7"
    },
    {
      "parameters": {
        "numberInputs": 4
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        -112,
        432
      ],
      "id": "4c3c8134-e570-47d8-8456-1580b8e2f6da",
      "name": "Merge"
    },
    {
      "parameters": {
        "language": "python",
        "pythonCode": "# n8n Code node: Menu Item Transformation (Dahi Cheeni \u2014 qty \u00d7 rate)\ninput_data = _input.all()[0].json\nitems_list = input_data.get(\"body\", {}).get(\"Items\", [])\n\noutput = []\nfor item in items_list:\n    qty = item.get(\"Qty\", item.get(\"Portions\", 1))\n    rate = item.get(\"Rate\", 0)\n    try:\n        amount = float(item.get(\"Amount\", 0))\n    except (TypeError, ValueError):\n        try:\n            amount = float(qty or 0) * float(rate or 0)\n        except (TypeError, ValueError):\n            amount = 0\n    output.append({\n        \"Name\": item.get(\"Name\"),\n        \"Description\": item.get(\"Description\"),\n        \"Qty\": qty,\n        \"Rate\": rate,\n        \"Category\": item.get(\"Category\", \"\"),\n        \"Veg/Non Veg\": item.get(\"VegNonVeg\", \"\"),\n        \"Amount\": amount,\n    })\n\nreturn output\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -448,
        368
      ],
      "id": "2c2fedc8-5112-4f8e-bfed-570c7866ee2a",
      "name": "Menu Item Transformation"
    },
    {
      "parameters": {
        "language": "python",
        "pythonCode": "logo_url = \"https://res.cloudinary.com/dwxjq3tj9/image/upload/q_auto/f_auto/v1778926627/Dahi_Cheeni_Logo_draxao.png\"\n\ntry:\n    cust_list = _input.all(\"Customer Details\")\n    cust = cust_list[0].json if cust_list else {}\nexcept Exception:\n    cust = {}\n\nmenu_items = _input.all(\"Proposed Menu\")\nservices = _input.all(\"Other Services\")\nbrand = \"#5c1a1a\"\ncream = \"#f5ebe0\"\ngold = \"#c9a227\"\n\ndef fmt_money(val):\n    if val is None or val == \"\":\n        return \"\"\n    try:\n        s = str(val).replace(\",\", \"\").strip()\n        v = float(s)\n        return f\"\u20b9{int(v):,}\" if v == int(v) else f\"\u20b9{v:,.2f}\"\n    except Exception:\n        return str(val)\n\nhtml = f\"\"\"<!DOCTYPE html>\n<html>\n<head>\n<style>\n  @import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@500;600;700&family=Source+Sans+3:wght@400;600;700&display=swap');\n  @page {{ \n    margin: 15mm;\n    @bottom-center {{\n        content: element(footer);\n    }}\n  }}\n  body {{ font-family: 'Source Sans 3', sans-serif; color: #222; margin: 0; line-height: 1.7; padding-bottom: 35mm; }}\n  \n  .footer {{ \n    position: fixed; \n    bottom: 0; \n    left: 0; \n    right: 0; \n    text-align: center; \n    font-size: 11px; \n    color: #444; \n    border-top: 1px solid #ccc; \n    padding-top: 12px;\n    line-height: 1.4;\n    background: white;\n  }}\n  .footer-title {{ font-weight: 700; font-size: 12px; color: #000; }}\n  \n  h1, h2, h3 {{ font-family: 'Cormorant Garamond', serif; color: {brand}; }}\n  \n  /* Logo and Layout Styling */\n  .logo-wrap {{ text-align: center; padding: 20px 0 30px; }}\n  .main-logo {{ max-width: 120px; height: auto; }}\n  \n  .intro-container {{ padding: 0 10px; }}\n  .welcome-text {{ color: {brand}; font-size: 22px; font-weight: 700; margin-bottom: 25px; font-family: 'Cormorant Garamond', serif; }}\n  .intro-body {{ font-size: 16px; color: #333; }}\n  .intro-body p {{ margin-bottom: 22px; text-align: justify; }}\n  .highlight {{ color: {brand}; font-weight: 700; }}\n  .signature {{ margin-top: 40px; font-size: 16px; line-height: 1.4; }}\n  .signature strong {{ color: {brand}; font-size: 18px; }}\n\n  /* Quotation Page Styling */\n  .header-banner {{ background: {brand}; color: {cream}; padding: 18px; border-radius: 8px; margin-bottom: 20px; }}\n  .header-banner h1 {{ color: {cream} !important; text-align: center; font-size: 28px; margin: 0; letter-spacing: 1px; }}\n  .header-details {{ margin-top: 12px; font-size: 14px; border-top: 1px solid rgba(255,255,255,0.25); padding-top: 10px; }}\n  .detail-row {{ display: table; width: 100%; }}\n  .detail-row > div {{ display: table-cell; width: 50%; padding: 4px 0; }}\n  \n  h2 {{ font-size: 22px; border-bottom: 2px solid {brand}; padding-bottom: 6px; margin-top: 25px; text-transform: uppercase; letter-spacing: 1px; }}\n  \n  .data-table {{ width: 100%; border-collapse: collapse; margin-top: 12px; table-layout: fixed; }}\n  .data-table th {{ background: {brand}; color: {cream}; padding: 10px; border: 1px solid {brand}; font-size: 13px; text-transform: uppercase; }}\n  .data-table td {{ padding: 10px; border: 1px solid #ddd; font-size: 14px; vertical-align: top; }}\n  .cat-row td {{ background: #fdf8f5; font-weight: 700; color: {brand}; font-family: 'Cormorant Garamond', serif; font-size: 18px; padding: 12px 10px; }}\n  \n  .description {{ font-size: 11px; color: #666; font-style: italic; display: block; margin-top: 5px; }}\n  .badge {{ font-size: 10px; padding: 2px 8px; border-radius: 4px; background: #f0f0f0; margin-left: 8px; color: {brand}; font-weight: 700; border: 0.5px solid #ccc; }}\n  .num {{ text-align: center; }}\n  .total-row td {{ font-weight: 700; background: #faf6f4; font-size: 15px; }}\n  \n  .note-list {{ font-size: 14px; padding-left: 20px; }}\n  .note-list li {{ margin-bottom: 12px; }}\n</style>\n</head>\n<body>\n\n<div class=\"footer\">\n  <div class=\"footer-title\">Dahi Cheeni Catering</div>\n  (Unit of NC Hospitality Pvt Ltd) CIN : U55101DL2009PTC188581<br>\n  Regd. Address : E 5 Kalindi Colony, Near New Friends Colony, New Delhi 110065<br>\n  Website : www.dahicheenicatering.com | Email : sales@dahicheenicatering.com\n</div>\n\n<!-- PAGE 1: INTRODUCTION -->\n<div class=\"intro-container\">\n    <div class=\"logo-wrap\">\n      <img src=\"{logo_url}\" class=\"main-logo\" alt=\"Dahi Cheeni\">\n    </div>\n\n    <div class=\"welcome-text\">Welcome to Dahi Cheeni \u2014 Pure Veg Home-Style Catering</div>\n\n    <div class=\"intro-body\">\n      <p>Thank you for considering <span class=\"highlight\">Dahi Cheeni</span> for your upcoming gathering. With over <span class=\"highlight\">10 years of dedicated experience</span> in the hospitality industry, we bring a refined legacy of excellence, taste, and trust to your doorstep.</p>\n      \n      <p>We specialize exclusively in <span class=\"highlight\">100% pure vegetarian catering</span>, designed specifically for your most <span class=\"highlight\">auspicious occasions</span>. Whether it is a housewarming, a traditional ceremony, or an intimate family milestone, our menus are thoughtfully curated to honor the sanctity and joy of your celebration.</p>\n      \n      <p>Our culinary philosophy is rooted in authentic <span class=\"highlight\">\"home-style\" preparation</span>. We prioritize the selection of the freshest seasonal ingredients, traditional spice blends, and the highest standards of hygiene. Our goal is to serve food that doesn't just satiate hunger but evokes a sense of comfort and nostalgia, much like a meal prepared in one\u2019s own family kitchen.</p>\n      \n      <p>We take pride in our smooth, stress-free service, allowing you to focus entirely on being a host while we take care of the flavors.</p>\n      \n      <p>We look forward to being a part of your celebration and creating a delightful, soul-satisfying dining experience for you and your loved ones.</p>\n    </div>\n\n    <div class=\"signature\">\n      Warm regards,<br>\n      <strong>Team Dahi Cheeni</strong><br>\n      Pure Veg. Authentic. Intimate.\n    </div>\n</div>\n\n<div style=\"page-break-before: always;\"></div>\n\n<!-- PAGE 2: QUOTATION -->\n<div class=\"logo-wrap\">\n  <img src=\"{logo_url}\" class=\"main-logo\" alt=\"Dahi Cheeni\">\n</div>\n\n<div class=\"header-banner\">\n  <h1>EVENT QUOTATION</h1>\n  <div class=\"header-details\">\n    <div class=\"detail-row\">\n      <div><strong>HOST:</strong> {cust.get('Host Name', 'N/A')}</div>\n      <div><strong>MOBILE:</strong> {cust.get('Mobile No', 'N/A')}</div>\n    </div>\n    <div class=\"detail-row\">\n      <div><strong>DATE:</strong> {cust.get('Event Date', 'N/A')}</div>\n      <div><strong>TIME:</strong> {cust.get('Time', 'N/A')}</div>\n    </div>\n    <div class=\"detail-row\">\n      <div><strong>LOCATION:</strong> {cust.get('Location', 'N/A')}</div>\n      <div><strong>PAX:</strong> {cust.get('Pax', 'N/A')}</div>\n    </div>\n  </div>\n</div>\n\n<h2>Proposed Menu</h2>\n\"\"\"\n\nfrom collections import OrderedDict\n\ncategories = OrderedDict()\nfor item in menu_items:\n    d = item.json\n    name = (d.get(\"Name\") or \"\").strip()\n    if not name:\n        continue\n    cat = d.get(\"Category\") or \"Other\"\n    categories.setdefault(cat, []).append(d)\n\nfor cat, items in categories.items():\n    html += f\"\"\"\n<table class=\"data-table\">\n  <colgroup>\n    <col style=\"width:50%\" />\n    <col style=\"width:14%\" />\n    <col style=\"width:18%\" />\n    <col style=\"width:18%\" />\n  </colgroup>\n  <thead>\n    <tr class=\"cat-row\"><td colspan=\"4\">{cat.upper()}</td></tr>\n    <tr>\n      <th>ITEM</th>\n      <th class=\"num\">QTY</th>\n      <th class=\"num\">RATE</th>\n      <th class=\"num\">AMOUNT</th>\n    </tr>\n  </thead>\n  <tbody>\n\"\"\"\n    for d in items:\n        # Veg/Non Veg logic removed here\n        qty = d.get(\"Qty\", d.get(\"Portions\", \"\"))\n        html += f\"\"\"\n    <tr>\n      <td><strong>{d.get('Name', '')}</strong>\n        <span class=\"description\">{d.get('Description', '')}</span>\n      </td>\n      <td class=\"num\">{qty}</td>\n      <td class=\"num\">{fmt_money(d.get('Rate', ''))}</td>\n      <td class=\"num\">{fmt_money(d.get('Amount', ''))}</td>\n    </tr>\n\"\"\"\n    html += \"</tbody></table>\"\n\nhtml += f\"\"\"\n<div style=\"page-break-before: always;\">\n  <div class=\"logo-wrap\">\n    <img src=\"{logo_url}\" class=\"main-logo\" alt=\"Dahi Cheeni\">\n  </div>\n  <h2>Other Services &amp; Summary</h2>\n  <table class=\"data-table\">\n    <tbody>\n\"\"\"\n\nfor s in services:\n    sd = s.json\n    label = (sd.get(\"Other Services\") or \"\").strip()\n    if not label:\n        continue\n    amount = fmt_money(sd.get(\"Amount\", \"\"))\n    row_class = \"total-row\" if any(x in label.upper() for x in (\"TOTAL\", \"SUBTOTAL\", \"GST\")) else \"\"\n    html += f'<tr class=\"{row_class}\"><td colspan=\"3\">{label}</td><td class=\"num\">{amount}</td></tr>'\n\nhtml += f\"\"\"\n    </tbody>\n  </table>\n</div>\n\n<div style=\"page-break-before: always; margin-top: 20px;\">\n  <div class=\"logo-wrap\">\n    <img src=\"{logo_url}\" class=\"main-logo\" alt=\"Dahi Cheeni\">\n  </div>\n  <h3 style=\"text-decoration: underline; font-size: 20px;\">Important Terms & Conditions</h3>\n  <ul class=\"note-list\">\n    <li><strong>Pricing Model:</strong> Final billing is based on the actual quantity ordered or the minimum guaranteed pax, whichever is higher.</li>\n    <li><strong>Taxation:</strong> 5% GST is applicable on the final subtotal as per government mandates.</li>\n    <li><strong>Menu Finalization:</strong> We request you to confirm your final menu selections at least 4\u20135 days prior to the event date.</li>\n    <li><strong>Booking Policy:</strong> Dates are blocked only upon receipt of the booking advance.</li>\n    <li><strong>Logistics:</strong> Basic kitchen access, electricity, and water supply should be provided at the venue.</li>\n    <li><strong>Cancellation:</strong> Please refer to our detailed cancellation policy provided at the time of booking.</li>\n  </ul>\n</div>\n\n</body>\n</html>\n\"\"\"\n\nreturn [{\"html_content\": html}]"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        112,
        464
      ],
      "id": "43e4ea1d-0324-4c7c-97f9-feb8f6a9b500",
      "name": "JSON TO HTML"
    },
    {
      "parameters": {
        "operation": "toText",
        "sourceProperty": "html_content",
        "binaryPropertyName": "=data",
        "options": {
          "fileName": "=index.html"
        }
      },
      "type": "n8n-nodes-base.convertToFile",
      "typeVersion": 1.1,
      "position": [
        336,
        464
      ],
      "id": "11421d2c-8daf-490d-be58-fa1eca0539fd",
      "name": "Convert to File"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://168.231.122.119:3010/forms/chromium/convert/html",
        "sendBody": true,
        "contentType": "multipart-form-data",
        "bodyParameters": {
          "parameters": [
            {
              "parameterType": "formBinaryData",
              "name": "files",
              "inputDataFieldName": "data"
            }
          ]
        },
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        560,
        464
      ],
      "id": "5f3d3c4d-549e-4bf7-a082-5b6cb5d4a350",
      "name": "HTML TO PDF"
    },
    {
      "parameters": {
        "respondWith": "binary",
        "responseDataSource": "set",
        "options": {}
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        784,
        368
      ],
      "id": "a977732e-ec0a-437a-afe0-9e79c75569c1",
      "name": "Respond to Webhook1"
    },
    {
      "parameters": {
        "name": "={{ $('Webhook Form').first().json.body.HostName }} - {{ $('Webhook Form').first().json.body.EventDate }}.pdf",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "folderId": {
          "__rl": true,
          "value": "17HkrULgQ6MluWCSysJ19tb_GmW98r85p",
          "mode": "list",
          "cachedResultName": "Little Jalebis",
          "cachedResultUrl": "https://drive.google.com/drive/folders/17HkrULgQ6MluWCSysJ19tb_GmW98r85p"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        784,
        560
      ],
      "id": "079ae593-95a8-4937-9dad-ffe66f89acf2",
      "name": "Upload file",
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "disabled": true
    },
    {
      "parameters": {
        "language": "python",
        "pythonCode": "import json\n\n# Access the body from the first input item\nbody = _input.all()[0].json.get('body', {})\n\n# Helper function to extract numeric values\ndef extract_number(val):\n    if not val or isinstance(val, (int, float)):\n        return val or 0\n    str_val = str(val).strip()\n    import re\n    match = re.search(r'[\\d.]+', str_val)\n    if not match:\n        return 0\n    try:\n        return float(match.group())\n    except:\n        return 0\n\n# Prepare data for Supabase\nsupabase_data = {\n    \"quotation_id\": body.get(\"QuotationId\", \"\"),\n    \"host_name\": body.get(\"HostName\", \"\"),\n    \"mobile_no\": body.get(\"MobileNo\", \"\"),\n    \"event_date\": body.get(\"EventDate\", \"\"),\n    \"time\": body.get(\"Time\", \"\"),\n    \"pax\": body.get(\"Pax\", \"\"),\n    \"location\": body.get(\"Location\", \"\"),\n    \"image_grid\": body.get(\"ImageGrid\", []),\n    \"items\": body.get(\"Items\", []),\n    \"total\": extract_number(body.get(\"Total\", 0)),\n    \"chef_servers\": extract_number(body.get(\"ChefServers\", 0)),\n    \"table_decor\": extract_number(body.get(\"TableDecor\", 0)),\n    \"cutlery\": extract_number(body.get(\"Cutlery\", 0)),\n    \"chaffing\": extract_number(body.get(\"Chaffing\", 0)),\n    \"conveyance\": extract_number(body.get(\"Conveyance\", 0)),\n    \"venue_charges\": extract_number(body.get(\"VenueCharges\", 0)),\n    \"tables\": body.get(\"Tables\", \"\"),\n    \"kitchen_space\": body.get(\"KitchenSpace\", \"\")\n}\n\nreturn [supabase_data]"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -448,
        944
      ],
      "id": "cf609e4b-1619-4f63-9d8e-b835447380b3",
      "name": "Prepare Supabase Data"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://wtqtnpjliyhcwxjkincj.supabase.co/rest/v1/quotations?on_conflict=quotation_id",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "sb_publishable_JejvEEqBVuaYhS_6otvYuA_djCMsv-1"
            },
            {
              "name": "Authorization",
              "value": "<redacted-credential>"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Prefer",
              "value": "resolution=merge-duplicates,return=minimal"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify($json) }}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        -112,
        944
      ],
      "id": "021b8597-e300-44ff-9977-ca0c03f6b396",
      "name": "Save to Supabase"
    },
    {
      "parameters": {
        "path": "quotations-list",
        "responseMode": "responseNode",
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Access-Control-Allow-Origin",
                "value": "*"
              }
            ]
          }
        }
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        160,
        1136
      ],
      "id": "29404384-feb7-4987-af5d-ab8388d6b607",
      "name": "Get Quotations List"
    },
    {
      "parameters": {
        "url": "https://wtqtnpjliyhcwxjkincj.supabase.co/rest/v1/quotations?select=quotation_id,host_name,event_date,created_at&order=created_at.desc&limit=100",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "sb_publishable_JejvEEqBVuaYhS_6otvYuA_djCMsv-1"
            },
            {
              "name": "Authorization",
              "value": "<redacted-credential>"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        400,
        1136
      ],
      "id": "2eef3cb5-a669-4989-bad3-503e23073827",
      "name": "Fetch Quotations List"
    },
    {
      "parameters": {
        "respondWith": "allIncomingItems",
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Access-Control-Allow-Origin",
                "value": "*"
              }
            ]
          }
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        704,
        1136
      ],
      "id": "6496ce39-9660-4ae5-b6e5-7f1bc90dc159",
      "name": "Respond Quotations List"
    },
    {
      "parameters": {
        "path": "quotation-by-id",
        "responseMode": "responseNode",
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Access-Control-Allow-Origin",
                "value": "*"
              }
            ]
          }
        }
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        128,
        1376
      ],
      "id": "203f3096-04f5-42d8-a853-5218aaa98f16",
      "name": "Get Quotation By ID"
    },
    {
      "parameters": {
        "url": "=https://wtqtnpjliyhcwxjkincj.supabase.co/rest/v1/quotations?quotation_id=eq.{{ $json.query.id }}&limit=1",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "sb_publishable_JejvEEqBVuaYhS_6otvYuA_djCMsv-1"
            },
            {
              "name": "Authorization",
              "value": "<redacted-credential>"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        432,
        1376
      ],
      "id": "3b0fd852-38ec-4f82-969b-ed72559355cd",
      "name": "Fetch Quotation By ID"
    },
    {
      "parameters": {
        "respondWith": "allIncomingItems",
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Access-Control-Allow-Origin",
                "value": "*"
              }
            ]
          }
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        720,
        1376
      ],
      "id": "373d3f4f-8853-44fe-9d11-413f4002f20d",
      "name": "Respond Quotation By ID"
    },
    {
      "parameters": {
        "content": "Dahi Cheeni quotation workflow\nForm: form.html\nPricing: Qty \u00d7 Rate\nRe-import this JSON after edits, then activate workflow.\npython -m http.server 8000",
        "height": 112,
        "width": 464
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        0,
        0
      ],
      "id": "b2574559-2d26-45f4-94af-19a08bb79aac",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "sendTo": "vishwashchauhan77@gmail.com",
        "subject": "hello",
        "message": "={{ $('Webhook Form').first().json.body.HostName }} - {{ $('Webhook Form').first().json.body.EventDate }}.pdf",
        "options": {}
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        864,
        800
      ],
      "id": "af8eac50-45fe-4359-950e-046ecfa523c8",
      "name": "Send a message",
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "disabled": true
    },
    {
      "parameters": {
        "content": "## Data Transformation ",
        "height": 1200,
        "color": 4
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -512,
        32
      ],
      "id": "b199ef9b-7b9c-4014-933b-831865ed0713",
      "name": "Sticky Note1"
    }
  ],
  "connections": {
    "Webhook Form": {
      "main": [
        [
          {
            "node": "Code in Python (Beta)",
            "type": "main",
            "index": 0
          },
          {
            "node": "Menu Item Transformation",
            "type": "main",
            "index": 0
          },
          {
            "node": "Code in Python (Beta)13",
            "type": "main",
            "index": 0
          },
          {
            "node": "Customer Details",
            "type": "main",
            "index": 0
          },
          {
            "node": "Prepare Supabase Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in Python (Beta)": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Code in Python (Beta)13": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 3
          }
        ]
      ]
    },
    "Customer Details": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "JSON TO HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Menu Item Transformation": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "JSON TO HTML": {
      "main": [
        [
          {
            "node": "Convert to File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert to File": {
      "main": [
        [
          {
            "node": "HTML TO PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTML TO PDF": {
      "main": [
        [
          {
            "node": "Respond to Webhook1",
            "type": "main",
            "index": 0
          },
          {
            "node": "Upload file",
            "type": "main",
            "index": 0
          },
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Supabase Data": {
      "main": [
        []
      ]
    },
    "Get Quotations List": {
      "main": [
        [
          {
            "node": "Fetch Quotations List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Quotations List": {
      "main": [
        [
          {
            "node": "Respond Quotations List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Quotation By ID": {
      "main": [
        [
          {
            "node": "Fetch Quotation By ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Quotation By ID": {
      "main": [
        [
          {
            "node": "Respond Quotation By ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Quotation-Workflow. Uses httpRequest, googleDrive, gmail. Webhook trigger; 23 nodes.

Source: https://github.com/Vishwash-chauhan/dc_quotation_maker/blob/9e2a249a1a0efdd1c8acfa570e29bcb5489c6b20/n8n/quotation-workflow.json — original creator credit. Request a take-down →

More Email & Gmail workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Email & Gmail

Streamline and standardize your entire client onboarding process with a single end-to-end automation. 🚀📋 This workflow captures detailed client intake data via webhook, automatically creates a fully s

Slack, Asana, HTTP Request +4
Email & Gmail

This workflow automates daily attendance tracking by analyzing uploaded attendance images, extracting participant names via VLM Run’s Execute Agent, appending the structured data into Google Sheets, a

@Vlm Run/N8N Nodes Vlmrun, Google Drive Trigger, Google Drive +2
Email & Gmail

✨🔪 Advanced AI Powered Document Parsing & Text Extraction with Llama Parse. Uses gmail, gmailTrigger, limit, stickyNote. Webhook trigger; 54 nodes.

Gmail, Gmail Trigger, HTTP Request +6
Email & Gmail

Automate WhatsApp communication for recruitment agencies with an interactive, structured customer experience. This workflow handles pricing inquiries, request submissions, tracking, complaints, and hu

HTTP Request, Google Sheets, Gmail +1
Email & Gmail

Hectelion | Evaluation d'entreprise. Uses googleDrive, httpRequest, microsoftOutlook, googleSheets. Webhook trigger; 64 nodes.

Google Drive, HTTP Request, Microsoft Outlook +1