UNPKG

n8n-nodes-linkedin-jobs

Version:

Nœud n8n pour récupérer des offres d'emploi LinkedIn avec des filtres avancés

417 lines (416 loc) 16 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LinkedInJobs = void 0; // Import des valeurs à l'exécution pour compatibilité n8n Community Nodes const { NodeOperationError, } = require('n8n-workflow'); class LinkedInJobs { constructor() { this.description = { displayName: 'LinkedIn Jobs', name: 'linkedInJobs', icon: 'file:linkedin.svg', group: ['input'], version: 1, subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', description: 'Récupère des offres d\'emploi depuis LinkedIn avec des filtres avancés', defaults: { name: 'LinkedIn Jobs', }, inputs: ['main'], outputs: ['main'], credentials: [], properties: [ { displayName: 'Resource', name: 'resource', type: 'options', noDataExpression: true, options: [ { name: 'Job', value: 'job', }, ], default: 'job', }, { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, displayOptions: { show: { resource: ['job'], }, }, options: [ { name: 'Search', value: 'search', description: 'Rechercher des offres d\'emploi', action: 'Rechercher des offres d\'emploi', }, ], default: 'search', }, // Paramètres de recherche { displayName: 'Mot-clé', name: 'keyword', type: 'string', displayOptions: { show: { operation: ['search'], resource: ['job'], }, }, default: '', placeholder: 'ex: développeur frontend', description: 'Le texte à rechercher (ex: développeur logiciel)', }, { displayName: 'Localisation', name: 'location', type: 'string', displayOptions: { show: { operation: ['search'], resource: ['job'], }, }, default: '', placeholder: 'ex: Paris, France', description: 'Nom de la ville ou région', }, { displayName: 'Date de publication', name: 'dateSincePosted', type: 'options', displayOptions: { show: { operation: ['search'], resource: ['job'], }, }, options: [ { name: 'Tout', value: '', }, { name: 'Dernières 24h', value: '24hr', }, { name: 'Dernière semaine', value: 'past week', }, { name: 'Dernier mois', value: 'past month', }, ], default: '', description: 'Période de publication des offres', }, { displayName: 'Type d\'emploi', name: 'jobType', type: 'options', displayOptions: { show: { operation: ['search'], resource: ['job'], }, }, options: [ { name: 'Tous', value: '', }, { name: 'Temps plein', value: 'full time', }, { name: 'Temps partiel', value: 'part time', }, { name: 'Contrat', value: 'contract', }, { name: 'Temporaire', value: 'temporary', }, { name: 'Bénévolat', value: 'volunteer', }, { name: 'Stage', value: 'internship', }, ], default: '', description: 'Type de poste recherché', }, { displayName: 'Télétravail', name: 'remoteFilter', type: 'options', displayOptions: { show: { operation: ['search'], resource: ['job'], }, }, options: [ { name: 'Tous', value: '', }, { name: 'Sur site', value: 'on site', }, { name: 'Télétravail', value: 'remote', }, { name: 'Hybride', value: 'hybrid', }, ], default: '', description: 'Préférence de télétravail', }, { displayName: 'Salaire minimum', name: 'salary', type: 'options', displayOptions: { show: { operation: ['search'], resource: ['job'], }, }, options: [ { name: 'Aucun minimum', value: '', }, { name: '40 000+', value: '40000', }, { name: '60 000+', value: '60000', }, { name: '80 000+', value: '80000', }, { name: '100 000+', value: '100000', }, { name: '120 000+', value: '120000', }, ], default: '', description: 'Salaire minimum recherché', }, { displayName: 'Niveau d\'expérience', name: 'experienceLevel', type: 'options', displayOptions: { show: { operation: ['search'], resource: ['job'], }, }, options: [ { name: 'Tous', value: '', }, { name: 'Stage', value: 'internship', }, { name: 'Débutant', value: 'entry level', }, { name: 'Confirmé', value: 'associate', }, { name: 'Senior', value: 'senior', }, { name: 'Directeur', value: 'director', }, { name: 'Exécutif', value: 'executive', }, ], default: '', description: 'Niveau d\'expérience requis', }, { displayName: 'Nombre de résultats', name: 'limit', type: 'number', displayOptions: { show: { operation: ['search'], resource: ['job'], }, }, default: 10, typeOptions: { minValue: 1, maxValue: 100, }, description: 'Nombre d\'offres à retourner (1-100)', }, { displayName: 'Trier par', name: 'sortBy', type: 'options', displayOptions: { show: { operation: ['search'], resource: ['job'], }, }, options: [ { name: 'Par défaut', value: '', }, { name: 'Plus récent', value: 'recent', }, { name: 'Plus pertinent', value: 'relevant', }, ], default: '', description: 'Ordre de tri des résultats', }, { displayName: 'Page', name: 'page', type: 'number', displayOptions: { show: { operation: ['search'], resource: ['job'], }, }, default: 0, typeOptions: { minValue: 0, }, description: 'Numéro de page (commence à 0)', }, ], }; } async execute() { var _a; const items = this.getInputData(); const returnData = []; const resource = this.getNodeParameter('resource', 0); const operation = this.getNodeParameter('operation', 0); // Import dynamique du package linkedin-jobs-api let linkedIn; try { linkedIn = require('linkedin-jobs-api'); } catch (error) { throw new NodeOperationError(this.getNode(), 'Le package "linkedin-jobs-api" n\'est pas installé. Installez-le avec: npm install linkedin-jobs-api'); } for (let i = 0; i < items.length; i++) { try { if (resource === 'job' && operation === 'search') { // Récupération des paramètres const pageParam = this.getNodeParameter('page', i); const pageValue = pageParam != null ? pageParam.toString() : '0'; const queryOptions = { keyword: this.getNodeParameter('keyword', i), location: this.getNodeParameter('location', i), dateSincePosted: this.getNodeParameter('dateSincePosted', i), jobType: this.getNodeParameter('jobType', i), remoteFilter: this.getNodeParameter('remoteFilter', i), salary: this.getNodeParameter('salary', i), experienceLevel: this.getNodeParameter('experienceLevel', i), limit: String(this.getNodeParameter('limit', i)), sortBy: this.getNodeParameter('sortBy', i), page: pageValue, }; // Nettoyage des paramètres vides Object.keys(queryOptions).forEach(key => { if (queryOptions[key] === '' || queryOptions[key] === undefined) { delete queryOptions[key]; } }); // Exécution de la requête const response = await linkedIn.query(queryOptions); if (Array.isArray(response)) { // Ajouter chaque offre d'emploi comme un élément séparé for (const job of response) { returnData.push({ json: { ...job, // Ajout de métadonnées de recherche searchParams: queryOptions, retrievedAt: new Date().toISOString(), }, }); } } else { // Si la réponse n'est pas un tableau, l'ajouter tel quel returnData.push({ json: { data: response, searchParams: queryOptions, retrievedAt: new Date().toISOString(), }, }); } } } catch (error) { if (this.continueOnFail()) { returnData.push({ json: { error: (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : String(error), searchParams: this.getNodeParameter('keyword', i), }, }); continue; } throw error; } } return [returnData]; } } exports.LinkedInJobs = LinkedInJobs;