This workflow corresponds to n8n.io template #16108 — we link there as the canonical source.
This workflow follows the Form Trigger → Gmail 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 →
{
"id": "SeQJypdV91un4n9d",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Client Onboarding",
"tags": [],
"nodes": [
{
"id": "500116c6-e395-48dc-b2b5-cdc1e038fad2",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
4064,
1984
],
"parameters": {
"width": 560,
"height": 960,
"content": "# Client Onboarding\n\n\n## How it works\n\n1. A client submits a form from your n8n form, website, Tally, Typeform, Google Form, or any webhook source. One config variable controls which AI provider runs: OpenAI (default) or Anthropic.\n2. Fields are normalized into a single clean object so nothing downstream ever breaks when you swap the intake source.\n3. The AI reads the submission and writes two things: a 3-sentence internal brief for your team, and a 2-sentence warm summary addressed directly to the client.\n4. The full record including the AI brief is logged to Google Sheets and a dedicated client folder is created in Google Drive automatically.\n5. Your team gets a Slack ping with the brief and a direct link to the Drive folder before the client email even lands.\n6. The client receives a polished welcome email with their AI-personalized summary and a booking link. 24 hours later, a soft follow-up goes out automatically.\n7. Optionally, a CEO/COO digest email fires after the follow-up; a clean summary of the new client with the Drive folder link. Toggle it on or off with one config variable.\n\n\n## Setup steps\n\n- [ ] Connect a Google Form or web form trigger as the intake source\n- [ ] Configure OpenAI API credentials and set the prompt for brief generation\n- [ ] Set up Google Sheets connection with the target spreadsheet and worksheet\n- [ ] Configure Google Drive connection and specify parent folder for new submissions\n- [ ] Set up Slack bot credentials and target channel for team notifications\n- [ ] Configure Gmail credentials and create email templates for welcome and follow-up messages\n- [ ] Verify the 24-hour wait duration matches your follow-up timing requirements\n\n\n## Customization\n\nYou can customize the AI prompt in the 'AI brief' node to generate different summaries. Modify the Slack message format in 'Team ping' for custom notifications. Adjust wait duration in 'Wait 24h' node if you need a different follow-up interval."
},
"typeVersion": 1
},
{
"id": "b405c547-3a06-4f02-9281-5cbfb444f935",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
4688,
1984
],
"parameters": {
"color": 7,
"width": 448,
"height": 384,
"content": "## Form intake and normalization\n\nCaptures form submissions and standardizes field names and values for downstream processing."
},
"typeVersion": 1
},
{
"id": "64b660cb-2827-49cb-a8fa-c75061a2de7a",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
5184,
1984
],
"parameters": {
"color": 7,
"width": 352,
"height": 384,
"content": "## AI brief generation\n\nUses OpenAI to generate an intelligent summary or brief from the normalized form data."
},
"typeVersion": 1
},
{
"id": "9640d3bf-cefb-4a5d-9da1-fe4e90b8e1a1",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
5584,
1984
],
"parameters": {
"color": 7,
"width": 480,
"height": 592,
"content": "## Data logging and storage\n\nMerges AI output with context data, logs to Google Sheets, and creates organized folder structure in Google Drive."
},
"typeVersion": 1
},
{
"id": "bcd4b7f2-6f09-49f7-8460-b5db01146c01",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
6112,
2272
],
"parameters": {
"color": 7,
"width": 976,
"height": 304,
"content": "## Team notifications and follow-ups\n\nNotifies team via Slack, sends welcome email to submitter, waits 24 hours, and sends follow-up communication."
},
"typeVersion": 1
},
{
"id": "d928374f-52f1-47b9-a796-f7d7754c5308",
"name": "When Form Submitted",
"type": "n8n-nodes-base.formTrigger",
"notes": "Swap for a Webhook node if using Tally, Typeform, or Google Form. Nothing downstream changes.",
"position": [
4752,
2160
],
"parameters": {
"path": "9be41c7b-f640-4bb3-a074-0df6adb414b7",
"options": {
"appendAttribution": false
},
"formTitle": "Work with us",
"formFields": {
"values": [
{
"fieldLabel": "Full name",
"requiredField": true
},
{
"fieldLabel": "Company name",
"requiredField": true
},
{
"fieldType": "email",
"fieldLabel": "Business email",
"requiredField": true
},
{
"fieldLabel": "Phone number"
},
{
"fieldType": "dropdown",
"fieldLabel": "Service you're interested in",
"fieldOptions": {
"values": [
{
"option": "Strategy & advisory"
},
{
"option": "Operations consulting"
},
{
"option": "Digital transformation"
},
{
"option": "Management consulting"
}
]
},
"requiredField": true
},
{
"fieldType": "textarea",
"fieldLabel": "Tell us about your challenge",
"requiredField": true
},
{
"fieldType": "dropdown",
"fieldLabel": "Budget range",
"fieldOptions": {
"values": [
{
"option": "Under $5,000"
},
{
"option": "$5,000 \u2013 $15,000"
},
{
"option": "$15,000 \u2013 $50,000"
},
{
"option": "Over $50,000"
}
]
}
},
{
"fieldType": "date",
"fieldLabel": "Ideal start date"
},
{
"fieldType": "textarea",
"fieldLabel": "Anything else we should know?"
}
]
},
"formDescription": "Tell us about your project. We'll review and be in touch within one business day."
},
"typeVersion": 2.1
},
{
"id": "d617f0ec-feb2-4a6c-9e05-b66a8223d7ab",
"name": "Normalize Form Fields",
"type": "n8n-nodes-base.set",
"notes": "Single translation layer. Add field aliases here when adding a new intake source. Downstream never changes.",
"position": [
4976,
2160
],
"parameters": {
"mode": "raw",
"options": {},
"jsonOutput": "={\n \"clientName\": \"{{ $json['Full name'] || $json['name'] || $json['full_name'] }}\",\n \"company\": \"{{ $json['Company name'] || $json['company'] || $json['company_name'] }}\",\n \"email\": \"{{ $json['Business email'] || $json['email'] }}\",\n \"phone\": \"{{ $json['Phone number'] || $json['phone'] || '' }}\",\n \"service\": \"{{ $json['Service you\\'re interested in'] || $json['service'] }}\",\n \"challenge\": \"{{ $json['Tell us about your challenge'] || $json['challenge'] || $json['message'] }}\",\n \"budget\": \"{{ $json['Budget range'] || $json['budget'] || 'Not specified' }}\",\n \"startDate\": \"{{ $json['Ideal start date'] || $json['start_date'] || 'Flexible' }}\",\n \"extra\": \"{{ $json['Anything else we should know?'] || $json['notes'] || '' }}\",\n \"submittedAt\":\"{{ $now.toFormat('yyyy-MM-dd HH:mm:ss') }} GMT+2\"\n}"
},
"typeVersion": 3.4
},
{
"id": "8607412c-6170-4e0a-9919-9c7fb1859a21",
"name": "Generate AI Brief",
"type": "@n8n/n8n-nodes-langchain.openAi",
"notes": "Swap for Anthropic node if preferred. Same prompt works.",
"position": [
5248,
2160
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini"
},
"options": {},
"messages": {
"values": [
{
"role": "system",
"content": "You are a senior client success specialist. Read the inquiry and return valid JSON only \u2014 no markdown, no extra text \u2014 with exactly two keys:\n\n\"brief\": 3 sentences for the internal team. What the client actually needs, which service fits, and the one thing to cover on the discovery call.\n\n\"clientSummary\": 2 sentences written to the client. Warm, plain language. Acknowledge their specific challenge. No jargon, no hype."
},
{
"content": "=Name: {{ $json.clientName }}\nCompany: {{ $json.company }}\nService: {{ $json.service }}\nChallenge: {{ $json.challenge }}\nBudget: {{ $json.budget }}\nStart date: {{ $json.startDate }}\nNotes: {{ $json.extra }}\n\nReturn JSON with keys: brief, clientSummary"
}
]
}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.4
},
{
"id": "a742af77-1577-4b3b-8dc4-2ba9dc70cc64",
"name": "Build Complete Context",
"type": "n8n-nodes-base.set",
"notes": "Combines AI output + client data into one object. All nodes below read from this.",
"position": [
5648,
2160
],
"parameters": {
"mode": "raw",
"options": {},
"jsonOutput": "={\n \"brief\": {{ JSON.parse($json.message.content).brief | json }},\n \"clientSummary\": {{ JSON.parse($json.message.content).clientSummary | json }},\n \"clientName\": \"{{ $('Normalize Form Fields').item.json.clientName }}\",\n \"company\": \"{{ $('Normalize Form Fields').item.json.company }}\",\n \"email\": \"{{ $('Normalize Form Fields').item.json.email }}\",\n \"phone\": \"{{ $('Normalize Form Fields').item.json.phone }}\",\n \"service\": \"{{ $('Normalize Form Fields').item.json.service }}\",\n \"challenge\": \"{{ $('Normalize Form Fields').item.json.challenge }}\",\n \"budget\": \"{{ $('Normalize Form Fields').item.json.budget }}\",\n \"startDate\": \"{{ $('Normalize Form Fields').item.json.startDate }}\",\n \"submittedAt\": \"{{ $('Normalize Form Fields').item.json.submittedAt }}\"\n}"
},
"typeVersion": 3.4
},
{
"id": "23c01063-7ca7-442f-b7c3-55903bbb82fc",
"name": "Append to Sheets",
"type": "n8n-nodes-base.googleSheets",
"notes": "One tab called Clients. Filter by Service column in the sheet itself. Sheet columns: Timestamp | Name | Company | Email | Phone | Service | Challenge | Budget | Start date | AI brief | Status",
"position": [
5888,
2160
],
"parameters": {
"columns": {
"value": {
"Name": "={{ $json.clientName }}",
"Email": "={{ $json.email }}",
"Phone": "={{ $json.phone }}",
"Budget": "={{ $json.budget }}",
"Status": "New",
"Company": "={{ $json.company }}",
"Service": "={{ $json.service }}",
"AI brief": "={{ $json.brief }}",
"Challenge": "={{ $json.challenge }}",
"Timestamp": "={{ $json.submittedAt }}",
"Start date": "={{ $json.startDate }}"
},
"mappingMode": "defineBelow"
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "Clients"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1n-m27GRmNU7YLW5yQ0hwIW3zQVI0lvCnw1o9-vmgatk",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1n-m27GRmNU7YLW5yQ0hwIW3zQVI0lvCnw1o9-vmgatk/edit?usp=drivesdk",
"cachedResultName": "The form"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.4
},
{
"id": "d5544109-f2ca-4349-8b5e-afab3ce3f168",
"name": "Create Drive Folder",
"type": "n8n-nodes-base.googleDrive",
"notes": "Set folderId to your master /Clients/ folder ID. Folder name = Company \u2014 Service.",
"position": [
5648,
2400
],
"parameters": {
"operation": "create"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "19260fea-6583-4d11-8da9-4e5df0d6ab7e",
"name": "Send Welcome Email",
"type": "n8n-nodes-base.gmail",
"notes": "Replace YOUR_BOOKING_LINK, [Your Name], [Company Name].",
"position": [
6416,
2400
],
"parameters": {
"sendTo": "={{ $('Build Complete Context').item.json.email }}",
"message": "=<!DOCTYPE html> <html> <head> <meta charset=\"utf-8\"> <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"> </head> <body style=\"font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; background-color: #f8f9fa; margin: 0; padding: 40px 10px; color: #2d3748; -webkit-font-smoothing: antialiased; line-height: 1.625;\"> <!-- Main Container Card --> <div style=\"max-width: 560px; margin: 0 auto; background-color: #ffffff; border: 1px solid #e2e8f0; border-radius: 12px; padding: 40px 32px; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);\"> <!-- Logo placeholder or Header --> <div style=\"margin-bottom: 32px; border-bottom: 1px solid #edf2f7; padding-bottom: 20px;\"> <span style=\"font-size: 18px; font-weight: 700; tracking: -0.02em; color: #1a202c;\">[Company Name]</span> </div> <!-- Greeting --> <p style=\"font-size: 16px; font-weight: 500; margin-top: 0; margin-bottom: 16px; color: #1a202c;\"> Hi {{ $('Build Complete Context').item.json.clientName.split(' ')[0] }}, </p> <!-- Context --> <p style=\"font-size: 15px; margin-bottom: 20px; color: #4a5568;\"> Thanks for reaching out. We've received your inquiry about <span style=\"font-weight: 600; color: #1a202c;\">{{ $('Build Complete Context').item.json.service }}</span> and our team has already been briefed. </p> <!-- AI/System Summary Block --> <div style=\"background-color: #f7fafc; border-left: 4px solid #3182ce; padding: 16px 20px; margin-bottom: 32px; border-radius: 0 8px 8px 0;\"> <p style=\"font-size: 14px; margin: 0; color: #4a5568; font-style: italic;\"> \"{{ $('Build Complete Context').item.json.clientSummary }}\" </p> </div> <!-- Section Title --> <p style=\"font-size: 15px; font-weight: 600; margin-bottom: 16px; color: #1a202c;\"> Here's what happens next: </p> <!-- Ordered List --> <ol style=\"font-size: 15px; padding-left: 20px; margin-top: 0; margin-bottom: 32px; color: #4a5568;\"> <li style=\"margin-bottom: 10px; padding-left: 4px;\">Book a 30-minute discovery call at your convenience.</li> <li style=\"margin-bottom: 10px; padding-left: 4px;\">We'll review your challenge and ask the right questions.</li> <li style=\"margin-bottom: 0; padding-left: 4px;\">Within 48 hours of the call, you'll receive a clear proposal.</li> </ol> <!-- CTA Button --> <div style=\"text-align: center; margin-bottom: 36px;\"> <a href=\"YOUR_BOOKING_LINK\" style=\"display: inline-block; background-color: #3182ce; color: #ffffff; text-decoration: none; padding: 14px 32px; border-radius: 8px; font-size: 15px; font-weight: 600; letter-spacing: -0.01em; box-shadow: 0 4px 6px -1px rgba(49, 130, 206, 0.2); transition: background-color 0.2s ease;\"> Book your discovery call </a> </div> <!-- Info Section --> <div style=\"border-top: 1px solid #edf2f7; padding-top: 24px; margin-bottom: 32px;\"> <p style=\"font-size: 14px; font-weight: 600; color: #718096; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 12px; margin-top: 0;\"> Good to know before the call </p> <ul style=\"font-size: 14.5px; color: #4a5568; padding-left: 20px; margin-top: 0; margin-bottom: 0;\"> <li style=\"margin-bottom: 8px;\">The call is completely free \u2014 no pitch, just listening.</li> <li style=\"margin-bottom: 8px;\">Bring whatever you have: a deck, a problem statement, or just a clear head.</li> <li style=\"margin-bottom: 0;\">We'll send over a brief agenda 24 hours before we meet.</li> </ul> </div> <!-- Closing --> <p style=\"font-size: 15px; margin-bottom: 24px; color: #4a5568;\"> If anything changes or you have questions before then, simply reply directly to this email. </p> <!-- Sign-off --> <table style=\"width: 100%; border-collapse: collapse;\"> <tr> <td> <p style=\"font-size: 15px; margin: 0 0 4px 0; color: #4a5568;\">Looking forward to it,</p> <p style=\"font-size: 15px; margin: 0; font-weight: 700; color: #1a202c;\">[Your Name]</p> <p style=\"font-size: 13px; margin: 2px 0 0 0; color: #718096; font-weight: 500;\">CEO \u00b7 [Company Name]</p> </td> </tr> </table> </div> </body> </html>",
"options": {
"appendAttribution": false
},
"subject": "=We've received your inquiry, {{ $('Build Complete Context').item.json.clientName.split(' ')[0] }}"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "6bc38eaa-6201-42c2-a7f6-c05e0044445c",
"name": "Wait 1 Day",
"type": "n8n-nodes-base.wait",
"position": [
6656,
2400
],
"parameters": {
"unit": "days",
"amount": 1
},
"typeVersion": 1.1
},
{
"id": "da25227f-2b3f-4cb5-ac18-2e4e75ff2aec",
"name": "Send Follow-up Email",
"type": "n8n-nodes-base.gmail",
"notes": "Replace YOUR_BOOKING_LINK, [Your Name].",
"position": [
6880,
2400
],
"parameters": {
"sendTo": "={{ $('Build Complete Context').item.json.email }}",
"message": "=<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n</head>\n<body style=\"font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; max-width: 560px; margin: 0 auto; padding: 32px 20px; color: #2d3748; -webkit-font-smoothing: antialiased; line-height: 1.6;\">\n\n <!-- Greeting -->\n <p style=\"font-size: 16px; font-weight: 500; margin-top: 0; margin-bottom: 20px; color: #1a202c;\">\n Hi {{ $('Build Complete Context').item.json.clientName.split(' ')[0] }},\n </p>\n\n <!-- Core Message -->\n <p style=\"font-size: 15px; margin-bottom: 16px; color: #4a5568;\">\n Just checking in \u2014 wanted to make sure my earlier email landed and the booking link worked.\n </p>\n\n <p style=\"font-size: 15px; margin-bottom: 28px; color: #4a5568;\">\n If scheduling is tricky this week, no problem at all. Feel free to grab any future slot that aligns with your calendar.\n </p>\n\n <!-- Clean, Accessible Call to Action -->\n <div style=\"margin-bottom: 28px;\">\n <a href=\"YOUR_BOOKING_LINK\" style=\"display: inline-block; background-color: #1a202c; color: #ffffff; text-decoration: none; padding: 12px 24px; border-radius: 6px; font-size: 14px; font-weight: 600; letter-spacing: -0.01em; box-shadow: 0 2px 4px rgba(0,0,0,0.05);\">\n Book your discovery call\n </a>\n </div>\n\n <!-- Alternative Option -->\n <p style=\"font-size: 14.5px; color: #718096; margin-bottom: 32px;\">\n Or, simply reply directly to this thread \u2014 I am happy to coordinate a time over email.\n </p>\n\n <!-- Sign-off Block -->\n <table style=\"width: 100%; border-collapse: collapse;\">\n <tr>\n <td>\n <p style=\"font-size: 15px; margin: 0 0 4px 0; color: #4a5568;\">Cheers,</p>\n <p style=\"font-size: 15px; margin: 0; font-weight: 700; color: #1a202c;\">[Your Name]</p>\n <p style=\"font-size: 13px; margin: 2px 0 0 0; color: #718096;\">CEO \u00b7 [Company Name]</p>\n </td>\n </tr>\n </table>\n\n</body>\n</html>\n",
"options": {
"appendAttribution": false
},
"subject": "=Quick check-in, {{ $('Build Complete Context').item.json.clientName.split(' ')[0] }}"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "c67bea32-a247-4b3a-a6a5-b577e265ec64",
"name": "Post to Slack Channel",
"type": "n8n-nodes-base.slack",
"notes": "Replace channelId. Message includes AI brief + Drive folder link.",
"position": [
6160,
2400
],
"parameters": {
"text": "=*New client inquiry*\n\n*Name:* {{ $('Build Complete Context').item.json.clientName }}\n*Company:* {{ $('Build Complete Context').item.json.company }}\n*Service:* {{ $('Build Complete Context').item.json.service }}\n*Budget:* {{ $('Build Complete Context').item.json.budget }}\n*Start:* {{ $('Build Complete Context').item.json.startDate }}\n\n*Brief:*\n{{ $('Build Complete Context').item.json.brief }}\n\n*Drive:* {{ $json.webViewLink }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "YOUR_CHANNEL_ID"
},
"otherOptions": {
"botProfile": {
"imageValues": {
"icon_emoji": "incoming_envelope",
"profilePhotoType": "emoji"
}
},
"includeLinkToWorkflow": false
},
"authentication": "oAuth2"
},
"typeVersion": 2.2
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"executionOrder": "v1"
},
"versionId": "d2e6e028-23bb-4a14-aa8f-c84452eebc92",
"connections": {
"Wait 1 Day": {
"main": [
[
{
"node": "Send Follow-up Email",
"type": "main",
"index": 0
}
]
]
},
"Append to Sheets": {
"main": [
[
{
"node": "Create Drive Folder",
"type": "main",
"index": 0
}
]
]
},
"Generate AI Brief": {
"main": [
[
{
"node": "Build Complete Context",
"type": "main",
"index": 0
}
]
]
},
"Send Welcome Email": {
"main": [
[
{
"node": "Wait 1 Day",
"type": "main",
"index": 0
}
]
]
},
"Create Drive Folder": {
"main": [
[
{
"node": "Post to Slack Channel",
"type": "main",
"index": 0
}
]
]
},
"When Form Submitted": {
"main": [
[
{
"node": "Normalize Form Fields",
"type": "main",
"index": 0
}
]
]
},
"Normalize Form Fields": {
"main": [
[
{
"node": "Generate AI Brief",
"type": "main",
"index": 0
}
]
]
},
"Post to Slack Channel": {
"main": [
[
{
"node": "Send Welcome Email",
"type": "main",
"index": 0
}
]
]
},
"Build Complete Context": {
"main": [
[
{
"node": "Append to Sheets",
"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.
gmailOAuth2googleDriveOAuth2ApigoogleSheetsOAuth2ApiopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow captures client inquiries via an n8n Form, uses OpenAI to generate an internal brief and client-facing summary, logs the submission to Google Sheets, creates a Google Drive folder, notifies your team in Slack, and sends welcome and follow-up emails through Gmail.…
Source: https://n8n.io/workflows/16108/ — 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.
An n8n-based automation that generates client proposals from a form, lets you review everything in one place, and sends the proposal only when you approve it.
Overview
Small teams, solo operators, and security-conscious individuals who receive email attachments from external senders. Useful for freelancers, agencies, HR teams, and anyone handling CVs, invoices, or d
Reimbursements used to be a headache.
This n8n workflow streamlines the entire process of turning your written articles into engaging audio, distributing them, and tracking their performance. Here's a step-by-step breakdown: New Content D