{
  "name": "AI-Generated Sales Proposal & Deck Automation",
  "nodes": [
    {
      "id": "form_discovery_call",
      "name": "Post-Call Proposal Request",
      "type": "n8n-nodes-base.formTrigger",
      "typeVersion": 2.5,
      "position": [0, 300],
      "parameters": {
        "formTitle": "Post-Discovery-Call Proposal Request",
        "formDescription": "Fill this out right after the call — the proposal deck is generated and sent automatically.",
        "formFields": {
          "values": [
            { "fieldLabel": "Prospect Name", "requiredField": true },
            { "fieldLabel": "Company", "requiredField": true },
            { "fieldLabel": "Prospect Email", "requiredField": true },
            { "fieldLabel": "Key Challenges Discussed", "fieldType": "textarea", "requiredField": true },
            { "fieldLabel": "Proposed Solution (rep notes)", "fieldType": "textarea", "requiredField": true },
            { "fieldLabel": "Budget Range", "requiredField": true },
            { "fieldLabel": "Project Milestones / Timeline", "fieldType": "textarea", "requiredField": true }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "openai_generate_copy",
      "name": "Generate Proposal Copy",
      "type": "n8n-nodes-base.openAi",
      "typeVersion": 1.1,
      "position": [220, 300],
      "onError": "continueRegularOutput",
      "parameters": {
        "resource": "chat",
        "operation": "complete",
        "model": "gpt-4o-mini",
        "prompt": {
          "messages": [
            {
              "role": "system",
              "content": "You are a proposal writer for a Fractional COO / AI-automation consultancy. Given a rep's raw discovery-call notes, write tight, confident proposal copy. Return ONLY a single JSON object — no prose, no markdown fences — matching exactly this schema: {\"problem_statement\": \"2-3 sentences naming the specific operational pain\", \"solution_summary\": \"2-3 sentences on the proposed system/fix\", \"pricing_recommendation\": \"one sentence recommending a tier given the stated budget\", \"timeline_summary\": \"one sentence summarizing the milestone sequence\"}."
            },
            {
              "role": "user",
              "content": "={{ \"Prospect: \" + $json['Prospect Name'] + \" at \" + $json['Company'] + \"\\nChallenges: \" + $json['Key Challenges Discussed'] + \"\\nRep notes on proposed solution: \" + $json['Proposed Solution (rep notes)'] + \"\\nBudget range: \" + $json['Budget Range'] + \"\\nMilestones/timeline: \" + $json['Project Milestones / Timeline'] }}"
            }
          ]
        },
        "maxTokens": 500,
        "options": { "temperature": 0.3 }
      }
    },
    {
      "id": "code_parse_copy",
      "name": "Parse Proposal Copy",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [440, 300],
      "parameters": {
        "language": "javaScript",
        "mode": "runOnceForAllItems",
        "jsCode": "const out = [];\nfor (const item of $input.all()) {\n  const raw = item.json?.message?.content ?? item.json?.text ?? item.json?.choices?.[0]?.message?.content ?? '';\n  let copy;\n  try {\n    const match = String(raw).match(/\\{[\\s\\S]*\\}/);\n    copy = JSON.parse(match ? match[0] : raw);\n  } catch (e) {\n    copy = {\n      problem_statement: 'Your team described a recurring operational bottleneck slowing delivery and adding manual overhead.',\n      solution_summary: 'A staged systems build addressing the highest-leverage breakdown first, with measurable savings from month one.',\n      pricing_recommendation: 'A fixed-fee diagnostic sprint, scoped to the budget range discussed on the call.',\n      timeline_summary: 'A phased rollout aligned to the milestones from the call, generation-error flagged for manual review',\n      parseError: true\n    };\n  }\n  out.push({ json: { ...item.json, copy } });\n}\nreturn out;"
      }
    },
    {
      "id": "drive_copy_template",
      "name": "Copy Proposal Template",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "onError": "continueRegularOutput",
      "position": [660, 300],
      "parameters": {
        "authentication": "oAuth2",
        "resource": "file",
        "operation": "copy",
        "fileId": { "__rl": true, "mode": "id", "value": "REPLACE_WITH_TEMPLATE_PRESENTATION_ID", "cachedResultName": "Proposal Template" },
        "driveId": { "__rl": true, "mode": "list", "value": "My Drive", "cachedResultName": "My Drive" },
        "folderId": { "__rl": true, "mode": "id", "value": "root", "cachedResultName": "root" },
        "options": {
          "name": "={{ \"Proposal — \" + $json['Company'] }}"
        }
      }
    },
    {
      "id": "slides_replace_text",
      "name": "Fill In Proposal Deck",
      "type": "n8n-nodes-base.googleSlides",
      "typeVersion": 2,
      "onError": "continueRegularOutput",
      "position": [880, 300],
      "parameters": {
        "authentication": "oAuth2",
        "resource": "presentation",
        "operation": "replaceText",
        "presentationId": "={{ $json.id }}",
        "textUi": {
          "textValues": [
            { "text": "[[CLIENT_NAME]]", "replaceText": "={{ $('Parse Proposal Copy').item.json['Prospect Name'] + ' — ' + $('Parse Proposal Copy').item.json['Company'] }}" },
            { "text": "[[PROBLEM_STATEMENT]]", "replaceText": "={{ $('Parse Proposal Copy').item.json.copy.problem_statement }}" },
            { "text": "[[SOLUTION_SUMMARY]]", "replaceText": "={{ $('Parse Proposal Copy').item.json.copy.solution_summary }}" },
            { "text": "[[PRICING]]", "replaceText": "={{ $('Parse Proposal Copy').item.json.copy.pricing_recommendation }}" },
            { "text": "[[TIMELINE]]", "replaceText": "={{ $('Parse Proposal Copy').item.json.copy.timeline_summary }}" }
          ]
        }
      }
    },
    {
      "id": "drive_export_pdf",
      "name": "Export Deck as PDF",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "onError": "continueRegularOutput",
      "position": [1100, 300],
      "parameters": {
        "authentication": "oAuth2",
        "resource": "file",
        "operation": "download",
        "fileId": { "__rl": true, "mode": "id", "value": "={{ $('Copy Proposal Template').item.json.id }}", "cachedResultName": "Proposal Copy" },
        "options": {
          "googleFileConversion": {
            "conversion": { "docsToFormat": "application/pdf" }
          }
        }
      }
    },
    {
      "id": "hubspot_log_proposal",
      "name": "Log Proposal on CRM Contact",
      "type": "n8n-nodes-base.hubspot",
      "typeVersion": 2.2,
      "onError": "continueRegularOutput",
      "position": [1320, 200],
      "parameters": {
        "authentication": "apiKey",
        "resource": "contact",
        "operation": "upsert",
        "email": "={{ $('Parse Proposal Copy').item.json['Prospect Email'] }}",
        "additionalFields": {
          "firstName": "={{ $('Parse Proposal Copy').item.json['Prospect Name'] }}",
          "customPropertiesUi": {
            "customPropertiesValues": [
              { "property": "proposal_status", "value": "Sent" },
              { "property": "proposal_link", "value": "={{ 'https://docs.google.com/presentation/d/' + $('Copy Proposal Template').item.json.id }}" }
            ]
          }
        }
      }
    },
    {
      "id": "gmail_send_proposal",
      "name": "Email Proposal to Prospect",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.2,
      "onError": "continueRegularOutput",
      "position": [1320, 400],
      "parameters": {
        "authentication": "oAuth2",
        "resource": "message",
        "operation": "send",
        "sendTo": "={{ $('Parse Proposal Copy').item.json['Prospect Email'] }}",
        "subject": "={{ \"Your proposal — \" + $('Parse Proposal Copy').item.json['Company'] }}",
        "message": "={{ \"Hi \" + $('Parse Proposal Copy').item.json['Prospect Name'] + \",\\n\\nGreat talking today. Attached is a proposal built around what we discussed — \" + $('Parse Proposal Copy').item.json.copy.solution_summary + \"\\n\\nDeck: https://docs.google.com/presentation/d/\" + $('Copy Proposal Template').item.json.id + \"\\n\\nHappy to walk through it whenever works.\" }}",
        "options": {
          "attachmentsUi": {
            "attachmentsBinary": [{ "property": "data" }]
          }
        }
      }
    },
    {
      "id": "slack_notify_rep",
      "name": "Notify Rep — Proposal Sent",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.4,
      "onError": "continueRegularOutput",
      "position": [1540, 300],
      "parameters": {
        "resource": "message",
        "operation": "post",
        "select": "channel",
        "channelId": { "__rl": true, "mode": "name", "value": "#proposals-sent", "cachedResultName": "proposals-sent" },
        "text": "={{ \":page_facing_up: Proposal generated and sent to \" + $('Parse Proposal Copy').item.json['Prospect Name'] + \" at \" + $('Parse Proposal Copy').item.json['Company'] + \" — deck: https://docs.google.com/presentation/d/\" + $('Copy Proposal Template').item.json.id }}"
      }
    }
  ],
  "connections": {
    "Post-Call Proposal Request": {
      "main": [[{ "node": "Generate Proposal Copy", "type": "main", "index": 0 }]]
    },
    "Generate Proposal Copy": {
      "main": [[{ "node": "Parse Proposal Copy", "type": "main", "index": 0 }]]
    },
    "Parse Proposal Copy": {
      "main": [[{ "node": "Copy Proposal Template", "type": "main", "index": 0 }]]
    },
    "Copy Proposal Template": {
      "main": [[{ "node": "Fill In Proposal Deck", "type": "main", "index": 0 }]]
    },
    "Fill In Proposal Deck": {
      "main": [[{ "node": "Export Deck as PDF", "type": "main", "index": 0 }]]
    },
    "Export Deck as PDF": {
      "main": [
        [
          { "node": "Log Proposal on CRM Contact", "type": "main", "index": 0 },
          { "node": "Email Proposal to Prospect", "type": "main", "index": 0 }
        ]
      ]
    },
    "Log Proposal on CRM Contact": {
      "main": [[{ "node": "Notify Rep — Proposal Sent", "type": "main", "index": 0 }]]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}
