{
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "3f85f600-afcc-401d-b89d-1c1e329098bb",
        "responseMode": "lastNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        -368,
        -240
      ],
      "id": "d386d937-64f6-4100-9adc-b85c753680e0",
      "name": "Webhook"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=Write a tailored cover letter using the information below.\n\nCandidate\u2019s resume\n\"\"\"\n{{ $json.resume }}\n\"\"\"\n\nJob offer description\n\"\"\"\n{{ $json.description }}\n\"\"\"\n\nPlease:\n\nWrite a single professional cover letter targeted specifically to the role described in the job offer.\n\nUse the candidate\u2019s resume as the only source of their skills, experience, and achievements. Do not invent any new facts.\n\nEmphasize the 2\u20134 experiences or achievements from the resume that best match the requirements and responsibilities in the job offer.\n\nMention the company name and job title if they are present in the job offer. If no hiring manager name is provided, use \u201cDear Hiring Manager,\u201d as the greeting.\n\nNaturally include important keywords and requirements from the job offer so the letter aligns well with ATS screening.\n\nKeep the tone confident, clear, and concise, and avoid clich\u00e9s and overly generic phrases.\n\nAim for about 250\u2013400 words.\n\nReturn only the final cover letter text, with no explanations or additional formatting.",
        "hasOutputParser": true,
        "options": {
          "systemMessage": "You are an expert career copywriter specializing in concise, tailored cover letters.\nYour job is to write a single, polished cover letter in English using the candidate\u2019s resume and the job description provided.\n\nFollow these rules:\n\nGoal & audience\n\nWrite a professional, confident, and friendly cover letter suitable for an online application or email body.\n\nFocus on showing fit between the candidate and the specific role and company.\n\nContent & tailoring\n\nUse only information that appears in the resume and job description. Do not invent skills, dates, companies, or achievements.\n\nPrioritize and highlight the 2\u20134 most relevant experiences or achievements from the resume that match the job description.\n\nNaturally incorporate important keywords and requirements from the job description (for ATS compatibility), but avoid keyword stuffing.\n\nIf the company name, role title, or hiring manager name are present in the job description, use them.\n\nIf no hiring manager name is given, address the letter to \u201cDear Hiring Manager,\u201d.\n\nIf no company name is given, refer generically to \u201cyour company\u201d or \u201cyour organization\u201d.\n\nStructure\n\nStandard cover letter structure:\n\nGreeting\n\nOpening paragraph: position you\u2019re applying for + brief hook on why you\u2019re a strong fit.\n\n1\u20133 body paragraphs: specific, resume-backed examples that show relevant skills, impact, and alignment with the role.\n\nClosing paragraph: enthusiasm, call to action, and sign-off.\n\nEnd with a professional closing such as \u201cSincerely,\u201d or \u201cBest regards,\u201d followed by the candidate\u2019s name (from the resume if available).\n\nStyle & tone\n\nClear, concise, and easy to read.\n\nAvoid clich\u00e9s (\u201cI am writing to express my interest\u2026\u201d, \u201cteam player\u201d, \u201chard worker\u201d) when possible\u2014rewrite them into more concrete, specific statements.\n\nAvoid exaggeration, flattery, and buzzwords; focus on evidence-based strengths (quantified impact where possible).\n\nLength & format\n\nAim for about 250\u2013400 words, unless the job description clearly demands something shorter or longer.\n\nOutput plain text only (no markdown, bullet points, or headings).\n\nAssumptions\n\nIf some details are missing (e.g., location, exact dates), write a generic but strong cover letter without asking clarifying questions.\n\nNever mention these instructions or the resume/job description sections explicitly in the final letter."
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3,
      "position": [
        -64,
        -96
      ],
      "id": "eef0eeba-6a34-4103-bbfd-fab77e9dcc72",
      "name": "AI Agent"
    },
    {
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"coverLetter\": {\n      \"type\": \"string\",\n      \"description\": \"Text containing the generated cover letter, as a single plain-text string (no markdown, no extra formatting).\"\n    }\n  },\n  \"required\": [\"coverLetter\"],\n  \"additionalProperties\": false\n}"
      },
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "typeVersion": 1.3,
      "position": [
        96,
        80
      ],
      "id": "8ada7818-87b4-441b-a808-ff6b6ca704af",
      "name": "Structured Output Parser"
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "typeVersion": 1,
      "position": [
        -80,
        80
      ],
      "id": "f1c5e801-e4a5-4e7c-83a8-dfc0a011e34a",
      "name": "Google Gemini Chat Model",
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "findOneAndUpdate",
        "collection": "job-offers",
        "updateKey": "=id",
        "fields": "coverLetter",
        "options": {}
      },
      "type": "n8n-nodes-base.mongoDb",
      "typeVersion": 1.2,
      "position": [
        560,
        -224
      ],
      "id": "148eceb4-249a-42dd-a3c4-f3593e346df5",
      "name": "Find and update documents",
      "alwaysOutputData": false,
      "credentials": {
        "mongoDb": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "eca0825b-26b8-4180-8a17-c1a8594848f6",
              "name": "id",
              "value": "={{ $json.body.id }}",
              "type": "string"
            },
            {
              "id": "489dabda-4ead-4c04-bdcf-a14d9cf237d6",
              "name": "description",
              "value": "={{ $json.body.jobDescription }}",
              "type": "string"
            },
            {
              "id": "68dc9761-a883-4b89-b62e-c51e4c0e83d3",
              "name": "resume",
              "value": "={{ $json.body.resume }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -208,
        -240
      ],
      "id": "e9607511-6674-4c70-8d8b-7cfbcfd332af",
      "name": "Edit Fields"
    },
    {
      "parameters": {
        "mode": "combine",
        "combineBy": "combineByPosition",
        "options": {}
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        384,
        -224
      ],
      "id": "a6979cb6-4b04-4b96-9c56-554d1b204135",
      "name": "Merge"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "ab6f15a3-1cf7-49b8-8d02-ea26dd767096",
              "name": "coverLetter",
              "value": "={{ $json.output.coverLetter }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        208,
        -96
      ],
      "id": "56e10320-72e4-4954-84ae-50d51d79c4fc",
      "name": "Edit Fields1"
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Edit Fields1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "AI Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "Find and update documents",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields1": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    }
  },
  "meta": {
    "templateCredsSetupCompleted": true
  }
}