{
  "id": "TcrHaQAWIeGsHHS0",
  "name": "My workflow",
  "tags": [],
  "nodes": [
    {
      "id": "5c7eafd7-ca03-4541-8915-e2f936f92e81",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        256,
        -480
      ],
      "parameters": {
        "width": 480,
        "height": 816,
        "content": "## My workflow\n\n### How it works\n\nThis workflow handles contact form submissions from a website. It receives the webhook payload, normalizes key form fields, builds email content, sends notifications to both the site admin and visitor, then returns a success response to the website.\n\n### Setup steps\n\n- Configure the webhook URL in the website contact form so submissions are sent to the n8n webhook trigger.\n- Review the field mappings in the normalization step to match the form payload keys for name, email, subject, message, and timestamp.\n- Connect and authorize the Gmail credentials used by both email-sending nodes.\n- Set the admin recipient address and verify the visitor confirmation email uses the submitted email address.\n- Test the workflow with a sample form submission and confirm both emails are delivered and the website receives a success response.\n\n### Customization\n\nCustomize the email templates in the code node, update the admin recipient, or add validation/spam checks before sending emails."
      },
      "typeVersion": 1
    },
    {
      "id": "810dad9b-7344-4c14-9ffe-4ffddbca0b6d",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        816,
        -384
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 336,
        "content": "## Receive and prepare form\n\nCaptures the incoming contact form webhook submission, standardizes the submitted fields, and builds the admin and visitor email payloads. These nodes form the left-side preparation cluster before any messages are sent."
      },
      "typeVersion": 1
    },
    {
      "id": "f8f4bad8-75c6-44f6-a8ec-5e7d6c46856e",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1488,
        -432
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 464,
        "content": "## Send notification emails\n\nSends the prepared email content through Gmail, first notifying the administrator of the new submission and then sending a confirmation email to the visitor. These two Gmail nodes sit together in the central-right email delivery cluster."
      },
      "typeVersion": 1
    },
    {
      "id": "ab83a664-9b73-4081-a535-fa5dc4f2721e",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1936,
        -480
      ],
      "parameters": {
        "color": 7,
        "height": 432,
        "content": "## Return website response\n\nCompletes the webhook request by returning a success response to the website after both emails have been sent. This final response node is positioned at the far right as the workflow endpoint."
      },
      "typeVersion": 1
    },
    {
      "id": "65b080f9-9624-4c70-ad8d-f933314c5160",
      "name": "When Form Submitted",
      "type": "n8n-nodes-base.webhook",
      "position": [
        864,
        -208
      ],
      "parameters": {
        "path": "portfolio-contact",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "1d2cceeb-a257-48f5-b7c0-4130aae0297d",
      "name": "Set Contact Form Data",
      "type": "n8n-nodes-base.set",
      "position": [
        1088,
        -208
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "c1",
              "name": "timestamp",
              "type": "string",
              "value": "={{ $now.toISO() }}"
            },
            {
              "id": "c2",
              "name": "name",
              "type": "string",
              "value": "={{ $json.body?.name ?? $json.name }}"
            },
            {
              "id": "c3",
              "name": "email",
              "type": "string",
              "value": "={{ $json.body?.email ?? $json.email }}"
            },
            {
              "id": "c4",
              "name": "subject",
              "type": "string",
              "value": "={{ $json.body?.subject ?? $json.subject }}"
            },
            {
              "id": "c5",
              "name": "message",
              "type": "string",
              "value": "={{ $json.body?.message ?? $json.message }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "0f5c7115-38d9-4a06-b63c-d81dc043917f",
      "name": "Compose Emails for Admin & Visitor",
      "type": "n8n-nodes-base.code",
      "position": [
        1312,
        -208
      ],
      "parameters": {
        "jsCode": "const item = $input.first().json;\n\nconst d = {\n  timestamp: String(item.timestamp ?? ''),\n  name: String(item.name ?? ''),\n  email: String(item.email ?? ''),\n  subject: String(item.subject ?? ''),\n  message: String(item.message ?? ''),\n};\n\nfunction esc(value) {\n  return String(value ?? '')\n    .replace(/&/g, '&amp;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\"/g, '&quot;')\n    .replace(/\\n/g, '<br>');\n}\n\nconst brand = '#343a9e';\nconst brandLight = '#eef0fa';\n\nconst row = (label, value) =>\n  `<tr>\n    <td style=\"padding:12px 16px;border-bottom:1px solid #e8eaef;color:#6b7280;font-size:13px;width:120px;vertical-align:top;\">${label}</td>\n    <td style=\"padding:12px 16px;border-bottom:1px solid #e8eaef;color:#1a1d2e;font-size:14px;font-weight:500;\">${value}</td>\n  </tr>`;\n\nconst adminHtml = `<!DOCTYPE html>\n<html>\n<head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"></head>\n<body style=\"margin:0;padding:0;background:#f4f5f7;font-family:Arial,Helvetica,sans-serif;\">\n  <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#f4f5f7;padding:32px 16px;\">\n    <tr><td align=\"center\">\n      <table width=\"600\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#ffffff;border-radius:12px;overflow:hidden;box-shadow:0 4px 24px rgba(52,58,158,0.08);\">\n        <tr><td style=\"background:${brand};padding:28px 32px;\">\n          <p style=\"margin:0;color:rgba(255,255,255,0.85);font-size:12px;letter-spacing:1px;text-transform:uppercase;\">Portfolio Contact Form</p>\n          <h1 style=\"margin:8px 0 0;color:#ffffff;font-size:22px;font-weight:700;\">New Contact Message</h1>\n        </td></tr>\n        <tr><td style=\"padding:28px 32px 8px;\">\n          <p style=\"margin:0 0 20px;color:#4b5563;font-size:15px;line-height:1.6;\">Someone submitted the contact form on your portfolio. Details below.</p>\n          <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:${brandLight};border-radius:8px;overflow:hidden;\">\n            ${row('Name', esc(d.name))}\n            ${row('Email', `<a href=\"mailto:${esc(d.email)}\" style=\"color:${brand};text-decoration:none;\">${esc(d.email)}</a>`)}\n            ${row('Subject', esc(d.subject))}\n            ${row('Message', esc(d.message))}\n            ${row('Submitted', esc(d.timestamp))}\n          </table>\n        </td></tr>\n        <tr><td style=\"padding:8px 32px 28px;\">\n          <a href=\"mailto:${esc(d.email)}?subject=Re:%20${encodeURIComponent(d.subject)}\" style=\"display:inline-block;background:${brand};color:#ffffff;text-decoration:none;padding:12px 24px;border-radius:8px;font-size:14px;font-weight:600;\">Reply to ${esc(d.name)}</a>\n        </td></tr>\n        <tr><td style=\"padding:16px 32px;background:#f9fafb;border-top:1px solid #e8eaef;\">\n          <p style=\"margin:0;color:#9ca3af;font-size:12px;\">Umar Imran Portfolio \u00b7</p>\n        </td></tr>\n      </table>\n    </td></tr>\n  </table>\n</body>\n</html>`;\n\nconst customerHtml = `<!DOCTYPE html>\n<html>\n<head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"></head>\n<body style=\"margin:0;padding:0;background:#f4f5f7;font-family:Arial,Helvetica,sans-serif;\">\n  <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#f4f5f7;padding:32px 16px;\">\n    <tr><td align=\"center\">\n      <table width=\"600\" cellpadding=\"0\" cellspacing=\"0\" style=\"background:#ffffff;border-radius:12px;overflow:hidden;box-shadow:0 4px 24px rgba(52,58,158,0.08);\">\n        <tr><td style=\"background:${brand};padding:28px 32px;text-align:center;\">\n          <p style=\"margin:0;color:rgba(255,255,255,0.9);font-size:28px;font-weight:700;letter-spacing:-0.5px;\">Umar<span style=\"opacity:0.7;\">.</span></p>\n          <p style=\"margin:12px 0 0;color:rgba(255,255,255,0.85);font-size:13px;letter-spacing:0.5px;\">Full Stack Engineer &amp; Shopify Developer</p>\n        </td></tr>\n        <tr><td style=\"padding:32px;\">\n          <h1 style=\"margin:0 0 8px;color:#1a1d2e;font-size:22px;font-weight:700;\">Thanks for reaching out!</h1>\n          <p style=\"margin:0 0 24px;color:#4b5563;font-size:15px;line-height:1.6;\">Hi ${esc(d.name)},<br><br>I've received your message and will get back to you as soon as possible \u2014 usually within 24\u201348 hours.</p>\n          <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"border:2px solid ${brandLight};border-radius:10px;overflow:hidden;\">\n            <tr><td colspan=\"2\" style=\"background:${brandLight};padding:14px 20px;\">\n              <p style=\"margin:0;color:${brand};font-size:12px;font-weight:700;letter-spacing:0.5px;text-transform:uppercase;\">Your Message Summary</p>\n            </td></tr>\n            <tr>\n              <td style=\"padding:12px 16px;border-bottom:1px solid #e8eaef;color:#6b7280;font-size:13px;width:100px;vertical-align:top;\">Subject</td>\n              <td style=\"padding:12px 16px;border-bottom:1px solid #e8eaef;color:#1a1d2e;font-size:14px;font-weight:500;\">${esc(d.subject)}</td>\n            </tr>\n            <tr>\n              <td style=\"padding:12px 16px;color:#6b7280;font-size:13px;vertical-align:top;\">Message</td>\n              <td style=\"padding:12px 16px;color:#374151;font-size:14px;line-height:1.6;\">${esc(d.message)}</td>\n            </tr>\n          </table>\n          <div style=\"margin-top:28px;padding:20px;background:${brandLight};border-radius:8px;\">\n            <p style=\"margin:0 0 8px;color:${brand};font-size:13px;font-weight:700;\">What happens next?</p>\n            <p style=\"margin:0;color:#4b5563;font-size:14px;line-height:1.6;\">I'll review your inquiry and reply directly to <strong>${esc(d.email)}</strong>. For urgent projects, feel free to mention a timeline in your message.</p>\n          </div>\n        </td></tr>\n        <tr><td style=\"padding:20px 32px;background:#f9fafb;border-top:1px solid #e8eaef;text-align:center;\">\n          <p style=\"margin:0 0 4px;color:#6b7280;font-size:13px;\">Prefer a call? Schedule on my portfolio</p>\n          <a href=\"https://umar.asasosiatix.online/#contact\" style=\"color:${brand};font-size:14px;font-weight:600;text-decoration:none;\">umar.asasosiatix.online</a>\n          <p style=\"margin:16px 0 0;color:#9ca3af;font-size:11px;\">\u00a9 Umar Imran \u00b7 This is an automated confirmation</p>\n        </td></tr>\n      </table>\n    </td></tr>\n  </table>\n</body>\n</html>`;\n\nreturn [\n  {\n    json: {\n      name: d.name,\n      email: d.email,\n      subject: d.subject,\n      message: d.message,\n      timestamp: d.timestamp,\n      adminSubject: `New Contact \u2014 ${d.name}: ${d.subject}`,\n      adminHtml,\n      customerSubject: `We received your message \u2014 ${d.subject}`,\n      customerHtml,\n    },\n  },\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "b7ca5b9a-2f2f-4db9-ac40-8e31d16d0875",
      "name": "Send Admin Notification Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1536,
        -208
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "={{ $('Compose Emails for Admin & Visitor').first().json.adminHtml }}",
        "options": {},
        "subject": "={{ $('Compose Emails for Admin & Visitor').first().json.adminSubject }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "06c00647-adc5-427a-b992-c9ec48245e2d",
      "name": "Send Confirmation Email to Visitor",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1760,
        -208
      ],
      "parameters": {
        "sendTo": "={{ $('Compose Emails for Admin & Visitor').first().json.email }}",
        "message": "={{ $('Compose Emails for Admin & Visitor').first().json.customerHtml }}",
        "options": {},
        "subject": "={{ $('Compose Emails for Admin & Visitor').first().json.customerSubject }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "477206a5-1255-4160-bdd5-4ecdc0f13322",
      "name": "Acknowledge Form Submission Success",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        1984,
        -208
      ],
      "parameters": {
        "options": {
          "responseCode": 200
        },
        "respondWith": "json",
        "responseBody": "={{ { \"success\": true, \"message\": \"Contact emails sent\" } }}"
      },
      "typeVersion": 1.1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "6bfbdc72-b85f-45ba-b77b-e2f2384ffc79",
  "nodeGroups": [],
  "connections": {
    "When Form Submitted": {
      "main": [
        [
          {
            "node": "Set Contact Form Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Contact Form Data": {
      "main": [
        [
          {
            "node": "Compose Emails for Admin & Visitor",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Admin Notification Email": {
      "main": [
        [
          {
            "node": "Send Confirmation Email to Visitor",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Compose Emails for Admin & Visitor": {
      "main": [
        [
          {
            "node": "Send Admin Notification Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Confirmation Email to Visitor": {
      "main": [
        [
          {
            "node": "Acknowledge Form Submission Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}