Automatización de la evaluación de candidatos con puntuación GPT-4 y notificaciones por Gmail

Intermedio

Este es unHR, AI Summarizationflujo de automatización del dominio deautomatización que contiene 12 nodos.Utiliza principalmente nodos como If, Set, Code, Gmail, Webhook. Automatización de la evaluación de candidatos con puntuación GPT-4 y notificaciones de Gmail

Requisitos previos
  • Cuenta de Google y credenciales de API de Gmail
  • Punto final de HTTP Webhook (n8n generará automáticamente)
  • Pueden requerirse credenciales de autenticación para la API de destino
Vista previa del flujo de trabajo
Visualización de las conexiones entre nodos, con soporte para zoom y panorámica
Exportar flujo de trabajo
Copie la siguiente configuración JSON en n8n para importar y usar este flujo de trabajo
{
  "nodes": [
    {
      "id": "1",
      "name": "CV Submission Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        240,
        300
      ],
      "parameters": {
        "path": "cv-received",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 1
    },
    {
      "id": "2",
      "name": "Nota Adhesiva",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        140,
        180
      ],
      "parameters": {
        "width": 240,
        "height": 160,
        "content": "## Recruitment AI Config\n\n⚙️ **Customize scoring:**\n- Technical skills weights\n- Experience requirements\n- Education priorities\n- Cultural fit criteria"
      },
      "typeVersion": 1
    },
    {
      "id": "3",
      "name": "Requisitos del Puesto",
      "type": "n8n-nodes-base.set",
      "position": [
        440,
        300
      ],
      "parameters": {
        "values": {
          "number": [
            {
              "name": "minExperience",
              "value": 5
            },
            {
              "name": "passingScore",
              "value": 75
            }
          ],
          "string": [
            {
              "name": "requiredSkills",
              "value": "JavaScript,React,Node.js,Python"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "4",
      "name": "Analizar CV con IA",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        640,
        300
      ],
      "parameters": {
        "url": "https://api.openai.com/v1/chat/completions",
        "body": {
          "model": "gpt-4",
          "messages": [
            {
              "role": "system",
              "content": "You are a CV parsing expert. Extract key information from CVs and return structured JSON data."
            },
            {
              "role": "user",
              "content": "Parse this CV and extract: name, email, phone, skills, experience_years, education, previous_roles. CV content: {{ $json.cv_content }}"
            }
          ],
          "response_format": {
            "type": "json_object"
          }
        },
        "method": "POST",
        "headers": {
          "Content-Type": "application/json",
          "Authorization": "Bearer {{ $credentials.openai.apiKey }}"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "5",
      "name": "Puntuar Candidato",
      "type": "n8n-nodes-base.code",
      "position": [
        840,
        300
      ],
      "parameters": {
        "jsCode": "// Intelligent candidate scoring algorithm\nconst candidate = $json.choices[0].message.content;\nconst requirements = $node['Job Requirements'].json;\nconst candidateData = JSON.parse(candidate);\n\nlet totalScore = 0;\n\n// Skills matching (40% weight)\nconst requiredSkills = requirements.requiredSkills.split(',');\nconst candidateSkills = candidateData.skills || [];\nconst skillsMatch = requiredSkills.filter(skill => \n  candidateSkills.some(cSkill => cSkill.toLowerCase().includes(skill.toLowerCase()))\n);\nconst skillsScore = (skillsMatch.length / requiredSkills.length) * 40;\ntotalScore += skillsScore;\n\n// Experience scoring (30% weight)\nconst experienceYears = candidateData.experience_years || 0;\nlet experienceScore = 0;\nif (experienceYears >= requirements.minExperience) {\n  experienceScore = 30;\n} else if (experienceYears >= requirements.minExperience * 0.8) {\n  experienceScore = 25;\n} else if (experienceYears >= requirements.minExperience * 0.6) {\n  experienceScore = 20;\n} else {\n  experienceScore = 10;\n}\ntotalScore += experienceScore;\n\n// Education scoring (20% weight)\nconst education = candidateData.education || '';\nlet educationScore = 0;\nif (education.toLowerCase().includes('master') || education.toLowerCase().includes('phd')) {\n  educationScore = 20;\n} else if (education.toLowerCase().includes('bachelor') || education.toLowerCase().includes('degree')) {\n  educationScore = 15;\n} else {\n  educationScore = 10;\n}\ntotalScore += educationScore;\n\n// Role relevance (10% weight)\nconst previousRoles = candidateData.previous_roles || [];\nconst roleRelevance = previousRoles.some(role => \n  role.toLowerCase().includes('engineer') || role.toLowerCase().includes('developer')\n) ? 10 : 5;\ntotalScore += roleRelevance;\n\n// Determine recommendation\nlet recommendation = 'reject';\nlet priority = 'low';\n\nif (totalScore >= 85) {\n  recommendation = 'hire';\n  priority = 'high';\n} else if (totalScore >= requirements.passingScore) {\n  recommendation = 'interview';\n  priority = 'medium';\n} else if (totalScore >= 60) {\n  recommendation = 'phone_screen';\n  priority = 'low';\n}\n\nreturn {\n  candidateData,\n  scoring: {\n    skillsScore,\n    experienceScore,\n    educationScore,\n    roleRelevance,\n    totalScore: Math.round(totalScore),\n    recommendation,\n    priority\n  },\n  jobTitle: requirements.jobTitle,\n  evaluatedAt: new Date().toISOString()\n};"
      },
      "typeVersion": 1
    },
    {
      "id": "6",
      "name": "Verificar si es Candidato Destacado",
      "type": "n8n-nodes-base.if",
      "position": [
        1040,
        200
      ],
      "parameters": {
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.scoring.recommendation }}",
              "rightValue": "hire"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "7",
      "name": "Alertar al Equipo de RRHH",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1240,
        100
      ],
      "parameters": {
        "sendTo": "={{ $node['Job Requirements'].json.hrEmail }}",
        "message": "=<!DOCTYPE html>\n<html>\n<head>\n  <style>\n    body { font-family: Arial, sans-serif; margin: 20px; background-color: #f8f9fa; }\n    .container { max-width: 600px; margin: 0 auto; background: white; padding: 30px; border-radius: 10px; }\n    .top-candidate { background: linear-gradient(45deg, #28a745, #20c997); color: white; padding: 20px; text-align: center; margin: 20px 0; border-radius: 10px; }\n    .candidate-info { background: #d4edda; padding: 15px; margin: 15px 0; border-radius: 5px; }\n    .score-breakdown { background: #f8f9fa; padding: 15px; margin: 15px 0; border-radius: 5px; }\n    .cta { background: #007bff; color: white; padding: 15px 30px; text-decoration: none; border-radius: 5px; display: inline-block; margin: 20px 0; }\n  </style>\n</head>\n<body>\n  <div class=\"container\">\n    <div class=\"top-candidate\">\n      <h2>🌟 EXCEPTIONAL CANDIDATE</h2>\n      <p>High-priority candidate for {{ $json.jobTitle }}</p>\n    </div>\n    \n    <div class=\"candidate-info\">\n      <h3>👤 Candidate Profile</h3>\n      <p><strong>Name:</strong> {{ $json.candidateData.name }}</p>\n      <p><strong>Email:</strong> {{ $json.candidateData.email }}</p>\n      <p><strong>Phone:</strong> {{ $json.candidateData.phone }}</p>\n      <p><strong>Experience:</strong> {{ $json.candidateData.experience_years }} years</p>\n      <p><strong>Education:</strong> {{ $json.candidateData.education }}</p>\n    </div>\n    \n    <div class=\"score-breakdown\">\n      <h3>📊 Scoring Breakdown</h3>\n      <p><strong>Overall Score:</strong> {{ $json.scoring.totalScore }}/100</p>\n      <p><strong>Skills Match:</strong> {{ $json.scoring.skillsScore }}/40</p>\n      <p><strong>Experience:</strong> {{ $json.scoring.experienceScore }}/30</p>\n      <p><strong>Education:</strong> {{ $json.scoring.educationScore }}/20</p>\n      <p><strong>Role Relevance:</strong> {{ $json.scoring.roleRelevance }}/10</p>\n    </div>\n    \n    <div style=\"text-align: center;\">\n      <a href=\"mailto:{{ $json.candidateData.email }}\" class=\"cta\">📧 Contact Candidate</a>\n      <a href=\"https://calendly.com/interview-{{ $json.candidateData.name }}\" class=\"cta\">📅 Schedule Interview</a>\n    </div>\n    \n    <p style=\"color: #666; font-size: 14px; margin-top: 30px;\">\n      Recommendation: {{ $json.scoring.recommendation }} | Priority: {{ $json.scoring.priority }}\n    </p>\n  </div>\n</body>\n</html>",
        "options": {
          "contentType": "html"
        },
        "subject": "🌟 Top Candidate Alert - {{ $json.jobTitle }}"
      },
      "typeVersion": 1
    },
    {
      "id": "8",
      "name": "Verificar si es Apto para Entrevista",
      "type": "n8n-nodes-base.if",
      "position": [
        1040,
        300
      ],
      "parameters": {
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.scoring.recommendation }}",
              "rightValue": "interview"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "9",
      "name": "Enviar Invitación a Entrevista",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1240,
        300
      ],
      "parameters": {
        "sendTo": "={{ $json.candidateData.email }}",
        "message": "=<!DOCTYPE html>\n<html>\n<head>\n  <style>\n    body { font-family: Arial, sans-serif; margin: 20px; background-color: #f8f9fa; }\n    .container { max-width: 600px; margin: 0 auto; background: white; padding: 30px; border-radius: 10px; }\n    .interview-invite { background: #007bff; color: white; padding: 20px; text-align: center; margin: 20px 0; border-radius: 8px; }\n    .next-steps { background: #e8f4f8; padding: 15px; margin: 15px 0; border-radius: 5px; }\n    .cta { background: #28a745; color: white; padding: 15px 30px; text-decoration: none; border-radius: 5px; display: inline-block; margin: 20px 0; }\n  </style>\n</head>\n<body>\n  <div class=\"container\">\n    <div class=\"interview-invite\">\n      <h2>🎉 Interview Invitation</h2>\n      <p>Congratulations! We'd like to interview you for the {{ $json.jobTitle }} position.</p>\n    </div>\n    \n    <p>Dear {{ $json.candidateData.name }},</p>\n    \n    <p>We were impressed by your profile and would like to invite you for an interview.</p>\n    \n    <div class=\"next-steps\">\n      <h3>📅 Next Steps</h3>\n      <ul>\n        <li>Schedule your interview using the link below</li>\n        <li>Prepare for technical questions about your experience</li>\n        <li>Review our company culture and values</li>\n        <li>Prepare questions about the role and team</li>\n      </ul>\n    </div>\n    \n    <div style=\"text-align: center;\">\n      <a href=\"https://calendly.com/interview-{{ $json.candidateData.name }}\" class=\"cta\">\n        📅 Schedule Your Interview\n      </a>\n    </div>\n    \n    <p>Looking forward to meeting you!</p>\n    \n    <p style=\"color: #666; font-size: 14px; margin-top: 30px;\">\n      Best regards,<br>\n      HR Team\n    </p>\n  </div>\n</body>\n</html>",
        "options": {
          "contentType": "html"
        },
        "subject": "Interview Invitation - {{ $json.jobTitle }} Position"
      },
      "typeVersion": 1
    },
    {
      "id": "10",
      "name": "Verificar si es Rechazado",
      "type": "n8n-nodes-base.if",
      "position": [
        1040,
        400
      ],
      "parameters": {
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.scoring.recommendation }}",
              "rightValue": "reject"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "11",
      "name": "Enviar Correo de Rechazo",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1240,
        400
      ],
      "parameters": {
        "sendTo": "={{ $json.candidateData.email }}",
        "message": "=<!DOCTYPE html>\n<html>\n<head>\n  <style>\n    body { font-family: Arial, sans-serif; margin: 20px; background-color: #f8f9fa; }\n    .container { max-width: 600px; margin: 0 auto; background: white; padding: 30px; border-radius: 10px; }\n    .thank-you { background: #6c757d; color: white; padding: 20px; text-align: center; margin: 20px 0; border-radius: 8px; }\n    .feedback { background: #f8f9fa; padding: 15px; margin: 15px 0; border-radius: 5px; }\n  </style>\n</head>\n<body>\n  <div class=\"container\">\n    <div class=\"thank-you\">\n      <h2>Thank You for Your Interest</h2>\n      <p>We appreciate you taking the time to apply for the {{ $json.jobTitle }} position.</p>\n    </div>\n    \n    <p>Dear {{ $json.candidateData.name }},</p>\n    \n    <p>Thank you for your application. While your background is impressive, we have decided to move forward with other candidates who more closely match our current requirements.</p>\n    \n    <div class=\"feedback\">\n      <h3>💡 For Future Opportunities</h3>\n      <p>We encourage you to:</p>\n      <ul>\n        <li>Continue developing your technical skills</li>\n        <li>Gain more relevant experience in your field</li>\n        <li>Apply for future positions that match your expertise</li>\n      </ul>\n    </div>\n    \n    <p>We'll keep your resume on file and will reach out if a suitable position becomes available.</p>\n    \n    <p style=\"color: #666; font-size: 14px; margin-top: 30px;\">\n      Best regards,<br>\n      HR Team\n    </p>\n  </div>\n</body>\n</html>",
        "options": {
          "contentType": "html"
        },
        "subject": "Thank you for your application - {{ $json.jobTitle }}"
      },
      "typeVersion": 1
    },
    {
      "id": "12",
      "name": "Nota Adhesiva1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1140,
        60
      ],
      "parameters": {
        "width": 240,
        "height": 160,
        "content": "## AI-Powered Decisions\n\n🤖 **Automated actions:**\n- Top candidates: HR alert\n- Interview worthy: Auto-invite\n- Rejected: Polite decline\n- Phone screen: Initial contact"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "1": {
      "main": [
        [
          {
            "node": "3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3": {
      "main": [
        [
          {
            "node": "4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4": {
      "main": [
        [
          {
            "node": "5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5": {
      "main": [
        [
          {
            "node": "6",
            "type": "main",
            "index": 0
          },
          {
            "node": "8",
            "type": "main",
            "index": 0
          },
          {
            "node": "10",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6": {
      "main": [
        [
          {
            "node": "7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8": {
      "main": [
        [
          {
            "node": "9",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "10": {
      "main": [
        [
          {
            "node": "11",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Preguntas frecuentes

¿Cómo usar este flujo de trabajo?

Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.

¿En qué escenarios es adecuado este flujo de trabajo?

Intermedio - Recursos Humanos, Resumen de IA

¿Es de pago?

Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.

Información del flujo de trabajo
Nivel de dificultad
Intermedio
Número de nodos12
Categoría2
Tipos de nodos7
Descripción de la dificultad

Adecuado para usuarios con experiencia intermedia, flujos de trabajo de complejidad media con 6-15 nodos

Enlaces externos
Ver en n8n.io

Compartir este flujo de trabajo

Categorías

Categorías: 34