AutomationFlowsAI & RAG › Automate Freelance Project Intake with Custom Proposals Using Jotform & Gemini

Automate Freelance Project Intake with Custom Proposals Using Jotform & Gemini

Byiamvaar @iamvaar on n8n.io

Workflow explaination: https://youtu.be/ecafBTFPuvE?si=7csA1yNsaUxUG72F

Event trigger★★★★☆ complexityAI-powered9 nodesJot Form TriggerAgentGoogle SheetsGoogle Gemini ChatGoogle Docs ToolOutput Parser StructuredGmail
AI & RAG Trigger: Event Nodes: 9 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #9577 — we link there as the canonical source.

This workflow follows the Agent → 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 →

Download .json
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "4bce3ca7-ca59-429f-b557-fb5a04c07e4c",
      "name": "JotForm Trigger",
      "type": "n8n-nodes-base.jotFormTrigger",
      "position": [
        -528,
        -128
      ],
      "parameters": {
        "form": "252853173448059"
      },
      "credentials": {
        "jotFormApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "664711e2-b28f-4d94-9820-62941cabb465",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -208,
        -128
      ],
      "parameters": {
        "text": "=You are an **AI Freelance Proposal Generator**, an advanced automation agent for a digital freelance agency.\n\nYour primary goal is to analyze a new **freelance project inquiry** from a form submission, create a **custom proposal**, and generate a structured JSON response containing the proposal and a personalized email.\n\nYou have access to one essential tool:\n\n**Tool Name:** My Freelance Document\n\n**Description:** When called, this tool retrieves the latest content of our Google Doc, which includes all freelance services, deliverables, pricing structures, and standard project ranges in INR. You must treat this as the single source of truth for proposal generation and pricing alignment.\n\n---\n\n### Workflow\n\n**Fetch Internal Data:**\nFirst, call the My Freelance Document tool to load our service catalog and pricing guide.\n\n**Analyze Client Request:**\nRead and interpret the client\u2019s project requirements from the form submission provided below.\n\n**Generate Custom Proposal:**\nCompare the client\u2019s needs, goals, and budget (if provided) against the data from the document. Based on the alignment, generate a concise, structured JSON response that includes the summary, proposal content, and email details.\n\n---\n\n### Crucial Safety Rules\n\n* Your first action **must** be to call the My Freelance Document tool.\n* If this tool fails or the document cannot be accessed, stop immediately and output an error message stating the internal guide is unavailable.\n* Your final output must contain only the **single valid JSON object** defined in the Output Specification.\n* Do **not** include explanations, conversational text, or any formatting outside the JSON block.\n\n---\n\n### Output Specification\n\nThe output must be a valid JSON object. Use `'NAN'` for missing or inapplicable fields instead of empty strings.\n\n```json\n{\n  \"project_type\": \"aligned\" | \"partially_aligned\" | \"misaligned\",\n  \"confidence\": \"An integer from 0-100\",\n  \"summary\": \"A concise summary of the client's project goals.\",\n  \"budget\": \"Extracted client budget in INR, or 'NAN' if not provided.\",\n  \"proposal_quality\": \"high\" | \"medium\" | \"low\",\n  \"next_action\": \"Send proposal\" | \"Needs clarification\" | \"Out of scope\",\n  \"email_subject\": \"A compelling proposal email subject, or 'NAN' if out of scope.\",\n  \"email_template\": \"An HTML-formatted proposal email string, or 'NAN' if out of scope.\"\n}\n```\n\n---\n\n### Logic for Each Field\n\n**project_type:** Determine if the client\u2019s requested project fits our offerings. \u201caligned\u201d if it directly matches our services and pricing; \u201cpartially_aligned\u201d if it fits but needs budget adjustment; \u201cmisaligned\u201d if it\u2019s unrelated or unrealistic.\n\n**confidence:** Confidence level (0\u2013100) in your project_type classification.\n\n**summary:** 1\u20132 line summary describing the client\u2019s project intent.\n\n**budget:** Extract the budget mentioned in INR. If not present, return `'NAN'`.\n\n**proposal_quality:** Rate proposal alignment based on how clearly the client\u2019s goals and budget fit our documented offerings.\n\n**next_action:** Suggest what the sales or freelance team should do next based on your assessment.\n\n**email_subject:** Write a concise and engaging subject line for the proposal email. If project_type is \u201cmisaligned,\u201d return `'NAN'`.\n\n**email_template:**\n\n* If project_type is \u201caligned\u201d or \u201cpartially_aligned\u201d: write a professional HTML proposal email.\n* If the client\u2019s budget matches our pricing, send an enthusiastic proposal and suggest a meeting or next step.\n* If the budget is too low, generate a polite and strategic negotiation email emphasizing value and deliverables.\n* If project_type is \u201cmisaligned,\u201d return `'NAN'`.\n\n---\n\n### Client Form Submission Data\n\n**Explain Your Requirement in depth:**\n{{ $json[\"Explain Your Requirement in depth\"] }}\n\n**Name:**\n{{ $json['Your Full Name'].first }} {{ $json['Your Full Name'].last }}\n\n**Email ID:**\n{{ $json['Your Email Address'] }}\n\n**Phone Number:**\n{{ $json['Your Phone Number'].full }}\n\n**Company Name:**\n{{ $json['Your Company Name (Optional)'] }}\n",
        "options": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "1c788674-22f2-459b-829c-b776cef67635",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        368,
        -128
      ],
      "parameters": {
        "options": {
          "ignoreCase": true
        },
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "f39c3db4-83fa-4be6-9573-c76cba3905a9",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.project_type }}",
              "rightValue": "aligned"
            },
            {
              "id": "b914018a-909d-4b13-83e7-1ceaee823c16",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.project_type }}",
              "rightValue": "partially_aligned"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "0d24224b-7b75-459f-9239-34d56ee200fb",
      "name": "Append or update row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        144,
        -128
      ],
      "parameters": {
        "columns": {
          "value": {
            "Email": "={{ $('JotForm Trigger').item.json['Your Email Address'] }}",
            "summary": "={{ $json.output.summary }}",
            "Full Name": "={{ $('JotForm Trigger').item.json['Your Full Name'].first }} {{ $('JotForm Trigger').item.json['Your Full Name'].last }}",
            "confidence": "={{ $json.output.confidence }}",
            "Requirement": "={{ $('JotForm Trigger').item.json['Explain Your Requirement in depth'] }}",
            "Phone number": "={{ $('JotForm Trigger').item.json['Your Phone Number'].full }}",
            "project_type": "={{ $json.output.project_type }}",
            "Email Subject": "={{ $json.output.email_subject }}",
            "budget if any": "={{ $json.output.budget }}",
            "AI generated Email body": "={{ $json.output.email_template }}"
          },
          "schema": [
            {
              "id": "Full Name",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Full Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone number",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Phone number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Requirement",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Requirement",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "project_type",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "project_type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "confidence",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "confidence",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "summary",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "summary",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "budget if any",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "budget if any",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email Subject",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Email Subject",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "AI generated Email body",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "AI generated Email body",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Email"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1gg-xBRO93bPg41PDqOx_V_OtokWljHAf0IgIWsWgUls/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1gg-xBRO93bPg41PDqOx_V_OtokWljHAf0IgIWsWgUls",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1gg-xBRO93bPg41PDqOx_V_OtokWljHAf0IgIWsWgUls/edit?usp=drivesdk",
          "cachedResultName": "Freelance Project Proposal"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "2e31a538-e669-4ef3-9bf7-ba9a34550de9",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -416,
        80
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "6a3bfee5-d41a-412e-aee1-d32b987c960e",
      "name": "My Freelance Document",
      "type": "n8n-nodes-base.googleDocsTool",
      "position": [
        -128,
        96
      ],
      "parameters": {
        "operation": "get",
        "documentURL": "=",
        "authentication": "serviceAccount",
        "descriptionType": "manual",
        "toolDescription": "This Google document will have what are the freelancing services i am providing and what are my priorities and what's my typical budget for this and all"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "469d2cd8-2c4b-4e91-9b91-1bcb920a5624",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        16,
        96
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"project_type\": \"aligned\",\n  \"confidence\": 0,\n  \"summary\": \"A concise summary of the client's project goals.\",\n  \"budget\": \"NAN\",\n  \"proposal_quality\": \"medium\",\n  \"next_action\": \"Send proposal\",\n  \"email_subject\": \"your email subject goes here\",\n  \"email_template\": \"your-html-email-template-goes here\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "76dce5c2-8f6d-417d-aac5-229d06cf097a",
      "name": "Send a message",
      "type": "n8n-nodes-base.gmail",
      "position": [
        672,
        -144
      ],
      "parameters": {
        "sendTo": "={{ $json.Email }}",
        "message": "={{ $json['AI generated Email body'] }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "={{ $json['Email Subject'] }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "300c2c00-cdc4-44eb-b0fc-ffb899b28362",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -672,
        -352
      ],
      "parameters": {
        "width": 1622,
        "height": 640,
        "content": "## This is how this works:\n* A client submits a project inquiry via a JotForm, triggering the automation.\n* An AI agent analyzes the request, references your services document, and generates a custom proposal and email.\n* The client's details and the generated proposal are logged or updated in a Google Sheet CRM.\n* After a quick validity check, the personalized proposal is automatically sent to the client's inbox via Gmail."
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Append or update row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "JotForm Trigger": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "My Freelance Document": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "AI Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Append or update row in sheet": {
      "main": [
        [
          {
            "node": "If",
            "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Workflow explaination: https://youtu.be/ecafBTFPuvE?si=7csA1yNsaUxUG72F

Source: https://n8n.io/workflows/9577/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Workflow explaination video: https://youtu.be/z1grVuNOXMk

Jot Form Trigger, Agent, Google Gemini Chat +4
AI & RAG

Explanation video: https://youtu.be/QjbA-tFYCFE?si=--C36KlSgABzteoB

Jot Form Trigger, Google Drive, Google Sheets +4
AI & RAG

This workflow contains community nodes that are only compatible with the self-hosted version of n8n.

HTTP Request, Google Sheets, OpenRouter Chat +5
AI & RAG

This workflow automates the extraction and processing of invoice data from PDFs stored in a Google Drive folder. It leverages Google Drive, Google Sheets, and Gemini AI to streamline invoice managemen

Google Gemini Chat, Google Sheets, HTTP Request +5
AI & RAG

This n8n workflow converts a YouTube video into a polished, email-ready newsletter. It scrapes the transcript, extracts a thumbnail/logo and brand color theme, uses multiple AI agents to (1) clean & s

Output Parser Structured, Agent, Gmail +5