This workflow corresponds to n8n.io template #11731 — we link there as the canonical source.
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 →
{
"id": "",
"meta": {
"templateCredsSetupCompleted": false
},
"name": "AI Proposal Generator",
"tags": [],
"nodes": [
{
"id": "247a68af-aa45-45b8-9688-9f000779377f",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
-2272,
576
],
"parameters": {
"path": "proposal-generator",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2.1
},
{
"id": "a8171df0-a161-46d9-8fdb-5389c736c598",
"name": "HTML to PDF",
"type": "n8n-nodes-htmlcsstopdf.htmlcsstopdf",
"position": [
-944,
576
],
"parameters": {
"html_content": "={{ $json.html }}",
"output_format": "file",
"output_filename": "data"
},
"credentials": {
"htmlcsstopdfApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "cc66c2a0-721a-468e-879f-5c127fd43054",
"name": "Send Email with PDF Attachment",
"type": "n8n-nodes-base.gmail",
"position": [
-640,
352
],
"parameters": {
"sendTo": "={{ $('Webhook').item.json.body.client_email }}",
"message": "=<div style=\"font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; color: #1f2937; line-height: 1.7; max-width: 600px; margin: 0 auto; background: #ffffff;\">\n \n <!-- Header Banner -->\n <div style=\"background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 40px 30px; text-align: center; border-radius: 12px 12px 0 0;\">\n <h1 style=\"color: #ffffff; margin: 0; font-size: 28px; font-weight: 700; letter-spacing: -0.5px;\">\n \ud83d\udccb Your Project Proposal\n </h1>\n <p style=\"color: #e0e7ff; margin: 10px 0 0 0; font-size: 15px;\">\n Tailored exclusively for {{ $('Webhook').item.json.body.client_name }}\n </p>\n </div>\n\n <!-- Main Content -->\n <div style=\"padding: 40px 30px; background: #ffffff;\">\n \n <p style=\"font-size: 16px; margin-bottom: 20px; color: #374151;\">\n Dear <strong style=\"color: #667eea;\">{{ $('Webhook').item.json.body.client_name }}</strong>,\n </p>\n\n <p style=\"font-size: 15px; margin-bottom: 20px; color: #4b5563;\">\n Thank you for considering us for your <strong style=\"color: #764ba2;\">{{ $('Webhook').item.json.body.project_type }}</strong> project. We're excited about the opportunity to work together!\n </p>\n\n <p style=\"font-size: 15px; margin-bottom: 25px; color: #4b5563;\">\n I've prepared a comprehensive proposal that outlines our strategic approach, detailed timeline, and transparent investment breakdown. <strong>Please find the attached PDF</strong> for your review.\n </p>\n\n <!-- Quick Summary Box -->\n <div style=\"background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%); padding: 25px; border-radius: 12px; margin: 30px 0; border-left: 5px solid #667eea; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);\">\n <p style=\"margin: 0 0 15px 0; font-weight: 700; color: #1e40af; font-size: 17px; display: flex; align-items: center;\">\n <span style=\"font-size: 20px; margin-right: 8px;\">\u26a1</span> Quick Overview\n </p>\n <table style=\"width: 100%; border-collapse: collapse;\">\n <tr>\n <td style=\"padding: 8px 0; color: #374151; font-size: 14px;\">\n <strong style=\"color: #1e40af;\">\ud83d\udce6 Project:</strong>\n </td>\n <td style=\"padding: 8px 0; color: #1f2937; font-size: 14px; text-align: right;\">\n {{ $('Webhook').item.json.body.project_type }}\n </td>\n </tr>\n <tr>\n <td style=\"padding: 8px 0; color: #374151; font-size: 14px;\">\n <strong style=\"color: #1e40af;\">\u23f1\ufe0f Timeline:</strong>\n </td>\n <td style=\"padding: 8px 0; color: #1f2937; font-size: 14px; text-align: right;\">\n {{ $('Extract AI Content').item.json.delivery_timeline }}\n </td>\n </tr>\n <tr>\n <td style=\"padding: 8px 0; color: #374151; font-size: 14px;\">\n <strong style=\"color: #1e40af;\">\ud83d\udcb0 Investment:</strong>\n </td>\n <td style=\"padding: 8px 0; color: #1f2937; font-size: 14px; text-align: right;\">\n <span style=\"font-weight: 700; color: #667eea;\">${{ $('Extract AI Content').item.json.base_price }} - ${{ $('Extract AI Content').item.json.max_price }}</span>\n </td>\n </tr>\n <tr>\n <td style=\"padding: 8px 0; color: #374151; font-size: 14px; border-top: 1px solid #bfdbfe; padding-top: 12px;\">\n <strong style=\"color: #1e40af;\">\ud83d\udcc4 Proposal #:</strong>\n </td>\n <td style=\"padding: 8px 0; color: #1f2937; font-size: 14px; text-align: right; border-top: 1px solid #bfdbfe; padding-top: 12px;\">\n <code style=\"background: #e0f2fe; padding: 4px 8px; border-radius: 4px; font-size: 13px; color: #0369a1;\">{{ $('Extract AI Content').item.json.proposal_number }}</code>\n </td>\n </tr>\n </table>\n </div>\n\n <!-- Call to Action -->\n <div style=\"background: #f9fafb; padding: 20px; border-radius: 10px; margin: 25px 0; border: 2px dashed #d1d5db;\">\n <p style=\"margin: 0; color: #4b5563; font-size: 14px; text-align: center;\">\n \ud83d\udcac <strong>Have questions or need adjustments?</strong><br>\n <span style=\"color: #6b7280;\">I'm here to help! Feel free to reach out anytime.</span>\n </p>\n </div>\n\n <p style=\"font-size: 15px; margin: 25px 0 10px 0; color: #374151;\">\n I look forward to the opportunity to bring your vision to life and create something exceptional together.\n </p>\n\n <!-- Signature -->\n <div style=\"margin-top: 40px; padding-top: 25px; border-top: 2px solid #e5e7eb;\">\n <p style=\"margin: 0; color: #6b7280; font-size: 14px;\">\n Best regards,\n </p>\n <p style=\"margin: 10px 0 5px 0; color: #1f2937; font-size: 16px; font-weight: 700;\">\n Your Name\n </p>\n <p style=\"margin: 0; color: #6b7280; font-size: 14px;\">\n Your Title | Your Company<br>\n \ud83d\udce7 your.email@company.com | \ud83d\udcf1 +1 (555) 123-4567\n </p>\n </div>\n\n </div>\n\n <!-- Footer -->\n <div style=\"background: #f9fafb; padding: 20px 30px; text-align: center; border-radius: 0 0 12px 12px; border-top: 1px solid #e5e7eb;\">\n <p style=\"margin: 0; color: #9ca3af; font-size: 12px;\">\n This proposal is valid for 30 days from the date of issue.\n </p>\n </div>\n\n</div>",
"options": {
"attachmentsUi": {
"attachmentsBinary": [
{}
]
}
},
"subject": "=Your Project Proposal - {{ $('Webhook').item.json.body.project_type }}"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "7179c5ac-4341-42bb-8e69-d10feaa45637",
"name": "Upload file",
"type": "n8n-nodes-base.googleDrive",
"position": [
-640,
576
],
"parameters": {
"name": "=Proposal_{{ $('Webhook').item.json.body.client_name.replace(/\\s+/g, '_') }}_{{ $('Extract AI Content').item.json.proposal_number }}.pdf",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "root",
"cachedResultName": "YOUR_FOLDER_NAME"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "041e65a0-9879-48b4-9d6a-40ec9935c3f1",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"position": [
-144,
560
],
"parameters": {
"numberInputs": 3
},
"typeVersion": 3.2
},
{
"id": "f89b8bad-4227-4234-9a39-d9a61d4d1976",
"name": "Define Pricing & Timeline Logic",
"type": "n8n-nodes-base.set",
"position": [
-2016,
576
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "b68d5f93-d3b8-4971-b45d-3e12d0f5f320",
"name": "base_price",
"type": "string",
"value": "={{ $json.body.budget_range.split('-')[0] }}"
},
{
"id": "21cbcb19-3ee2-45ca-99fb-bbebb8205f90",
"name": "max_price",
"type": "string",
"value": "={{ $json.body.budget_range.split('-')[1] }}"
},
{
"id": "9e1b820b-5e1a-420d-957e-35e5732d9865",
"name": "delivery_timeline",
"type": "string",
"value": "={{ $json.body.timeline_weeks }} weeks"
},
{
"id": "0875fc1a-ecdf-4999-bd6c-afcef2d4e21f",
"name": "start_date",
"type": "string",
"value": "={{ $now.plus(1, 'week').toFormat('MMMM dd, yyyy') }}"
},
{
"id": "9f2d27cd-eefe-424c-9130-4e1d73d1aecc",
"name": "end_date",
"type": "string",
"value": "={{ $now.plus(parseInt($json.body.timeline_weeks) + 1, 'weeks').toFormat('MMMM dd, yyyy') }}"
},
{
"id": "8a659d14-cca6-421c-9795-9777b6e8b2cb",
"name": "proposal_number",
"type": "string",
"value": "=PROP-{{ $now.toFormat('yyyyMMdd') }}-{{ Math.floor(Math.random() * 1000) }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "036fbcf9-920e-42f4-9399-29e677df46e0",
"name": "Generate Proposal Content",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
-1744,
576
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4",
"cachedResultName": "GPT-4"
},
"options": {
"temperature": 0.7
},
"responses": {
"values": [
{
"role": "system",
"content": "=You are an expert freelance proposal writer with 10+ years of experience. Your proposals are known for being:\n- Professional and client-focused\n- Specific to client needs (never generic)\n- Clear and persuasive without being salesy\n- Well-structured with actionable details\n\nWrite proposals that demonstrate deep understanding of the client's problem and show how you'll solve it. Use confident, warm language. Focus on value and outcomes, not just deliverables.\n\nFormat your response with clear section headers:\n## Executive Summary\n## Project Scope\n## Methodology\n## Timeline & Milestones\n## Investment Breakdown\n## Why Choose Us\n\nKeep each section concise but comprehensive. Use bullet points where appropriate."
},
{
"content": "=Create a compelling proposal for this client:\n\nCLIENT INFORMATION:\n- Company Name: {{ $('Webhook').item.json.body.client_name }}\n- Project Type: {{ $('Webhook').item.json.body.project_type }}\n- Project Description: {{ $('Webhook').item.json.body.project_description }}\n\nPROJECT PARAMETERS:\n- Budget Range: ${{ $json.base_price }} - ${{ $json.max_price }}\n- Timeline: {{ $json.delivery_timeline }}\n- Start Date: {{ $json.start_date }}\n- Completion Date: {{ $json.end_date }}\n\nGenerate a complete, client-ready proposal that addresses their specific needs. Make it persuasive and show deep understanding of their project requirements."
}
]
},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "acbf20c9-ba6f-4082-a720-fdb7b0fd5d50",
"name": "Extract AI Content",
"type": "n8n-nodes-base.set",
"position": [
-1424,
576
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "d7ce2242-2431-4016-80f1-d2deb7d836c2",
"name": "ai_content",
"type": "string",
"value": "={{ $json.output[0].content[0].text }} "
},
{
"id": "f2c02cb3-2ff9-4d01-8fad-b79b2e10652d",
"name": "=client_name",
"type": "string",
"value": "={{ $('Webhook').item.json.body.client_name }}"
},
{
"id": "ef02d2fa-dc18-4029-88e0-231b45c620b1",
"name": "client_email",
"type": "string",
"value": "={{ $('Webhook').item.json.body.client_email }}"
},
{
"id": "f90ee3bf-5c9c-43ea-b26f-5a7f4b0831b2",
"name": "project_type",
"type": "string",
"value": "={{ $('Webhook').item.json.body.project_type }}"
},
{
"id": "83ba9a59-1ff3-4a8a-8c8a-99584d29e2c9",
"name": "proposal_number",
"type": "string",
"value": "={{ $('Define Pricing & Timeline Logic').item.json.proposal_number }}"
},
{
"id": "a82a1ac0-bad7-45d1-b748-778da01e2d9e",
"name": "base_price",
"type": "string",
"value": "={{ $('Define Pricing & Timeline Logic').item.json.base_price }}"
},
{
"id": "359904ae-172c-45b0-b0b9-1ec47b0eb26d",
"name": "max_price",
"type": "string",
"value": "={{ $('Define Pricing & Timeline Logic').item.json.max_price }}"
},
{
"id": "a257dfc1-a910-4e2e-95c3-160c892636fc",
"name": "delivery_timeline",
"type": "string",
"value": "={{ $('Define Pricing & Timeline Logic').item.json.delivery_timeline }}"
},
{
"id": "702061e5-c633-4cf5-9615-554f47898713",
"name": "start_date",
"type": "string",
"value": "={{ $('Define Pricing & Timeline Logic').item.json.start_date }}"
},
{
"id": "50fc62af-920d-485d-aa9d-8902f69ec89f",
"name": "end_date",
"type": "string",
"value": "={{ $('Define Pricing & Timeline Logic').item.json.end_date }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "723ee195-bae3-47c7-8e2b-35a0c827f1ac",
"name": "Generates HTML",
"type": "n8n-nodes-base.code",
"position": [
-1184,
576
],
"parameters": {
"jsCode": "const clientName = $input.first().json.client_name;\nconst projectType = $input.first().json.project_type;\nconst proposalNumber = $input.first().json.proposal_number;\nconst basePrice = $input.first().json.base_price;\nconst maxPrice = $input.first().json.max_price;\nconst timeline = $input.first().json.delivery_timeline;\nconst startDate = $input.first().json.start_date;\nconst endDate = $input.first().json.end_date;\nconst clientEmail = $input.first().json.client_email;\nconst aiContent = $input.first().json.ai_content;\n\n// Function to convert markdown-style content to HTML\nfunction convertToHTML(text) {\n // Split into sections by ## headers\n let html = text;\n \n // Convert ## headers to h2 tags\n html = html.replace(/## ([^\\n]+)/g, '<h2>$1</h2>');\n \n // Convert numbered lists (1. 2. 3. etc)\n html = html.replace(/(\\d+)\\.\\s\\*\\*([^*]+)\\*\\*:\\s([^\\n]+)/g, '<li><strong>$2</strong>: $3</li>');\n \n // Convert bullet points (- text)\n html = html.replace(/^- (.+)$/gm, '<li>$1</li>');\n \n // Wrap consecutive <li> in <ul>\n html = html.replace(/(<li>.*<\\/li>\\n?)+/gs, '<ul>$&</ul>');\n \n // Convert **bold** to <strong>\n html = html.replace(/\\*\\*([^*]+)\\*\\*/g, '<strong>$1</strong>');\n \n // Convert double line breaks to paragraphs\n html = html.split('\\n\\n').map(para => {\n // Don't wrap h2 or ul in p tags\n if (para.trim().startsWith('<h2>') || para.trim().startsWith('<ul>')) {\n return para;\n }\n // Don't wrap empty strings\n if (para.trim() === '') {\n return '';\n }\n return `<p>${para.replace(/\\n/g, '<br>')}</p>`;\n }).join('\\n');\n \n return html;\n}\n\nconst formattedContent = convertToHTML(aiContent);\n\nconst html = `\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body {\n font-family: 'Helvetica Neue', Arial, sans-serif;\n line-height: 1.8;\n color: #333;\n background: white;\n }\n .container {\n max-width: 800px;\n margin: 0 auto;\n padding: 60px 40px;\n }\n .header {\n border-bottom: 4px solid #2563eb;\n padding-bottom: 30px;\n margin-bottom: 40px;\n }\n .header h1 {\n font-size: 36px;\n color: #1e40af;\n margin-bottom: 10px;\n font-weight: 700;\n }\n .header .subtitle {\n font-size: 18px;\n color: #6b7280;\n font-weight: 400;\n }\n .proposal-number {\n background: #eff6ff;\n padding: 15px 20px;\n border-radius: 8px;\n margin: 30px 0;\n font-weight: 600;\n color: #1e40af;\n font-size: 14px;\n }\n .info-box {\n background: #f9fafb;\n padding: 25px;\n border-radius: 8px;\n border-left: 4px solid #2563eb;\n margin: 25px 0;\n line-height: 1.8;\n }\n .info-box strong {\n color: #1e40af;\n font-weight: 600;\n }\n .content {\n margin-top: 30px;\n }\n .content h2 {\n font-size: 22px;\n color: #1e40af;\n margin-bottom: 15px;\n margin-top: 35px;\n border-left: 4px solid #2563eb;\n padding-left: 15px;\n font-weight: 700;\n }\n .content h2:first-child {\n margin-top: 0;\n }\n .content p {\n margin-bottom: 15px;\n text-align: justify;\n line-height: 1.8;\n color: #374151;\n }\n .content ul {\n margin-left: 0;\n margin-bottom: 20px;\n list-style: none;\n padding-left: 0;\n }\n .content li {\n margin-bottom: 10px;\n padding-left: 25px;\n position: relative;\n line-height: 1.8;\n color: #374151;\n }\n .content li:before {\n content: \"\u2022\";\n color: #2563eb;\n font-weight: bold;\n font-size: 20px;\n position: absolute;\n left: 5px;\n }\n .content strong {\n color: #1e40af;\n font-weight: 600;\n }\n .footer {\n margin-top: 60px;\n padding-top: 30px;\n border-top: 2px solid #e5e7eb;\n text-align: center;\n color: #6b7280;\n font-size: 13px;\n line-height: 1.8;\n }\n .footer p {\n margin-bottom: 8px;\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"header\">\n <h1>Project Proposal</h1>\n <p class=\"subtitle\">Prepared for ${clientName}</p>\n </div>\n\n <div class=\"proposal-number\">\n Proposal #: ${proposalNumber} | Date: ${new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })}\n </div>\n\n <div class=\"info-box\">\n <strong>Project:</strong> ${projectType}<br>\n <strong>Timeline:</strong> ${timeline}<br>\n <strong>Start Date:</strong> ${startDate}<br>\n <strong>Estimated Completion:</strong> ${endDate}\n </div>\n\n <div class=\"content\">\n ${formattedContent}\n </div>\n\n <div class=\"footer\">\n <p>This proposal is valid for 30 days from the date of issue.</p>\n <p>Thank you for considering our services. We look forward to working with you.</p>\n </div>\n </div>\n</body>\n</html>\n`;\n\nreturn [{ \n json: { \n html, \n client_name: clientName, \n client_email: clientEmail, \n proposal_number: proposalNumber \n } \n}];"
},
"typeVersion": 2
},
{
"id": "2595a3dc-a03b-4ace-95d6-6dede2e65cc8",
"name": "Send a message",
"type": "n8n-nodes-base.slack",
"position": [
-640,
784
],
"parameters": {
"text": "=\ud83c\udf89 *New Proposal Generated & Sent Successfully!*\n\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\ud83d\udccb *PROPOSAL DETAILS*\n\n- *Proposal Number:* `{{ $('Extract AI Content').item.json.proposal_number }}`\n- *Client:* {{ $('Webhook').item.json.body.client_name }}\n- *Project:* {{ $('Webhook').item.json.body.project_type }}\n- *Budget Range:* ${{ $('Extract AI Content').item.json.base_price }} - ${{ $('Extract AI Content').item.json.max_price }}\n- *Timeline:* {{ $('Extract AI Content').item.json.delivery_timeline }}\n- *Start Date:* {{ $('Extract AI Content').item.json.start_date }}\n- *Completion:* {{ $('Extract AI Content').item.json.end_date }}\n\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\ud83d\udce7 *CLIENT INFO*\n\n- *Email:* {{ $('Webhook').item.json.body.client_email }}\n- *Status:* \u2705 Email sent with PDF attachment\n\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\u23f0 *Next Steps:* Follow up with client in 2-3 business days",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "YOUR_SLACK_CHANNEL_ID",
"cachedResultName": "slack-channel-name"
},
"otherOptions": {}
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.4
},
{
"id": "aa0a2ec9-b512-48ce-99e4-13e061174d36",
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
64,
576
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": "={\n \"success\": true,\n \"message\": \"Proposal generated and sent successfully!\",\n \"data\": {\n \"proposal_number\": \"{{ $('Extract AI Content').item.json.proposal_number }}\",\n \"client_name\": \"{{ $('Webhook').item.json.body.client_name }}\",\n \"project_type\": \"{{ $('Webhook').item.json.body.project_type }}\",\n \"budget_range\": \"${{ $('Extract AI Content').item.json.base_price }} - ${{ $('Extract AI Content').item.json.max_price }}\",\n \"timeline\": \"{{ $('Extract AI Content').item.json.delivery_timeline }}\",\n \"email_sent_to\": \"{{ $('Webhook').item.json.body.client_email }}\",\n \"timestamp\": \"{{ $now.toISO() }}\"\n },\n \"status\": {\n \"pdf_generated\": true,\n \"drive_uploaded\": true,\n \"email_sent\": true,\n \"slack_notified\": true\n }\n}"
},
"typeVersion": 1.5
},
{
"id": "a02ccb6a-937a-4bf8-9300-9f881d8659d3",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2688,
-112
],
"parameters": {
"width": 336,
"height": 880,
"content": "### How It Works\nThis workflow automates proposal generation for freelancers and agencies. When a client submits their project details through the webhook, the workflow processes their budget range and timeline, then uses OpenAI GPT-4 to generate a customized, professional proposal with sections covering executive summary, scope, methodology, timeline, and pricing. The AI-generated content is formatted into a branded HTML template, converted to PDF, and delivered via three channels: emailed directly to the client with the PDF attached, uploaded to Google Drive for your records, and posted to Slack to notify your team. The entire process completes in seconds, ensuring clients receive polished proposals instantly while your team stays informed.\n\n### Setup Steps\n1. Connect required credentials: OpenAI API, HTML-to-PDF service, Gmail, Google Drive, and Slack.\n2. Update the email template with your company name, contact details, and branding.\n3. Configure the Google Drive folder ID where proposals should be stored.\n4. Set your Slack channel for proposal notifications.\n5. Copy the webhook URL and integrate it into your contact form or CRM.\n6. Test with sample client data to verify all integrations work correctly.\n\n### Customization\n- Modify the OpenAI system prompt to match your writing style and industry focus.\n- Adjust the HTML template styling to match your brand colors and logo.\n- Customize email subject lines and body content for your business tone."
},
"typeVersion": 1
},
{
"id": "37178ef0-bf1d-47f5-b35a-c1dd24a73683",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2304,
464
],
"parameters": {
"color": 7,
"width": 448,
"height": 288,
"content": "## Input & Configuration\nReceives client project details via webhook and calculates pricing, timeline, and proposal metadata."
},
"typeVersion": 1
},
{
"id": "d3c4c0e9-0966-4f86-b045-6d1b7145a57a",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1776,
480
],
"parameters": {
"color": 7,
"width": 736,
"height": 272,
"content": "## AI Content Generation\nUses OpenAI GPT-4 to write a customized proposal, then formats it into a professional HTML document."
},
"typeVersion": 1
},
{
"id": "5454ef8b-e2c8-4258-bdd8-46e893013fde",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-976,
256
],
"parameters": {
"color": 7,
"width": 480,
"height": 688,
"content": "## PDF Creation & Distribution\nConverts HTML to PDF and delivers via email, Google Drive storage, and Slack team notification."
},
"typeVersion": 1
},
{
"id": "17737ea2-7eee-4ac8-acfa-30eddefe717d",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
-240,
464
],
"parameters": {
"color": 7,
"width": 464,
"height": 288,
"content": "## Completion\nMerges all execution paths and returns a structured JSON success response to the caller."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "",
"connections": {
"Merge": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
},
"Webhook": {
"main": [
[
{
"node": "Define Pricing & Timeline Logic",
"type": "main",
"index": 0
}
]
]
},
"HTML to PDF": {
"main": [
[
{
"node": "Send Email with PDF Attachment",
"type": "main",
"index": 0
},
{
"node": "Send a message",
"type": "main",
"index": 0
},
{
"node": "Upload file",
"type": "main",
"index": 0
}
]
]
},
"Upload file": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"Generates HTML": {
"main": [
[
{
"node": "HTML to PDF",
"type": "main",
"index": 0
}
]
]
},
"Send a message": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 2
}
]
]
},
"Extract AI Content": {
"main": [
[
{
"node": "Generates HTML",
"type": "main",
"index": 0
}
]
]
},
"Generate Proposal Content": {
"main": [
[
{
"node": "Extract AI Content",
"type": "main",
"index": 0
}
]
]
},
"Send Email with PDF Attachment": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"Define Pricing & Timeline Logic": {
"main": [
[
{
"node": "Generate Proposal Content",
"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.
gmailOAuth2googleDriveOAuth2ApihtmlcsstopdfApiopenAiApislackApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Creating client proposals manually is slow, repetitive, and often inconsistent. This AI-powered workflow transforms proposal creation from a manual task into a fully automated, professional process.
Source: https://n8n.io/workflows/11731/ — 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.
Automate incident reporting from detection to delivery with AI-driven analysis and professional documentation.
Transform customer feedback into actionable insights automatically with AI analysis, professional PDF reports, personalized emails, and real-time team notifications. Overview Features Demo Prerequisit
Transform your webinar registrations from basic form submissions into a verified, personalized, and premium attendee experience.
This system meticulously guides each lead through a fully automated journey, from initial contact to a personalized follow-up and CRM integration.
Creating job offer letters manually is time-consuming, error-prone, and difficult to scale. This AI-powered workflow automates the entire job offer letter process — from validating candidate emails to