This workflow corresponds to n8n.io template #16650 — we link there as the canonical source.
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 →
{
"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, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\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 & 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
}
]
]
}
}
}
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.
gmailOAuth2
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow receives portfolio contact form submissions via a webhook, normalizes the fields, generates branded HTML emails, and uses Gmail to send an admin notification plus an automated confirmation to the visitor before returning a success JSON response to the website.…
Source: https://n8n.io/workflows/16650/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow receives new signup events, enriches each contact with Twain (and optionally a LinkedIn lookup), drafts a personalized welcome email in Gmail, and posts review-ready previews to Slack, w
Receive orders via webhook with automatic payment verification, stock checking, inventory reservation, shipping label generation, confirmation emails, and Slack notifications.
OTP Verification System. Uses googleSheets, gmail. Webhook trigger; 23 nodes.
A comprehensive n8n workflow template for automating e-commerce return processes with fraud prevention and professional document generation. E-commerce businesses preventing fraudulent returns Custome
Transform your visitor management process with this fully automated, enterprise-grade workflow. The Verified Visitor Pass Generator eliminates manual data entry, prevents fake registrations through em