This workflow follows the Google Drive → OpenAI Chat 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 →
{
"name": "proposal-assistant-openai",
"nodes": [
{
"id": "e4f5a6b7-0001-4000-8000-000000000001",
"name": "Webhook Trigger",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
0,
300
],
"parameters": {
"httpMethod": "POST",
"path": "proposal-assistant",
"responseMode": "onReceived",
"options": {}
}
},
{
"id": "e4f5a6b7-0002-4000-8000-000000000002",
"name": "Generate Proposal",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1,
"position": [
220,
300
],
"parameters": {
"model": "gpt-4o",
"messages": {
"values": [
{
"role": "system",
"content": "You are a professional proposal writer for a consulting or freelance services business. Generate a clean, structured proposal from the discovery notes provided. Format the output as a professional document with these sections:\n\n1. Executive Summary (2-3 sentences)\n2. Problem Statement (what the client is dealing with)\n3. Proposed Solution (what you will deliver)\n4. Scope of Work (bulleted deliverables)\n5. Timeline (phases with durations)\n6. Investment (price range or fixed price)\n7. Next Steps (single clear call to action)\n\nWrite in second person. No em-dashes. Keep total length under 500 words."
},
{
"role": "user",
"content": "Client name: {{ $json.client_name }}\nCompany: {{ $json.client_company }}\nContact role: {{ $json.contact_role }}\nBudget range: {{ $json.budget_range }}\nTimeline expectation: {{ $json.timeline }}\n\nDiscovery notes:\n{{ $json.discovery_notes }}"
}
]
}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"id": "e4f5a6b7-0003-4000-8000-000000000003",
"name": "Parse Proposal",
"type": "n8n-nodes-base.set",
"typeVersion": 3,
"position": [
440,
300
],
"parameters": {
"mode": "manual",
"fields": {
"values": [
{
"name": "proposal_text",
"type": "expression",
"value": "={{ $json.message.content }}"
},
{
"name": "client_name",
"type": "expression",
"value": "={{ $('Webhook Trigger').item.json.client_name }}"
},
{
"name": "client_company",
"type": "expression",
"value": "={{ $('Webhook Trigger').item.json.client_company }}"
},
{
"name": "budget_range",
"type": "expression",
"value": "={{ $('Webhook Trigger').item.json.budget_range }}"
},
{
"name": "approver_email",
"type": "expression",
"value": "={{ $('Webhook Trigger').item.json.approver_email }}"
}
]
}
}
},
{
"id": "e4f5a6b7-0004-4000-8000-000000000004",
"name": "Save to Google Drive",
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
660,
300
],
"parameters": {
"operation": "create",
"name": "={{ 'Proposal - ' + $json.client_company + ' - ' + new Date().toISOString().split('T')[0] }}",
"driveId": {
"value": "MY_DRIVE"
},
"folderId": {
"value": "YOUR_PROPOSALS_FOLDER_ID"
},
"content": "={{ $json.proposal_text }}",
"mimeType": "text/plain"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"id": "e4f5a6b7-0005-4000-8000-000000000005",
"name": "Request Approval via Slack",
"type": "n8n-nodes-base.slack",
"typeVersion": 2,
"position": [
880,
300
],
"parameters": {
"operation": "post",
"select": "channel",
"channelId": {
"value": "#proposals"
},
"text": "New proposal ready for review.\nClient: {{ $('Parse Proposal').item.json.client_name }} at {{ $('Parse Proposal').item.json.client_company }}\nBudget: {{ $('Parse Proposal').item.json.budget_range }}\n\nProposal saved to Google Drive. Reply with 'approve' or 'revise' to proceed.",
"otherOptions": {}
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
}
}
],
"connections": {
"Webhook Trigger": {
"main": [
[
{
"node": "Generate Proposal",
"type": "main",
"index": 0
}
]
]
},
"Generate Proposal": {
"main": [
[
{
"node": "Parse Proposal",
"type": "main",
"index": 0
}
]
]
},
"Parse Proposal": {
"main": [
[
{
"node": "Save to Google Drive",
"type": "main",
"index": 0
}
]
]
},
"Save to Google Drive": {
"main": [
[
{
"node": "Request Approval via Slack",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"staticData": null,
"tags": [],
"triggerCount": 1,
"updatedAt": "2026-05-17T00:00:00.000Z",
"versionId": "v1"
}
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.
googleDriveOAuth2ApiopenAiApislackApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
proposal-assistant-openai. Uses lmChatOpenAi, googleDrive, slack. Webhook trigger; 5 nodes.
Source: https://github.com/sondersos/n8n-workflows/blob/main/workflows/03-proposal-assistant/proposal-assistant-openai.json — 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.
z-Api. Uses httpRequest, openAi, redis, postgres. Webhook trigger; 61 nodes.
This template automates the extraction of structured data from Thai government letters received via LINE or uploaded to Google Drive. It uses Mistral AI for OCR and OpenAI for information extraction,
I made this little workflow with care for people like you who are part of busy WhatsApp groups and want a simple way to keep track of everything.
6-[Frontend]-GenerateDocument. Uses lmChatOpenAi, googleDrive. Webhook trigger; 11 nodes.
cold-outbound-engine-openai. Uses httpRequest, lmChatOpenAi, airtable, slack. Webhook trigger; 10 nodes.