Add Activepieces integration for workflow automation
- Add Activepieces fork with SmoothSchedule custom piece - Create integrations app with Activepieces service layer - Add embed token endpoint for iframe integration - Create Automations page with embedded workflow builder - Add sidebar visibility fix for embed mode - Add list inactive customers endpoint to Public API - Include SmoothSchedule triggers: event created/updated/cancelled - Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"extends": [
|
||||
"../../../../.eslintrc.json"
|
||||
],
|
||||
"ignorePatterns": [
|
||||
"!**/*"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx",
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {},
|
||||
"extends": [
|
||||
"plugin:prettier/recommended"
|
||||
],
|
||||
"plugins": ["prettier"]
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# pieces-lever
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Building
|
||||
|
||||
Run `nx build pieces-lever` to build the library.
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "@activepieces/piece-lever",
|
||||
"version": "0.0.11"
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "pieces-lever",
|
||||
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "packages/pieces/community/lever/src",
|
||||
"projectType": "library",
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/js:tsc",
|
||||
"outputs": [
|
||||
"{options.outputPath}"
|
||||
],
|
||||
"options": {
|
||||
"outputPath": "dist/packages/pieces/community/lever",
|
||||
"tsConfig": "packages/pieces/community/lever/tsconfig.lib.json",
|
||||
"packageJson": "packages/pieces/community/lever/package.json",
|
||||
"main": "packages/pieces/community/lever/src/index.ts",
|
||||
"assets": [
|
||||
"packages/pieces/community/lever/*.md",
|
||||
{
|
||||
"input": "packages/pieces/community/lever/src/i18n",
|
||||
"output": "./src/i18n",
|
||||
"glob": "**/!(i18n.json)"
|
||||
}
|
||||
],
|
||||
"buildableProjectDepsInPackageJsonType": "dependencies",
|
||||
"updateBuildableProjectDepsInPackageJson": true
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
"prebuild"
|
||||
]
|
||||
},
|
||||
"publish": {
|
||||
"command": "node tools/scripts/publish.mjs pieces-lever {args.ver} {args.tag}",
|
||||
"dependsOn": [
|
||||
"build"
|
||||
]
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": [
|
||||
"{options.outputFile}"
|
||||
]
|
||||
},
|
||||
"prebuild": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"cwd": "packages/pieces/community/lever",
|
||||
"command": "bun install --no-save --silent"
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
]
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"Lever is a modern, collaborative recruiting platform that powers a more human approach to hiring.": "Hever ist eine moderne, kollaborative Rekrutierungsplattform, die einen menschlicheren Ansatz bei der Einstellung von Mitarbeitern unterstützt.",
|
||||
"API key": "API-Schlüssel",
|
||||
"Get opportunity": "Chance erhalten",
|
||||
"Update opportunity stage": "Verkaufs-Phase aktualisieren",
|
||||
"List opportunity forms": "Opportunity-Formulare auflisten",
|
||||
"List opportunity feedback": "Feedback zur Verkaufs-Chance anzeigen",
|
||||
"Add feedback to opportunity": "Feedback zu Verkaufs-Chance hinzufügen",
|
||||
"Custom API Call": "Eigener API-Aufruf",
|
||||
"Retrieve a single opportunity, i.e. an individual's unique candidacy or journey for a given job position": "Holen Sie sich eine einmalige Gelegenheit, z.B. die individuelle Kandidatur oder die Reise für eine bestimmte Position",
|
||||
"Change an Opportunity's current stage": "Aktuelles Stadium einer Verkaufschance ändern",
|
||||
"Get all forms for a given opportunity, optionally for a given form template": "Erhalten Sie alle Formulare für eine gegebene Gelegenheit, optional für eine vorgegebene Formularvorlage",
|
||||
"Get all feedback for a given opportunity, optionally for a given template": "Erhalten Sie alle Rückmeldungen für eine gegebene Gelegenheit, optional für eine vorgegebene Vorlage",
|
||||
"Provide feedback to a candidate after an interview": "Feedback an einen Kandidaten nach einem Interview geben",
|
||||
"Make a custom API call to a specific endpoint": "Einen benutzerdefinierten API-Aufruf an einen bestimmten Endpunkt machen",
|
||||
"Opportunity ID": "Verkaufs-ID",
|
||||
"Expand": "Erweitern",
|
||||
"Stage": "Teil",
|
||||
"Form template": "Formularvorlage",
|
||||
"Feedback template": "Feedback-Template",
|
||||
"Feedback author": "Feedback-Autor",
|
||||
"Interview panel": "Interview Panel",
|
||||
"Interview": "Interview",
|
||||
"Fields": "Felder",
|
||||
"Method": "Methode",
|
||||
"Headers": "Kopfzeilen",
|
||||
"Query Parameters": "Abfrageparameter",
|
||||
"Body": "Körper",
|
||||
"Response is Binary ?": "Antwort ist binär?",
|
||||
"No Error on Failure": "Kein Fehler bei Fehler",
|
||||
"Timeout (in seconds)": "Timeout (in Sekunden)",
|
||||
"If you select one, you must select an interview too": "Wenn du eines auswählst, musst du auch ein Interview auswählen",
|
||||
"Mandatory is you select an interview panel": "Bitte wählen Sie ein Interview-Panel aus",
|
||||
"Ignored if you select an interview panel and an interview": "Ignoriert, wenn Sie ein Interview-Panel und ein Interview auswählen",
|
||||
"Authorization headers are injected automatically from your connection.": "Autorisierungs-Header werden automatisch von Ihrer Verbindung injiziert.",
|
||||
"Enable for files like PDFs, images, etc..": "Aktivieren für Dateien wie PDFs, Bilder, etc..",
|
||||
"GET": "ERHALTEN",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "LÖSCHEN",
|
||||
"HEAD": "HEAD"
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"Lever is a modern, collaborative recruiting platform that powers a more human approach to hiring.": "Lever es una plataforma de reclutamiento moderna y colaborativa que potencia un enfoque más humano para la contratación.",
|
||||
"API key": "Clave API",
|
||||
"Get opportunity": "Obtener oportunidad",
|
||||
"Update opportunity stage": "Actualizar etapa de oportunidad",
|
||||
"List opportunity forms": "Listar formularios de oportunidad",
|
||||
"List opportunity feedback": "Listar comentarios de oportunidad",
|
||||
"Add feedback to opportunity": "Añadir comentarios a la oportunidad",
|
||||
"Custom API Call": "Llamada API personalizada",
|
||||
"Retrieve a single opportunity, i.e. an individual's unique candidacy or journey for a given job position": "Recuperar una sola oportunidad, es decir, la única candidatura o el viaje de un individuo para un puesto de trabajo determinado",
|
||||
"Change an Opportunity's current stage": "Cambiar la etapa actual de una oportunidad",
|
||||
"Get all forms for a given opportunity, optionally for a given form template": "Obtener todos los formularios para una oportunidad dada, opcionalmente para una plantilla de formulario determinada",
|
||||
"Get all feedback for a given opportunity, optionally for a given template": "Obtener todos los comentarios para una oportunidad dada, opcionalmente para una plantilla determinada",
|
||||
"Provide feedback to a candidate after an interview": "Proporcionar comentarios a un candidato después de una entrevista",
|
||||
"Make a custom API call to a specific endpoint": "Hacer una llamada API personalizada a un extremo específico",
|
||||
"Opportunity ID": "ID Oportunidad",
|
||||
"Expand": "Expandir",
|
||||
"Stage": "Etapa",
|
||||
"Form template": "Formulario plantilla",
|
||||
"Feedback template": "Plantilla de Comentarios",
|
||||
"Feedback author": "Autor de comentarios",
|
||||
"Interview panel": "Panel de entrevistas",
|
||||
"Interview": "Entrevista",
|
||||
"Fields": "Campos",
|
||||
"Method": "Método",
|
||||
"Headers": "Encabezados",
|
||||
"Query Parameters": "Parámetros de consulta",
|
||||
"Body": "Cuerpo",
|
||||
"Response is Binary ?": "¿Respuesta es binaria?",
|
||||
"No Error on Failure": "No hay ningún error en fallo",
|
||||
"Timeout (in seconds)": "Tiempo de espera (en segundos)",
|
||||
"If you select one, you must select an interview too": "Si seleccionas una, también debes seleccionar una entrevista",
|
||||
"Mandatory is you select an interview panel": "Mandatorio es que seleccionas un panel de entrevista",
|
||||
"Ignored if you select an interview panel and an interview": "Ignorado si seleccionas un panel de entrevista y una entrevista",
|
||||
"Authorization headers are injected automatically from your connection.": "Las cabeceras de autorización se inyectan automáticamente desde tu conexión.",
|
||||
"Enable for files like PDFs, images, etc..": "Activar para archivos como PDFs, imágenes, etc.",
|
||||
"GET": "RECOGER",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "BORRAR",
|
||||
"HEAD": "LIMPIO"
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"Lever is a modern, collaborative recruiting platform that powers a more human approach to hiring.": "Levier est une plateforme de recrutement moderne et collaborative qui permet une approche plus humaine de l'embauche.",
|
||||
"API key": "Clé API",
|
||||
"Get opportunity": "Obtenir une opportunité",
|
||||
"Update opportunity stage": "Mettre à jour l'étape d'opportunité",
|
||||
"List opportunity forms": "Lister les formulaires d'opportunité",
|
||||
"List opportunity feedback": "Lister les commentaires sur les opportunités",
|
||||
"Add feedback to opportunity": "Ajouter un commentaire à une opportunité",
|
||||
"Custom API Call": "Appel API personnalisé",
|
||||
"Retrieve a single opportunity, i.e. an individual's unique candidacy or journey for a given job position": "Récupérer une seule opportunité, c'est-à-dire la candidature unique ou le voyage d'une personne pour un poste donné",
|
||||
"Change an Opportunity's current stage": "Changer l'étape actuelle d'une Affaire",
|
||||
"Get all forms for a given opportunity, optionally for a given form template": "Obtenir tous les formulaires pour une opportunité donnée, optionnellement pour un modèle de formulaire donné",
|
||||
"Get all feedback for a given opportunity, optionally for a given template": "Obtenir tous les commentaires pour une opportunité donnée, optionnellement pour un modèle donné",
|
||||
"Provide feedback to a candidate after an interview": "Fournir un commentaire à un candidat après une interview",
|
||||
"Make a custom API call to a specific endpoint": "Passez un appel API personnalisé à un point de terminaison spécifique",
|
||||
"Opportunity ID": "ID de l'opportunité",
|
||||
"Expand": "Agrandir",
|
||||
"Stage": "Étape",
|
||||
"Form template": "Modèle de formulaire",
|
||||
"Feedback template": "Modèle de commentaire",
|
||||
"Feedback author": "Auteur du commentaire",
|
||||
"Interview panel": "Panneau d'entretien",
|
||||
"Interview": "Interview",
|
||||
"Fields": "Champs",
|
||||
"Method": "Méthode",
|
||||
"Headers": "En-têtes",
|
||||
"Query Parameters": "Paramètres de requête",
|
||||
"Body": "Corps",
|
||||
"Response is Binary ?": "La réponse est Binaire ?",
|
||||
"No Error on Failure": "Aucune erreur en cas d'échec",
|
||||
"Timeout (in seconds)": "Délai d'attente (en secondes)",
|
||||
"If you select one, you must select an interview too": "Si vous en sélectionnez une, vous devez également sélectionner une interview",
|
||||
"Mandatory is you select an interview panel": "Vous devez sélectionner un panneau d'entrevue",
|
||||
"Ignored if you select an interview panel and an interview": "Ignoré si vous sélectionnez un panel d'entrevue et une interview",
|
||||
"Authorization headers are injected automatically from your connection.": "Les en-têtes d'autorisation sont injectés automatiquement à partir de votre connexion.",
|
||||
"Enable for files like PDFs, images, etc..": "Activer pour les fichiers comme les PDFs, les images, etc.",
|
||||
"GET": "OBTENIR",
|
||||
"POST": "POSTER",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "EFFACER",
|
||||
"DELETE": "SUPPRIMER",
|
||||
"HEAD": "TÊTE"
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"Lever is a modern, collaborative recruiting platform that powers a more human approach to hiring.": "レバーは、採用へのより人間的なアプローチを強化する現代的な共同採用プラットフォームです。",
|
||||
"API key": "API キー",
|
||||
"Get opportunity": "商談を得る",
|
||||
"Update opportunity stage": "案件ステージを更新",
|
||||
"List opportunity forms": "案件フォームの一覧",
|
||||
"List opportunity feedback": "案件のフィードバックを一覧表示する",
|
||||
"Add feedback to opportunity": "商談にフィードバックを追加",
|
||||
"Custom API Call": "カスタムAPI通話",
|
||||
"Retrieve a single opportunity, i.e. an individual's unique candidacy or journey for a given job position": "単一の機会を取得します。例えば、特定の仕事のポジションのための個人のユニークな立候補または旅。",
|
||||
"Change an Opportunity's current stage": "機会の現在のステージを変更",
|
||||
"Get all forms for a given opportunity, optionally for a given form template": "与えられた機会のすべてのフォームを取得します。必要に応じて、指定されたフォーム テンプレートのすべてのフォームを取得します。",
|
||||
"Get all feedback for a given opportunity, optionally for a given template": "任意のテンプレートに対して、特定の機会についてのすべてのフィードバックを取得します",
|
||||
"Provide feedback to a candidate after an interview": "面接後に候補者にフィードバックを与える",
|
||||
"Make a custom API call to a specific endpoint": "特定のエンドポイントへのカスタム API コールを実行します。",
|
||||
"Opportunity ID": "商談ID",
|
||||
"Expand": "展開",
|
||||
"Stage": "ステージ",
|
||||
"Form template": "フォーム テンプレート",
|
||||
"Feedback template": "フィードバックテンプレート",
|
||||
"Feedback author": "フィードバック作成者",
|
||||
"Interview panel": "インタビューパネル",
|
||||
"Interview": "インタビュー",
|
||||
"Fields": "フィールド",
|
||||
"Method": "方法",
|
||||
"Headers": "ヘッダー",
|
||||
"Query Parameters": "クエリパラメータ",
|
||||
"Body": "本文",
|
||||
"Response is Binary ?": "応答はバイナリですか?",
|
||||
"No Error on Failure": "失敗時にエラーはありません",
|
||||
"Timeout (in seconds)": "タイムアウト(秒)",
|
||||
"If you select one, you must select an interview too": "選択した場合は、面接も選択する必要があります",
|
||||
"Mandatory is you select an interview panel": "面接パネルを選択してください",
|
||||
"Ignored if you select an interview panel and an interview": "面接パネルと面接を選択すると無視されます",
|
||||
"Authorization headers are injected automatically from your connection.": "認証ヘッダは接続から自動的に注入されます。",
|
||||
"Enable for files like PDFs, images, etc..": "PDF、画像などのファイルを有効にします。",
|
||||
"GET": "取得",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "削除",
|
||||
"HEAD": "頭"
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"Lever is a modern, collaborative recruiting platform that powers a more human approach to hiring.": "Enige tijd is een modern, gezamenlijk wervingsplatform dat een meer menselijke benadering aandraagt.",
|
||||
"API key": "API sleutel",
|
||||
"Get opportunity": "Kans maken",
|
||||
"Update opportunity stage": "Kans fase bijwerken",
|
||||
"List opportunity forms": "Lijst van kansformulieren",
|
||||
"List opportunity feedback": "Geef gelegenheid feedback",
|
||||
"Add feedback to opportunity": "Voeg feedback toe aan kans",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Retrieve a single opportunity, i.e. an individual's unique candidacy or journey for a given job position": "Haal één kans op, d.w.z. de unieke kandidatuur of reis voor een bepaalde functie",
|
||||
"Change an Opportunity's current stage": "Verander het huidige stadium van een Opportunit",
|
||||
"Get all forms for a given opportunity, optionally for a given form template": "Krijg alle formulieren voor een bepaalde mogelijkheid, eventueel voor een bepaalde formuliersjabloon",
|
||||
"Get all feedback for a given opportunity, optionally for a given template": "Krijg alle feedback voor een bepaalde mogelijkheid, eventueel voor een bepaalde sjabloon",
|
||||
"Provide feedback to a candidate after an interview": "Geef feedback aan een kandidaat na een interview",
|
||||
"Make a custom API call to a specific endpoint": "Maak een aangepaste API call naar een specifiek eindpunt",
|
||||
"Opportunity ID": "Kans ID",
|
||||
"Expand": "Uitklappen",
|
||||
"Stage": "Speelveld",
|
||||
"Form template": "Formulier sjabloon",
|
||||
"Feedback template": "Feedback sjabloon",
|
||||
"Feedback author": "Feedback auteur",
|
||||
"Interview panel": "Interview paneel",
|
||||
"Interview": "Interview",
|
||||
"Fields": "Velden",
|
||||
"Method": "Methode",
|
||||
"Headers": "Kopteksten",
|
||||
"Query Parameters": "Query parameters",
|
||||
"Body": "Lichaam",
|
||||
"Response is Binary ?": "Antwoord is binair?",
|
||||
"No Error on Failure": "Geen fout bij fout",
|
||||
"Timeout (in seconds)": "Time-out (in seconden)",
|
||||
"If you select one, you must select an interview too": "Als je er één selecteert, moet je ook een interview selecteren",
|
||||
"Mandatory is you select an interview panel": "Verplicht is dat u een interview paneel selecteert",
|
||||
"Ignored if you select an interview panel and an interview": "Genegeerd als u een interview paneel en een interview selecteert",
|
||||
"Authorization headers are injected automatically from your connection.": "Autorisatie headers worden automatisch geïnjecteerd vanuit uw verbinding.",
|
||||
"Enable for files like PDFs, images, etc..": "Inschakelen voor bestanden zoals PDF's, afbeeldingen etc..",
|
||||
"GET": "KRIJG",
|
||||
"POST": "POSTE",
|
||||
"PATCH": "BEKIJK",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "VERWIJDEREN",
|
||||
"HEAD": "HOOFD"
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"Lever is a modern, collaborative recruiting platform that powers a more human approach to hiring.": "Lever é uma plataforma moderna e colaborativa de recrutamento, que potencializa uma abordagem mais humana na contratação.",
|
||||
"API key": "Chave da API",
|
||||
"Get opportunity": "Obter oportunidade",
|
||||
"Update opportunity stage": "Atualizar fase de oportunidade",
|
||||
"List opportunity forms": "Listar formulários de oportunidade",
|
||||
"List opportunity feedback": "Listar feedback da oportunidade",
|
||||
"Add feedback to opportunity": "Adicionar feedback à oportunidade",
|
||||
"Custom API Call": "Chamada de API personalizada",
|
||||
"Retrieve a single opportunity, i.e. an individual's unique candidacy or journey for a given job position": "Recupere uma única oportunidade, isto é, a candidatura ou jornada única de um indivíduo para uma determinada posição de emprego",
|
||||
"Change an Opportunity's current stage": "Alterar o estágio atual de uma Oportunidade",
|
||||
"Get all forms for a given opportunity, optionally for a given form template": "Obter todos os formulários para uma dada oportunidade, opcionalmente para um determinado modelo de formulário",
|
||||
"Get all feedback for a given opportunity, optionally for a given template": "Obter todo o feedback para uma determinada oportunidade, opcionalmente para um determinado modelo",
|
||||
"Provide feedback to a candidate after an interview": "Fornecer feedback a um candidato após uma entrevista",
|
||||
"Make a custom API call to a specific endpoint": "Faça uma chamada de API personalizada para um ponto de extremidade específico",
|
||||
"Opportunity ID": "ID da Oportunidade",
|
||||
"Expand": "Expandir",
|
||||
"Stage": "Etapa",
|
||||
"Form template": "Modelo de formulário",
|
||||
"Feedback template": "Modelo de Feedback",
|
||||
"Feedback author": "Autor da qualificação",
|
||||
"Interview panel": "Painel de entrevista",
|
||||
"Interview": "Entrevista",
|
||||
"Fields": "campos",
|
||||
"Method": "Método",
|
||||
"Headers": "Cabeçalhos",
|
||||
"Query Parameters": "Parâmetros da consulta",
|
||||
"Body": "Conteúdo",
|
||||
"Response is Binary ?": "A resposta é binária ?",
|
||||
"No Error on Failure": "Nenhum erro no Failure",
|
||||
"Timeout (in seconds)": "Tempo limite (em segundos)",
|
||||
"If you select one, you must select an interview too": "Se você selecionar um, você deve selecionar uma entrevista também",
|
||||
"Mandatory is you select an interview panel": "Obrigatório é selecionar um painel de entrevistas",
|
||||
"Ignored if you select an interview panel and an interview": "Ignorado se você selecionar um painel de entrevista e uma entrevista",
|
||||
"Authorization headers are injected automatically from your connection.": "Os cabeçalhos de autorização são inseridos automaticamente a partir da sua conexão.",
|
||||
"Enable for files like PDFs, images, etc..": "Habilitar para arquivos como PDFs, imagens, etc..",
|
||||
"GET": "OBTER",
|
||||
"POST": "POSTAR",
|
||||
"PATCH": "COMPRAR",
|
||||
"PUT": "COLOCAR",
|
||||
"DELETE": "EXCLUIR",
|
||||
"HEAD": "CABEÇA"
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"Lever": "Лишь",
|
||||
"Lever is a modern, collaborative recruiting platform that powers a more human approach to hiring.": "Ливерпуль – это современная платформа для коллективного подбора персонала, которая обеспечивает более человеческий подход к найму.",
|
||||
"API key": "API ключ",
|
||||
"Get opportunity": "Получить возможность",
|
||||
"Update opportunity stage": "Обновить возможность этапа",
|
||||
"List opportunity forms": "Список форм возможностей",
|
||||
"List opportunity feedback": "Список возможностей обратной связи",
|
||||
"Add feedback to opportunity": "Добавить отзыв о возможности",
|
||||
"Custom API Call": "Пользовательский вызов API",
|
||||
"Retrieve a single opportunity, i.e. an individual's unique candidacy or journey for a given job position": "Получить единую возможность, то есть уникальную кандидатуру человека или путешествие на определенную должность",
|
||||
"Change an Opportunity's current stage": "Изменить текущий этап возможности",
|
||||
"Get all forms for a given opportunity, optionally for a given form template": "Получить все формы для данной возможности, при необходимости для данного шаблона формы",
|
||||
"Get all feedback for a given opportunity, optionally for a given template": "Получить все отзывы для данной возможности, при необходимости для данного шаблона",
|
||||
"Provide feedback to a candidate after an interview": "Оставьте отзыв на кандидата после интервью",
|
||||
"Make a custom API call to a specific endpoint": "Сделать пользовательский API вызов к определенной конечной точке",
|
||||
"Opportunity ID": "ID сделки",
|
||||
"Expand": "Развернуть",
|
||||
"Stage": "Этап",
|
||||
"Form template": "Шаблон формы",
|
||||
"Feedback template": "Шаблон отзыва",
|
||||
"Feedback author": "Автор отзыва",
|
||||
"Interview panel": "Панель интервью",
|
||||
"Interview": "Интервью",
|
||||
"Fields": "Поля",
|
||||
"Method": "Метод",
|
||||
"Headers": "Заголовки",
|
||||
"Query Parameters": "Параметры запроса",
|
||||
"Body": "Тело",
|
||||
"No Error on Failure": "Нет ошибок при ошибке",
|
||||
"Timeout (in seconds)": "Таймаут (в секундах)",
|
||||
"If you select one, you must select an interview too": "Если вы выберете его, вы должны выбрать интервью",
|
||||
"Mandatory is you select an interview panel": "Обязательно выберите панель интервью",
|
||||
"Ignored if you select an interview panel and an interview": "Игнорируется, если вы выбираете группу интервью и интервью",
|
||||
"Authorization headers are injected automatically from your connection.": "Заголовки авторизации включаются автоматически из вашего соединения.",
|
||||
"GET": "ПОЛУЧИТЬ",
|
||||
"POST": "ПОСТ",
|
||||
"PATCH": "ПАТЧ",
|
||||
"PUT": "ПОКУПИТЬ",
|
||||
"DELETE": "УДАЛИТЬ",
|
||||
"HEAD": "HEAD"
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"Lever is a modern, collaborative recruiting platform that powers a more human approach to hiring.": "Lever is a modern, collaborative recruiting platform that powers a more human approach to hiring.",
|
||||
"API key": "API key",
|
||||
"Get opportunity": "Get opportunity",
|
||||
"Update opportunity stage": "Update opportunity stage",
|
||||
"List opportunity forms": "List opportunity forms",
|
||||
"List opportunity feedback": "List opportunity feedback",
|
||||
"Add feedback to opportunity": "Add feedback to opportunity",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Retrieve a single opportunity, i.e. an individual's unique candidacy or journey for a given job position": "Retrieve a single opportunity, i.e. an individual's unique candidacy or journey for a given job position",
|
||||
"Change an Opportunity's current stage": "Change an Opportunity's current stage",
|
||||
"Get all forms for a given opportunity, optionally for a given form template": "Get all forms for a given opportunity, optionally for a given form template",
|
||||
"Get all feedback for a given opportunity, optionally for a given template": "Get all feedback for a given opportunity, optionally for a given template",
|
||||
"Provide feedback to a candidate after an interview": "Provide feedback to a candidate after an interview",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Opportunity ID": "Opportunity ID",
|
||||
"Expand": "Expand",
|
||||
"Stage": "Stage",
|
||||
"Form template": "Form template",
|
||||
"Feedback template": "Feedback template",
|
||||
"Feedback author": "Feedback author",
|
||||
"Interview panel": "Interview panel",
|
||||
"Interview": "Interview",
|
||||
"Fields": "Fields",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"Response is Binary ?": "Response is Binary ?",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"If you select one, you must select an interview too": "If you select one, you must select an interview too",
|
||||
"Mandatory is you select an interview panel": "Mandatory is you select an interview panel",
|
||||
"Ignored if you select an interview panel and an interview": "Ignored if you select an interview panel and an interview",
|
||||
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
|
||||
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD"
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"Lever": "Lever",
|
||||
"Lever is a modern, collaborative recruiting platform that powers a more human approach to hiring.": "Lever is a modern, collaborative recruiting platform that powers a more human approach to hiring.",
|
||||
"API key": "API key",
|
||||
"Get opportunity": "Get opportunity",
|
||||
"Update opportunity stage": "Update opportunity stage",
|
||||
"List opportunity forms": "List opportunity forms",
|
||||
"List opportunity feedback": "List opportunity feedback",
|
||||
"Add feedback to opportunity": "Add feedback to opportunity",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Retrieve a single opportunity, i.e. an individual's unique candidacy or journey for a given job position": "Retrieve a single opportunity, i.e. an individual's unique candidacy or journey for a given job position",
|
||||
"Change an Opportunity's current stage": "Change an Opportunity's current stage",
|
||||
"Get all forms for a given opportunity, optionally for a given form template": "Get all forms for a given opportunity, optionally for a given form template",
|
||||
"Get all feedback for a given opportunity, optionally for a given template": "Get all feedback for a given opportunity, optionally for a given template",
|
||||
"Provide feedback to a candidate after an interview": "Provide feedback to a candidate after an interview",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Opportunity ID": "Opportunity ID",
|
||||
"Expand": "Expand",
|
||||
"Stage": "Stage",
|
||||
"Form template": "Form template",
|
||||
"Feedback template": "Feedback template",
|
||||
"Feedback author": "Feedback author",
|
||||
"Interview panel": "Interview panel",
|
||||
"Interview": "Interview",
|
||||
"Fields": "Fields",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"If you select one, you must select an interview too": "If you select one, you must select an interview too",
|
||||
"Mandatory is you select an interview panel": "Mandatory is you select an interview panel",
|
||||
"Ignored if you select an interview panel and an interview": "Ignored if you select an interview panel and an interview",
|
||||
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD"
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"Lever is a modern, collaborative recruiting platform that powers a more human approach to hiring.": "Lever is a modern, collaborative recruiting platform that powers a more human approach to hiring.",
|
||||
"API key": "API key",
|
||||
"Get opportunity": "Get opportunity",
|
||||
"Update opportunity stage": "Update opportunity stage",
|
||||
"List opportunity forms": "List opportunity forms",
|
||||
"List opportunity feedback": "List opportunity feedback",
|
||||
"Add feedback to opportunity": "Add feedback to opportunity",
|
||||
"Custom API Call": "自定义 API 呼叫",
|
||||
"Retrieve a single opportunity, i.e. an individual's unique candidacy or journey for a given job position": "Retrieve a single opportunity, i.e. an individual's unique candidacy or journey for a given job position",
|
||||
"Change an Opportunity's current stage": "Change an Opportunity's current stage",
|
||||
"Get all forms for a given opportunity, optionally for a given form template": "Get all forms for a given opportunity, optionally for a given form template",
|
||||
"Get all feedback for a given opportunity, optionally for a given template": "Get all feedback for a given opportunity, optionally for a given template",
|
||||
"Provide feedback to a candidate after an interview": "Provide feedback to a candidate after an interview",
|
||||
"Make a custom API call to a specific endpoint": "将一个自定义 API 调用到一个特定的终点",
|
||||
"Opportunity ID": "Opportunity ID",
|
||||
"Expand": "Expand",
|
||||
"Stage": "Stage",
|
||||
"Form template": "Form template",
|
||||
"Feedback template": "Feedback template",
|
||||
"Feedback author": "Feedback author",
|
||||
"Interview panel": "Interview panel",
|
||||
"Interview": "Interview",
|
||||
"Fields": "Fields",
|
||||
"Method": "方法",
|
||||
"Headers": "信头",
|
||||
"Query Parameters": "查询参数",
|
||||
"Body": "正文内容",
|
||||
"Response is Binary ?": "Response is Binary ?",
|
||||
"No Error on Failure": "失败时没有错误",
|
||||
"Timeout (in seconds)": "超时(秒)",
|
||||
"If you select one, you must select an interview too": "If you select one, you must select an interview too",
|
||||
"Mandatory is you select an interview panel": "Mandatory is you select an interview panel",
|
||||
"Ignored if you select an interview panel and an interview": "Ignored if you select an interview panel and an interview",
|
||||
"Authorization headers are injected automatically from your connection.": "授权头自动从您的连接中注入。",
|
||||
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
|
||||
"GET": "获取",
|
||||
"POST": "帖子",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "弹出",
|
||||
"DELETE": "删除",
|
||||
"HEAD": "黑色"
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import {
|
||||
AppConnectionValueForAuthProperty,
|
||||
createPiece,
|
||||
PieceAuth,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { createCustomApiCallAction } from '@activepieces/pieces-common';
|
||||
import { getOpportunity } from './lib/actions/get-opportunity';
|
||||
import { updateOpportunityStage } from './lib/actions/update-opportunity-stage';
|
||||
import { listOpportunityForms } from './lib/actions/list-opportunity-forms';
|
||||
import { listOpportunityFeedback } from './lib/actions/list-opportunity-feedback';
|
||||
import { addFeedbackToOpportunity } from './lib/actions/add-feedback-to-opportunity';
|
||||
import { PieceCategory } from '@activepieces/shared';
|
||||
|
||||
export const LEVER_BASE_URL = 'https://api.lever.co/v1';
|
||||
|
||||
export const leverAuth = PieceAuth.CustomAuth({
|
||||
props: {
|
||||
apiKey: PieceAuth.SecretText({
|
||||
displayName: 'API key',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
required: true,
|
||||
});
|
||||
|
||||
export type LeverAuth = AppConnectionValueForAuthProperty<typeof leverAuth>;
|
||||
export const lever = createPiece({
|
||||
displayName: 'Lever',
|
||||
auth: leverAuth,
|
||||
description:
|
||||
'Lever is a modern, collaborative recruiting platform that powers a more human approach to hiring.',
|
||||
categories: [PieceCategory.HUMAN_RESOURCES],
|
||||
minimumSupportedRelease: '0.30.0',
|
||||
logoUrl: 'https://cdn.activepieces.com/pieces/lever.png',
|
||||
authors: ['AdamSelene'],
|
||||
actions: [
|
||||
getOpportunity,
|
||||
updateOpportunityStage,
|
||||
listOpportunityForms,
|
||||
listOpportunityFeedback,
|
||||
addFeedbackToOpportunity,
|
||||
createCustomApiCallAction({
|
||||
baseUrl: () => {
|
||||
return LEVER_BASE_URL;
|
||||
},
|
||||
auth: leverAuth,
|
||||
authMapping: async (auth) => {
|
||||
const { apiKey } = auth.props;
|
||||
return {
|
||||
Authorization:
|
||||
'Basic ' + Buffer.from(`${apiKey}:`).toString('base64'),
|
||||
};
|
||||
},
|
||||
}),
|
||||
],
|
||||
triggers: [],
|
||||
});
|
||||
@@ -0,0 +1,360 @@
|
||||
import {
|
||||
createAction,
|
||||
DynamicPropsValue,
|
||||
Property,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { LEVER_BASE_URL, LeverAuth, leverAuth } from '../..';
|
||||
import {
|
||||
AuthenticationType,
|
||||
httpClient,
|
||||
HttpMethod,
|
||||
} from '@activepieces/pieces-common';
|
||||
import { LeverFieldMapping } from '../common';
|
||||
|
||||
export const addFeedbackToOpportunity = createAction({
|
||||
name: 'addFeedbackToOpportunity',
|
||||
displayName: 'Add feedback to opportunity',
|
||||
description: 'Provide feedback to a candidate after an interview',
|
||||
auth: leverAuth,
|
||||
props: {
|
||||
performAs: Property.Dropdown({
|
||||
auth: leverAuth,
|
||||
displayName: 'Feedback author',
|
||||
required: true,
|
||||
refreshers: ['auth'],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect first.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
const users = [];
|
||||
let cursor = undefined;
|
||||
do {
|
||||
const queryParams: Record<string, string> = {
|
||||
include: 'name',
|
||||
};
|
||||
if (cursor) {
|
||||
queryParams['offset'] = cursor;
|
||||
}
|
||||
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `${LEVER_BASE_URL}/users`,
|
||||
queryParams: queryParams,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username: auth.props.apiKey,
|
||||
password: '',
|
||||
},
|
||||
});
|
||||
cursor = response.body.next;
|
||||
const usersPage = response.body.data.map(
|
||||
(user: { id: string; name: string }) => {
|
||||
return {
|
||||
label: user.name,
|
||||
value: user.id,
|
||||
};
|
||||
}
|
||||
);
|
||||
users.push(...usersPage);
|
||||
} while (cursor !== undefined);
|
||||
|
||||
return {
|
||||
options: users,
|
||||
};
|
||||
},
|
||||
}),
|
||||
opportunityId: Property.ShortText({
|
||||
displayName: 'Opportunity ID',
|
||||
required: true,
|
||||
}),
|
||||
panelId: Property.Dropdown({
|
||||
auth: leverAuth,
|
||||
displayName: 'Interview panel',
|
||||
description: 'If you select one, you must select an interview too',
|
||||
required: false,
|
||||
refreshers: ['auth', 'opportunityId'],
|
||||
options: async ({ auth, opportunityId }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect first.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
if (!opportunityId) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please select a candidate (opportunity).',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `${LEVER_BASE_URL}/opportunities/${opportunityId}/panels?expand=stage&include=id&include=stage&include=start`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username: auth.props.apiKey,
|
||||
password: '',
|
||||
},
|
||||
});
|
||||
return {
|
||||
options: response.body.data.map(
|
||||
(panel: { id: string; start: number; stage: { text: string } }) => {
|
||||
const interviewDate = new Date(panel.start);
|
||||
return {
|
||||
label: `${interviewDate.toLocaleDateString()} - ${
|
||||
panel.stage.text
|
||||
}`,
|
||||
value: panel.id,
|
||||
};
|
||||
}
|
||||
),
|
||||
};
|
||||
},
|
||||
}),
|
||||
interviewId: Property.Dropdown({
|
||||
auth: leverAuth,
|
||||
displayName: 'Interview',
|
||||
description: 'Mandatory is you select an interview panel',
|
||||
required: false,
|
||||
refreshers: ['auth', 'opportunityId', 'panelId'],
|
||||
options: async ({ auth, opportunityId, panelId }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect first.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
if (!opportunityId) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please select a candidate (opportunity).',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
if (!panelId) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please select an interview panel.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `${LEVER_BASE_URL}/opportunities/${opportunityId}/panels/${panelId}?include=interviews`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username: auth.props.apiKey,
|
||||
password: '',
|
||||
},
|
||||
});
|
||||
return {
|
||||
options: response.body.data.interviews.map(
|
||||
(interview: { id: string; subject: string }) => {
|
||||
return { label: interview.subject, value: interview.id };
|
||||
}
|
||||
),
|
||||
};
|
||||
},
|
||||
}),
|
||||
feedbackTemplateId: Property.Dropdown({
|
||||
auth: leverAuth,
|
||||
displayName: 'Feedback template',
|
||||
description: 'Ignored if you select an interview panel and an interview',
|
||||
required: false,
|
||||
refreshers: ['auth'],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect first.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `${LEVER_BASE_URL}/feedback_templates`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username: auth.props.apiKey,
|
||||
password: '',
|
||||
},
|
||||
});
|
||||
return {
|
||||
options: response.body.data.map(
|
||||
(template: { id: string; text: string }) => {
|
||||
return {
|
||||
label: template.text,
|
||||
value: template.id,
|
||||
};
|
||||
}
|
||||
),
|
||||
};
|
||||
},
|
||||
}),
|
||||
feedbackFields: Property.DynamicProperties({
|
||||
auth: leverAuth,
|
||||
displayName: 'Fields',
|
||||
required: true,
|
||||
refreshers: [
|
||||
'auth',
|
||||
'opportunityId',
|
||||
'panelId',
|
||||
'interviewId',
|
||||
'feedbackTemplateId',
|
||||
],
|
||||
props: async ({
|
||||
auth,
|
||||
opportunityId,
|
||||
panelId,
|
||||
interviewId,
|
||||
feedbackTemplateId,
|
||||
}) => {
|
||||
if (
|
||||
!auth ||
|
||||
!opportunityId ||
|
||||
!(feedbackTemplateId || (panelId && interviewId))
|
||||
) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder:
|
||||
'Please connect your Lever account first and select an interview or a feedback template',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const fields: DynamicPropsValue = {};
|
||||
const templateId =
|
||||
panelId && interviewId
|
||||
? await getFeedbackTemplateForInterview(
|
||||
opportunityId,
|
||||
panelId,
|
||||
interviewId,
|
||||
auth
|
||||
)
|
||||
: feedbackTemplateId;
|
||||
|
||||
try {
|
||||
const feedbackTemplateResponse = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `${LEVER_BASE_URL}/feedback_templates/${templateId}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username: auth.props.apiKey,
|
||||
password: '',
|
||||
},
|
||||
});
|
||||
feedbackTemplateResponse.body.data.fields.map(
|
||||
(field: {
|
||||
id: string;
|
||||
text: string;
|
||||
description: string;
|
||||
required: boolean;
|
||||
type: string;
|
||||
options?: { text: string; optionId: string }[];
|
||||
scores?: { text: string; description: string }[];
|
||||
}) => {
|
||||
const mappedField =
|
||||
LeverFieldMapping[field.type] || LeverFieldMapping['default'];
|
||||
mappedField.buildActivepieceType(fields, field);
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(
|
||||
'Unexpected error while building dynamic properties',
|
||||
e
|
||||
);
|
||||
}
|
||||
return fields;
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
const templateId =
|
||||
propsValue.panelId && propsValue.interviewId
|
||||
? await getFeedbackTemplateForInterview(
|
||||
propsValue.opportunityId,
|
||||
propsValue.panelId,
|
||||
propsValue.interviewId,
|
||||
auth
|
||||
)
|
||||
: propsValue.feedbackTemplateId;
|
||||
|
||||
const feedbackTemplateResponse = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `${LEVER_BASE_URL}/feedback_templates/${templateId}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username: auth.props.apiKey,
|
||||
password: '',
|
||||
},
|
||||
});
|
||||
|
||||
const templateFields = feedbackTemplateResponse.body.data.fields;
|
||||
const groupedValues = Object.entries(propsValue.feedbackFields).reduce<
|
||||
Record<string, DynamicPropsValue[]>
|
||||
>((values, [fieldId, fieldValue]: [string, DynamicPropsValue]) => {
|
||||
const canonicalId = fieldId.substring(0, 36);
|
||||
values[canonicalId] = values[canonicalId] ?? [];
|
||||
values[canonicalId].push(fieldValue);
|
||||
return values;
|
||||
}, {});
|
||||
|
||||
const payload = {
|
||||
baseTemplateId: templateId,
|
||||
panel: propsValue.panelId,
|
||||
interview: propsValue.interviewId,
|
||||
fieldValues: Object.entries(groupedValues).map(([fieldId, values]) => {
|
||||
const templateField = templateFields.find(
|
||||
(tf: { id: string }) => tf.id === fieldId
|
||||
);
|
||||
const mappedField =
|
||||
templateField.type in LeverFieldMapping
|
||||
? LeverFieldMapping[templateField.type]
|
||||
: LeverFieldMapping['default'];
|
||||
return mappedField.buildLeverType(fieldId, values);
|
||||
}),
|
||||
};
|
||||
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.POST,
|
||||
url: `${LEVER_BASE_URL}/opportunities/${propsValue.opportunityId}/feedback?perform_as=${propsValue.performAs}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username: auth.props.apiKey,
|
||||
password: '',
|
||||
},
|
||||
body: payload,
|
||||
});
|
||||
|
||||
return response.body.data;
|
||||
},
|
||||
});
|
||||
|
||||
async function getFeedbackTemplateForInterview(
|
||||
opportunityId: string | DynamicPropsValue,
|
||||
panelId: string | DynamicPropsValue,
|
||||
interviewId: string | DynamicPropsValue,
|
||||
auth: LeverAuth
|
||||
) {
|
||||
const interviewResponse = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `${LEVER_BASE_URL}/opportunities/${opportunityId}/panels/${panelId}?include=interviews`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username: auth.props.apiKey,
|
||||
password: '',
|
||||
},
|
||||
});
|
||||
const interview = interviewResponse.body.data.interviews.find(
|
||||
(interview: { id: string }) =>
|
||||
interview.id === (interviewId as unknown as string)
|
||||
);
|
||||
return interview.feedbackTemplate;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import qs from 'qs';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { LEVER_BASE_URL, leverAuth } from '../..';
|
||||
import {
|
||||
AuthenticationType,
|
||||
httpClient,
|
||||
HttpMethod,
|
||||
} from '@activepieces/pieces-common';
|
||||
|
||||
export const getOpportunity = createAction({
|
||||
name: 'getOpportunity',
|
||||
displayName: 'Get opportunity',
|
||||
description:
|
||||
"Retrieve a single opportunity, i.e. an individual's unique candidacy or journey for a given job position",
|
||||
auth: leverAuth,
|
||||
props: {
|
||||
opportunityId: Property.ShortText({
|
||||
displayName: 'Opportunity ID',
|
||||
required: true,
|
||||
}),
|
||||
expand: Property.Array({
|
||||
displayName: 'Expand',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `${LEVER_BASE_URL}/opportunities/${
|
||||
propsValue.opportunityId
|
||||
}?${decodeURIComponent(
|
||||
qs.stringify({ expand: propsValue.expand }, { arrayFormat: 'repeat' })
|
||||
)}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username: auth.props.apiKey,
|
||||
password: '',
|
||||
},
|
||||
});
|
||||
return response.body.data;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,71 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { LEVER_BASE_URL, LeverAuth, leverAuth } from '../..';
|
||||
import {
|
||||
AuthenticationType,
|
||||
httpClient,
|
||||
HttpMethod,
|
||||
} from '@activepieces/pieces-common';
|
||||
|
||||
export const listOpportunityFeedback = createAction({
|
||||
name: 'listOpportunityFeedback',
|
||||
displayName: 'List opportunity feedback',
|
||||
description:
|
||||
'Get all feedback for a given opportunity, optionally for a given template',
|
||||
auth: leverAuth,
|
||||
props: {
|
||||
opportunityId: Property.ShortText({
|
||||
displayName: 'Opportunity ID',
|
||||
required: true,
|
||||
}),
|
||||
template: Property.Dropdown({
|
||||
auth: leverAuth,
|
||||
displayName: 'Feedback template',
|
||||
required: false,
|
||||
refreshers: ['auth'],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect first.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `${LEVER_BASE_URL}/feedback_templates?include=text`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username: auth.props.apiKey,
|
||||
password: '',
|
||||
},
|
||||
});
|
||||
return {
|
||||
options: response.body.data.map(
|
||||
(template: { text: string; id: string }) => {
|
||||
return { label: template.text, value: template.id };
|
||||
}
|
||||
),
|
||||
};
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `${LEVER_BASE_URL}/opportunities/${propsValue.opportunityId}/feedback`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username: auth.props.apiKey,
|
||||
password: '',
|
||||
},
|
||||
});
|
||||
const feedback = response.body.data;
|
||||
if (propsValue.template) {
|
||||
return feedback.filter(
|
||||
(form: { baseTemplateId: string }) =>
|
||||
form.baseTemplateId === propsValue.template
|
||||
);
|
||||
}
|
||||
return feedback;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,71 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { LEVER_BASE_URL, LeverAuth, leverAuth } from '../..';
|
||||
import {
|
||||
AuthenticationType,
|
||||
httpClient,
|
||||
HttpMethod,
|
||||
} from '@activepieces/pieces-common';
|
||||
|
||||
export const listOpportunityForms = createAction({
|
||||
name: 'listOpportunityForms',
|
||||
displayName: 'List opportunity forms',
|
||||
description:
|
||||
'Get all forms for a given opportunity, optionally for a given form template',
|
||||
auth: leverAuth,
|
||||
props: {
|
||||
opportunityId: Property.ShortText({
|
||||
displayName: 'Opportunity ID',
|
||||
required: true,
|
||||
}),
|
||||
template: Property.Dropdown({
|
||||
auth: leverAuth,
|
||||
displayName: 'Form template',
|
||||
required: false,
|
||||
refreshers: ['auth'],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect first.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `${LEVER_BASE_URL}/form_templates?include=text`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username: auth.props.apiKey,
|
||||
password: '',
|
||||
},
|
||||
});
|
||||
return {
|
||||
options: response.body.data.map(
|
||||
(template: { text: string; id: string }) => {
|
||||
return { label: template.text, value: template.id };
|
||||
}
|
||||
),
|
||||
};
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `${LEVER_BASE_URL}/opportunities/${propsValue.opportunityId}/forms`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username: auth.props.apiKey,
|
||||
password: '',
|
||||
},
|
||||
});
|
||||
const forms = response.body.data;
|
||||
if (propsValue.template) {
|
||||
return forms.filter(
|
||||
(form: { baseTemplateId: string }) =>
|
||||
form.baseTemplateId === propsValue.template
|
||||
);
|
||||
}
|
||||
return forms;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,65 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import {
|
||||
AuthenticationType,
|
||||
httpClient,
|
||||
HttpMethod,
|
||||
} from '@activepieces/pieces-common';
|
||||
import { LEVER_BASE_URL, LeverAuth, leverAuth } from '../..';
|
||||
|
||||
export const updateOpportunityStage = createAction({
|
||||
name: 'updateOpportunityStage',
|
||||
displayName: 'Update opportunity stage',
|
||||
description: "Change an Opportunity's current stage",
|
||||
auth: leverAuth,
|
||||
props: {
|
||||
opportunityId: Property.ShortText({
|
||||
displayName: 'Opportunity ID',
|
||||
required: true,
|
||||
}),
|
||||
stage: Property.Dropdown({
|
||||
auth: leverAuth,
|
||||
displayName: 'Stage',
|
||||
required: true,
|
||||
refreshers: ['auth'],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect first.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `${LEVER_BASE_URL}/stages`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username: auth.props.apiKey,
|
||||
password: '',
|
||||
},
|
||||
});
|
||||
return {
|
||||
options: response.body.data.map(
|
||||
(stage: { text: string; id: string }) => {
|
||||
return { label: stage.text, value: stage.id };
|
||||
}
|
||||
),
|
||||
};
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.PUT,
|
||||
url: `${LEVER_BASE_URL}/opportunities/${propsValue.opportunityId}/stage`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username: auth.props.apiKey,
|
||||
password: '',
|
||||
},
|
||||
body: { stage: propsValue.stage },
|
||||
});
|
||||
|
||||
return response.body.data;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,176 @@
|
||||
import { DynamicPropsValue, Property } from '@activepieces/pieces-framework';
|
||||
|
||||
export type LeverFieldType = {
|
||||
id: string;
|
||||
text: string;
|
||||
description: string;
|
||||
required: boolean;
|
||||
type: string;
|
||||
options?: { text: string; optionId: string }[];
|
||||
scores?: { text: string; description: string }[];
|
||||
};
|
||||
|
||||
export const LeverFieldMapping: Record<
|
||||
string,
|
||||
{
|
||||
buildActivepieceType: (
|
||||
fields: DynamicPropsValue,
|
||||
field: LeverFieldType
|
||||
) => void;
|
||||
buildLeverType: (
|
||||
id: string,
|
||||
propsValues: DynamicPropsValue[]
|
||||
) => {
|
||||
id: string;
|
||||
value:
|
||||
| string
|
||||
| string[]
|
||||
| number
|
||||
| number[]
|
||||
| { score: number; comment?: string }[];
|
||||
};
|
||||
}
|
||||
> = {
|
||||
default: {
|
||||
buildActivepieceType: (fields, field) =>
|
||||
(fields[field.id] = Property.ShortText({
|
||||
displayName: field.text,
|
||||
description: field.description,
|
||||
required: field.required,
|
||||
})),
|
||||
buildLeverType: (id, propsValues) => ({
|
||||
id,
|
||||
value: propsValues[0] as unknown as string,
|
||||
}),
|
||||
},
|
||||
textarea: {
|
||||
buildActivepieceType: (fields, field) =>
|
||||
(fields[field.id] = Property.LongText({
|
||||
displayName: field.text,
|
||||
description: field.description,
|
||||
required: field.required,
|
||||
})),
|
||||
buildLeverType: (id, propsValues) => ({
|
||||
id,
|
||||
value: propsValues[0] as unknown as string,
|
||||
}),
|
||||
},
|
||||
'yes-no': {
|
||||
buildActivepieceType: (fields, field) =>
|
||||
(fields[field.id] = Property.Checkbox({
|
||||
displayName: field.text,
|
||||
description: field.description,
|
||||
required: field.required,
|
||||
})),
|
||||
buildLeverType: (id, propsValues) => {
|
||||
const value = propsValues[0] as unknown as boolean;
|
||||
return {
|
||||
id,
|
||||
value: value === true ? 'yes' : value === false ? 'no' : 'null',
|
||||
};
|
||||
},
|
||||
},
|
||||
dropdown: {
|
||||
buildActivepieceType: (fields, field) =>
|
||||
(fields[field.id] = Property.StaticDropdown({
|
||||
displayName: field.text,
|
||||
description: field.description,
|
||||
required: field.required,
|
||||
options: {
|
||||
disabled: false,
|
||||
options:
|
||||
field.options?.map((option: { text: string; optionId: string }) => {
|
||||
return { value: option.text, label: option.text };
|
||||
}) || [],
|
||||
},
|
||||
})),
|
||||
buildLeverType: (id, propsValues) => ({
|
||||
id,
|
||||
value: propsValues[0] as unknown as string,
|
||||
}),
|
||||
},
|
||||
'multiple-choice': {
|
||||
buildActivepieceType: (fields, field) =>
|
||||
(fields[field.id] = Property.StaticDropdown({
|
||||
displayName: field.text,
|
||||
description: field.description,
|
||||
required: field.required,
|
||||
options: {
|
||||
disabled: false,
|
||||
options:
|
||||
field.options?.map((option: { text: string; optionId: string }) => {
|
||||
return { value: option.text, label: option.text };
|
||||
}) || [],
|
||||
},
|
||||
})),
|
||||
buildLeverType: (id, propsValues) => ({
|
||||
id,
|
||||
value: propsValues[0] as unknown as string,
|
||||
}),
|
||||
},
|
||||
'multiple-select': {
|
||||
buildActivepieceType: (fields, field) =>
|
||||
(fields[field.id] = Property.StaticMultiSelectDropdown({
|
||||
displayName: field.text,
|
||||
description: field.description,
|
||||
required: field.required,
|
||||
options: {
|
||||
disabled: false,
|
||||
options:
|
||||
field.options?.map((option: { text: string; optionId: string }) => {
|
||||
return { value: option.text, label: option.text };
|
||||
}) || [],
|
||||
},
|
||||
})),
|
||||
buildLeverType: (id, propsValues) => ({
|
||||
id,
|
||||
value: propsValues[0] as unknown as string[],
|
||||
}),
|
||||
},
|
||||
'score-system': {
|
||||
buildActivepieceType: (fields, field) =>
|
||||
(fields[field.id] = Property.StaticDropdown({
|
||||
displayName: field.text,
|
||||
description: field.description,
|
||||
required: field.required,
|
||||
options: {
|
||||
options:
|
||||
field.options?.map((option) => {
|
||||
return { value: option.text, label: option.text };
|
||||
}) || [],
|
||||
},
|
||||
})),
|
||||
buildLeverType: (id, propsValues) => ({
|
||||
id,
|
||||
value: propsValues[0] as unknown as string,
|
||||
}),
|
||||
},
|
||||
scorecard: {
|
||||
buildActivepieceType: (fields, field) =>
|
||||
field.scores?.map((score, index) => {
|
||||
fields[`${field.id}-${index}`] = Property.StaticDropdown({
|
||||
displayName: score.text,
|
||||
description: score.description,
|
||||
required: field.required,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'n.a.', value: 0 },
|
||||
{ label: '👎👎', value: 1 },
|
||||
{ label: '👎', value: 2 },
|
||||
{ label: '👍', value: 3 },
|
||||
{ label: '👍👍', value: 4 },
|
||||
],
|
||||
},
|
||||
});
|
||||
}),
|
||||
buildLeverType: (id, propsValues) => ({
|
||||
id,
|
||||
value: propsValues.map((propsValue: DynamicPropsValue) => {
|
||||
return {
|
||||
score: propsValue as unknown as number,
|
||||
comment: '',
|
||||
};
|
||||
}),
|
||||
}),
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"outDir": "../../../../dist/out-tsc",
|
||||
"declaration": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
Reference in New Issue
Block a user