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,18 @@
|
||||
{
|
||||
"extends": ["../../../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# pieces-linkedin
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Running lint
|
||||
|
||||
Run `nx lint pieces-linkedin` to execute the lint via [ESLint](https://eslint.org/).
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "@activepieces/piece-linkedin",
|
||||
"version": "0.1.20"
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "pieces-linkedin",
|
||||
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "packages/pieces/community/linkedin/src",
|
||||
"projectType": "library",
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/js:tsc",
|
||||
"outputs": [
|
||||
"{options.outputPath}"
|
||||
],
|
||||
"options": {
|
||||
"outputPath": "dist/packages/pieces/community/linkedin",
|
||||
"tsConfig": "packages/pieces/community/linkedin/tsconfig.lib.json",
|
||||
"packageJson": "packages/pieces/community/linkedin/package.json",
|
||||
"main": "packages/pieces/community/linkedin/src/index.ts",
|
||||
"assets": [
|
||||
"packages/pieces/community/linkedin/*.md",
|
||||
{
|
||||
"input": "packages/pieces/community/linkedin/src/i18n",
|
||||
"output": "./src/i18n",
|
||||
"glob": "**/!(i18n.json)"
|
||||
}
|
||||
],
|
||||
"buildableProjectDepsInPackageJsonType": "dependencies",
|
||||
"updateBuildableProjectDepsInPackageJson": true
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
"prebuild"
|
||||
]
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": [
|
||||
"{options.outputFile}"
|
||||
]
|
||||
},
|
||||
"prebuild": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"cwd": "packages/pieces/community/linkedin",
|
||||
"command": "bun install --no-save --silent"
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
]
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"LinkedIn": "LinkedIn",
|
||||
"Connect and network with professionals": "Connect and network with professionals",
|
||||
"Create Share Update": "Create Share Update",
|
||||
"Create Company Update": "Create Company Update",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Create a share update on LinkedIn": "Create a share update on LinkedIn",
|
||||
"Create a new company update for Company Page": "Create a new company update for Company Page",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Text": "Text",
|
||||
"Visibility": "Visibility",
|
||||
"Image": "Image",
|
||||
"Content - URL": "Content - URL",
|
||||
"Content - Title": "Content - Title",
|
||||
"Content - Description": "Content - Description",
|
||||
"Company Page": "Company Page",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"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,31 @@
|
||||
{
|
||||
"Connect and network with professionals": "Verbinden und Netzwerk mit Profis",
|
||||
"Create Share Update": "Teilen Update erstellen",
|
||||
"Create Company Update": "Unternehmensupdate erstellen",
|
||||
"Custom API Call": "Eigener API-Aufruf",
|
||||
"Create a share update on LinkedIn": "Ein Freigabe-Update auf LinkedIn erstellen",
|
||||
"Create a new company update for Company Page": "Neues Unternehmensupdate für Unternehmensseite erstellen",
|
||||
"Make a custom API call to a specific endpoint": "Einen benutzerdefinierten API-Aufruf an einen bestimmten Endpunkt machen",
|
||||
"Text": "Text",
|
||||
"Visibility": "Sichtbarkeit",
|
||||
"Image": "Bild",
|
||||
"Content - URL": "Inhalt - URL",
|
||||
"Content - Title": "Inhalt - Titel",
|
||||
"Content - Description": "Inhalt - Beschreibung",
|
||||
"Company Page": "Firmenseite",
|
||||
"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)",
|
||||
"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,31 @@
|
||||
{
|
||||
"Connect and network with professionals": "Conectar y conectar a la red con profesionales",
|
||||
"Create Share Update": "Crear Actualización de Compartir",
|
||||
"Create Company Update": "Crear actualización de la empresa",
|
||||
"Custom API Call": "Llamada API personalizada",
|
||||
"Create a share update on LinkedIn": "Crear una actualización para compartir en LinkedIn",
|
||||
"Create a new company update for Company Page": "Crear una nueva actualización de la empresa para la página de la empresa",
|
||||
"Make a custom API call to a specific endpoint": "Hacer una llamada API personalizada a un extremo específico",
|
||||
"Text": "Texto",
|
||||
"Visibility": "Visibilidad",
|
||||
"Image": "Imagen",
|
||||
"Content - URL": "Contenido - URL",
|
||||
"Content - Title": "Contenido - Título",
|
||||
"Content - Description": "Contenido - Descripción",
|
||||
"Company Page": "Página de la empresa",
|
||||
"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)",
|
||||
"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,31 @@
|
||||
{
|
||||
"Connect and network with professionals": "Se connecter et se connecter avec des professionnels",
|
||||
"Create Share Update": "Créer une mise à jour de partage",
|
||||
"Create Company Update": "Créer une mise à jour de la société",
|
||||
"Custom API Call": "Appel API personnalisé",
|
||||
"Create a share update on LinkedIn": "Créer une mise à jour de partage sur LinkedIn",
|
||||
"Create a new company update for Company Page": "Créer une nouvelle mise à jour de la société pour la page de l'entreprise",
|
||||
"Make a custom API call to a specific endpoint": "Passez un appel API personnalisé à un point de terminaison spécifique",
|
||||
"Text": "Texte du texte",
|
||||
"Visibility": "Visibilité",
|
||||
"Image": "Image",
|
||||
"Content - URL": "Contenu - URL",
|
||||
"Content - Title": "Contenu - Titre",
|
||||
"Content - Description": "Contenu - Description",
|
||||
"Company Page": "Page de la société",
|
||||
"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)",
|
||||
"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": "HEAD"
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"LinkedIn": "LinkedIn",
|
||||
"Connect and network with professionals": "Connect and network with professionals",
|
||||
"Create Share Update": "Create Share Update",
|
||||
"Create Company Update": "Create Company Update",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Create a share update on LinkedIn": "Create a share update on LinkedIn",
|
||||
"Create a new company update for Company Page": "Create a new company update for Company Page",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Text": "Text",
|
||||
"Visibility": "Visibility",
|
||||
"Image": "Image",
|
||||
"Content - URL": "Content - URL",
|
||||
"Content - Title": "Content - Title",
|
||||
"Content - Description": "Content - Description",
|
||||
"Company Page": "Company Page",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"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,30 @@
|
||||
{
|
||||
"LinkedIn": "LinkedIn",
|
||||
"Connect and network with professionals": "Connect and network with professionals",
|
||||
"Create Share Update": "Create Share Update",
|
||||
"Create Company Update": "Create Company Update",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Create a share update on LinkedIn": "Create a share update on LinkedIn",
|
||||
"Create a new company update for Company Page": "Create a new company update for Company Page",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Text": "Text",
|
||||
"Visibility": "Visibility",
|
||||
"Image": "Image",
|
||||
"Content - URL": "Content - URL",
|
||||
"Content - Title": "Content - Title",
|
||||
"Content - Description": "Content - Description",
|
||||
"Company Page": "Company Page",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"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,31 @@
|
||||
{
|
||||
"Connect and network with professionals": "プロとネットワークを接続する",
|
||||
"Create Share Update": "共有アップデートを作成",
|
||||
"Create Company Update": "会社の更新を作成",
|
||||
"Custom API Call": "カスタムAPI通話",
|
||||
"Create a share update on LinkedIn": "LinkedIn で共有の更新を作成する",
|
||||
"Create a new company update for Company Page": "会社ページの新しい会社更新を作成する",
|
||||
"Make a custom API call to a specific endpoint": "特定のエンドポイントへのカスタム API コールを実行します。",
|
||||
"Text": "テキスト",
|
||||
"Visibility": "公開範囲",
|
||||
"Image": "画像",
|
||||
"Content - URL": "コンテンツ - URL",
|
||||
"Content - Title": "コンテンツ - タイトル",
|
||||
"Content - Description": "コンテンツ - 説明",
|
||||
"Company Page": "勤務先ページ",
|
||||
"Method": "方法",
|
||||
"Headers": "ヘッダー",
|
||||
"Query Parameters": "クエリパラメータ",
|
||||
"Body": "本文",
|
||||
"Response is Binary ?": "応答はバイナリですか?",
|
||||
"No Error on Failure": "失敗時にエラーはありません",
|
||||
"Timeout (in seconds)": "タイムアウト(秒)",
|
||||
"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,31 @@
|
||||
{
|
||||
"Connect and network with professionals": "Verbind en netwerk met professionals",
|
||||
"Create Share Update": "Maak Share Update",
|
||||
"Create Company Update": "Maak bedrijfsupdate",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Create a share update on LinkedIn": "Maak een share update aan op LinkedIn",
|
||||
"Create a new company update for Company Page": "Maak een nieuwe bedrijfsupdate voor Bedrijfspagina",
|
||||
"Make a custom API call to a specific endpoint": "Maak een aangepaste API call naar een specifiek eindpunt",
|
||||
"Text": "Tekstveld",
|
||||
"Visibility": "Zichtbaarheid",
|
||||
"Image": "Afbeelding",
|
||||
"Content - URL": "Inhoud - URL",
|
||||
"Content - Title": "Inhoud - Titel",
|
||||
"Content - Description": "Inhoud - Beschrijving",
|
||||
"Company Page": "Bedrijfs pagina",
|
||||
"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)",
|
||||
"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,31 @@
|
||||
{
|
||||
"Connect and network with professionals": "Conecte-se e rede com profissionais",
|
||||
"Create Share Update": "Criar Atualização de Compartilhamento",
|
||||
"Create Company Update": "Criar atualização de empresa",
|
||||
"Custom API Call": "Chamada de API personalizada",
|
||||
"Create a share update on LinkedIn": "Criar uma atualização de compartilhamento no LinkedIn",
|
||||
"Create a new company update for Company Page": "Criar uma nova atualização da empresa para a Página Empresa",
|
||||
"Make a custom API call to a specific endpoint": "Faça uma chamada de API personalizada para um ponto de extremidade específico",
|
||||
"Text": "texto",
|
||||
"Visibility": "Visibilidade",
|
||||
"Image": "Imagem:",
|
||||
"Content - URL": "Conteúdo - URL",
|
||||
"Content - Title": "Conteúdo - Título",
|
||||
"Content - Description": "Conteúdo - Descrição",
|
||||
"Company Page": "Página da Empresa",
|
||||
"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)",
|
||||
"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,30 @@
|
||||
{
|
||||
"LinkedIn": "LinkedIn",
|
||||
"Connect and network with professionals": "Связь и связь со специалистами",
|
||||
"Create Share Update": "Создать обновление общего доступа",
|
||||
"Create Company Update": "Создать обновление компании",
|
||||
"Custom API Call": "Пользовательский вызов API",
|
||||
"Create a share update on LinkedIn": "Создать общее обновление на LinkedIn",
|
||||
"Create a new company update for Company Page": "Создать новое обновление компании для страницы компании",
|
||||
"Make a custom API call to a specific endpoint": "Сделать пользовательский API вызов к определенной конечной точке",
|
||||
"Text": "Текст",
|
||||
"Visibility": "Видимость",
|
||||
"Image": "Изображение",
|
||||
"Content - URL": "Содержимое - URL",
|
||||
"Content - Title": "Содержимое - Заголовок",
|
||||
"Content - Description": "Контент - Описание",
|
||||
"Company Page": "Страница компании",
|
||||
"Method": "Метод",
|
||||
"Headers": "Заголовки",
|
||||
"Query Parameters": "Параметры запроса",
|
||||
"Body": "Тело",
|
||||
"No Error on Failure": "Нет ошибок при ошибке",
|
||||
"Timeout (in seconds)": "Таймаут (в секундах)",
|
||||
"Authorization headers are injected automatically from your connection.": "Заголовки авторизации включаются автоматически из вашего соединения.",
|
||||
"GET": "ПОЛУЧИТЬ",
|
||||
"POST": "ПОСТ",
|
||||
"PATCH": "ПАТЧ",
|
||||
"PUT": "ПОКУПИТЬ",
|
||||
"DELETE": "УДАЛИТЬ",
|
||||
"HEAD": "HEAD"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Connect and network with professionals": "Connect and network with professionals",
|
||||
"Create Share Update": "Create Share Update",
|
||||
"Create Company Update": "Create Company Update",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Create a share update on LinkedIn": "Create a share update on LinkedIn",
|
||||
"Create a new company update for Company Page": "Create a new company update for Company Page",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Text": "Text",
|
||||
"Visibility": "Visibility",
|
||||
"Image": "Image",
|
||||
"Content - URL": "Content - URL",
|
||||
"Content - Title": "Content - Title",
|
||||
"Content - Description": "Content - Description",
|
||||
"Company Page": "Company Page",
|
||||
"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)",
|
||||
"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,30 @@
|
||||
{
|
||||
"LinkedIn": "LinkedIn",
|
||||
"Connect and network with professionals": "Connect and network with professionals",
|
||||
"Create Share Update": "Create Share Update",
|
||||
"Create Company Update": "Create Company Update",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Create a share update on LinkedIn": "Create a share update on LinkedIn",
|
||||
"Create a new company update for Company Page": "Create a new company update for Company Page",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Text": "Text",
|
||||
"Visibility": "Visibility",
|
||||
"Image": "Image",
|
||||
"Content - URL": "Content - URL",
|
||||
"Content - Title": "Content - Title",
|
||||
"Content - Description": "Content - Description",
|
||||
"Company Page": "Company Page",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"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,31 @@
|
||||
{
|
||||
"Connect and network with professionals": "Connect and network with professionals",
|
||||
"Create Share Update": "Create Share Update",
|
||||
"Create Company Update": "Create Company Update",
|
||||
"Custom API Call": "自定义 API 呼叫",
|
||||
"Create a share update on LinkedIn": "Create a share update on LinkedIn",
|
||||
"Create a new company update for Company Page": "Create a new company update for Company Page",
|
||||
"Make a custom API call to a specific endpoint": "将一个自定义 API 调用到一个特定的终点",
|
||||
"Text": "文本",
|
||||
"Visibility": "Visibility",
|
||||
"Image": "Image",
|
||||
"Content - URL": "Content - URL",
|
||||
"Content - Title": "Content - Title",
|
||||
"Content - Description": "Content - Description",
|
||||
"Company Page": "Company Page",
|
||||
"Method": "方法",
|
||||
"Headers": "信头",
|
||||
"Query Parameters": "查询参数",
|
||||
"Body": "正文内容",
|
||||
"Response is Binary ?": "Response is Binary ?",
|
||||
"No Error on Failure": "失败时没有错误",
|
||||
"Timeout (in seconds)": "超时(秒)",
|
||||
"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,52 @@
|
||||
import {
|
||||
OAuth2PropertyValue,
|
||||
PieceAuth,
|
||||
createPiece,
|
||||
} from '@activepieces/pieces-framework';
|
||||
|
||||
import { PieceCategory } from '@activepieces/shared';
|
||||
import { createCompanyUpdate } from './lib/actions/create-company-update';
|
||||
import { createShareUpdate } from './lib/actions/create-share-update';
|
||||
import { createCustomApiCallAction } from '@activepieces/pieces-common';
|
||||
import { linkedinCommon } from './lib/common';
|
||||
|
||||
export const linkedinAuth = PieceAuth.OAuth2({
|
||||
authUrl: 'https://www.linkedin.com/oauth/v2/authorization',
|
||||
tokenUrl: 'https://www.linkedin.com/oauth/v2/accessToken',
|
||||
required: true,
|
||||
scope: [
|
||||
'w_member_social',
|
||||
'w_organization_social',
|
||||
'rw_organization_admin',
|
||||
'openid',
|
||||
'email',
|
||||
'profile',
|
||||
],
|
||||
});
|
||||
|
||||
export const linkedin = createPiece({
|
||||
displayName: 'LinkedIn',
|
||||
description: 'Connect and network with professionals',
|
||||
|
||||
minimumSupportedRelease: '0.30.0',
|
||||
logoUrl: 'https://cdn.activepieces.com/pieces/linkedin.png',
|
||||
categories: [PieceCategory.MARKETING],
|
||||
authors: ["aasimsani","kishanprmr","MoShizzle","khaledmashaly","abuaboud", "izdrail"],
|
||||
auth: linkedinAuth,
|
||||
actions: [
|
||||
createShareUpdate,
|
||||
createCompanyUpdate,
|
||||
createCustomApiCallAction({
|
||||
auth: linkedinAuth,
|
||||
baseUrl: () => {
|
||||
return linkedinCommon.baseUrl;
|
||||
},
|
||||
authMapping: async (auth) => {
|
||||
return {
|
||||
Authorization: `Bearer ${(auth as OAuth2PropertyValue).access_token}`,
|
||||
};
|
||||
},
|
||||
}),
|
||||
],
|
||||
triggers: [],
|
||||
});
|
||||
@@ -0,0 +1,71 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import {
|
||||
AuthenticationType,
|
||||
httpClient,
|
||||
HttpMethod,
|
||||
HttpRequest,
|
||||
} from '@activepieces/pieces-common';
|
||||
import { Image, linkedinCommon, santizeText } from '../common';
|
||||
import { linkedinAuth } from '../..';
|
||||
|
||||
export const createCompanyUpdate = createAction({
|
||||
auth: linkedinAuth,
|
||||
name: 'create_company_update',
|
||||
displayName: 'Create Company Update',
|
||||
description: 'Create a new company update for Company Page',
|
||||
props: {
|
||||
company: linkedinCommon.company,
|
||||
imageUrl: linkedinCommon.imageUrl,
|
||||
text: linkedinCommon.text,
|
||||
link: linkedinCommon.link,
|
||||
linkTitle: linkedinCommon.linkTitle,
|
||||
linkDescription: linkedinCommon.linkDescription,
|
||||
},
|
||||
|
||||
run: async (context) => {
|
||||
const imageUrl = context.propsValue.imageUrl;
|
||||
const bodyConfig: {
|
||||
urn: string;
|
||||
text: string;
|
||||
link?: string | undefined;
|
||||
linkDescription?: string | undefined;
|
||||
linkTitle?: string | undefined;
|
||||
visibility: string;
|
||||
image?: Image | undefined;
|
||||
} = {
|
||||
urn: `organization:${context.propsValue.company}`,
|
||||
text: santizeText(context.propsValue.text),
|
||||
link: context.propsValue.link,
|
||||
linkDescription: context.propsValue.linkDescription,
|
||||
linkTitle: context.propsValue.linkTitle,
|
||||
visibility: 'PUBLIC',
|
||||
};
|
||||
|
||||
if (imageUrl) {
|
||||
bodyConfig.image = await linkedinCommon.uploadImage(
|
||||
context.auth.access_token,
|
||||
`organization:${context.propsValue.company}`,
|
||||
imageUrl
|
||||
);
|
||||
}
|
||||
|
||||
const requestBody = linkedinCommon.generatePostRequestBody(bodyConfig);
|
||||
const createPostHeaders: any = linkedinCommon.linkedinHeaders;
|
||||
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.POST,
|
||||
url: `${linkedinCommon.baseUrl}/rest/posts`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: context.auth.access_token,
|
||||
},
|
||||
headers: createPostHeaders,
|
||||
body: requestBody,
|
||||
};
|
||||
|
||||
const response = await httpClient.sendRequest(request);
|
||||
return {
|
||||
success: true,
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,69 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import {
|
||||
AuthenticationType,
|
||||
httpClient,
|
||||
HttpMethod,
|
||||
HttpRequest,
|
||||
} from '@activepieces/pieces-common';
|
||||
import { Image, linkedinCommon, santizeText } from '../common';
|
||||
import jwt, { JwtPayload } from 'jsonwebtoken';
|
||||
import { linkedinAuth } from '../..';
|
||||
|
||||
export const createShareUpdate = createAction({
|
||||
auth: linkedinAuth,
|
||||
name: 'create_share_update',
|
||||
displayName: 'Create Share Update',
|
||||
description: 'Create a share update on LinkedIn',
|
||||
props: {
|
||||
text: linkedinCommon.text,
|
||||
visibility: linkedinCommon.visibility,
|
||||
imageUrl: linkedinCommon.imageUrl,
|
||||
link: linkedinCommon.link,
|
||||
linkTitle: linkedinCommon.linkTitle,
|
||||
linkDescription: linkedinCommon.linkDescription,
|
||||
},
|
||||
|
||||
run: async (context) => {
|
||||
|
||||
const token = context.auth.data.id_token;
|
||||
const decoded: JwtPayload = jwt.decode(token) as JwtPayload;
|
||||
const imageUrl = context.propsValue.imageUrl;
|
||||
const { text, link, linkDescription, linkTitle, visibility } =
|
||||
context.propsValue;
|
||||
let image: Image | undefined;
|
||||
if (imageUrl) {
|
||||
image = await linkedinCommon.uploadImage(
|
||||
context.auth.access_token,
|
||||
`person:${decoded.sub}`,
|
||||
imageUrl
|
||||
);
|
||||
}
|
||||
|
||||
const requestBody = linkedinCommon.generatePostRequestBody({
|
||||
urn: `person:${decoded.sub}`,
|
||||
text: santizeText(text),
|
||||
link,
|
||||
linkDescription,
|
||||
linkTitle,
|
||||
visibility,
|
||||
image,
|
||||
});
|
||||
const createPostHeaders: any = linkedinCommon.linkedinHeaders;
|
||||
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.POST,
|
||||
url: `${linkedinCommon.baseUrl}/rest/posts`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: context.auth.access_token,
|
||||
},
|
||||
headers: createPostHeaders,
|
||||
body: requestBody,
|
||||
};
|
||||
|
||||
const response = await httpClient.sendRequest(request);
|
||||
return {
|
||||
success: true,
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,279 @@
|
||||
import { ApFile, Property } from '@activepieces/pieces-framework';
|
||||
import {
|
||||
HttpMethod,
|
||||
httpClient,
|
||||
AuthenticationType,
|
||||
} from '@activepieces/pieces-common';
|
||||
|
||||
import FormData from 'form-data';
|
||||
import { linkedinAuth } from '../..';
|
||||
|
||||
export const santizeText = (text: string) => {
|
||||
// LinkedIn Posts API has a list of characters that need to be escaped since it's type is "LittleText"
|
||||
// https://learn.microsoft.com/en-us/linkedin/marketing/community-management/shares/posts-api?view=li-lms-2023-11&tabs=http
|
||||
// https://learn.microsoft.com/en-us/linkedin/marketing/community-management/shares/little-text-format?view=li-lms-2023-11
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
return text.replace(/[\(*\)\[\]\{\}<>@|~_]/gm, (x: string) => '\\' + x);
|
||||
};
|
||||
|
||||
export const linkedinCommon = {
|
||||
baseUrl: 'https://api.linkedin.com',
|
||||
linkedinHeaders: {
|
||||
'X-Restli-Protocol-Version': '2.0.0',
|
||||
'LinkedIn-Version': '202511',
|
||||
},
|
||||
text: Property.LongText({
|
||||
displayName: 'Text',
|
||||
required: true,
|
||||
}),
|
||||
imageUrl: Property.File({
|
||||
displayName: 'Image',
|
||||
required: false,
|
||||
}),
|
||||
link: Property.ShortText({
|
||||
displayName: 'Content - URL',
|
||||
required: false,
|
||||
}),
|
||||
linkTitle: Property.ShortText({
|
||||
displayName: 'Content - Title',
|
||||
required: false,
|
||||
}),
|
||||
linkDescription: Property.ShortText({
|
||||
displayName: 'Content - Description',
|
||||
required: false,
|
||||
}),
|
||||
visibility: Property.Dropdown({
|
||||
auth: linkedinAuth,
|
||||
displayName: 'Visibility',
|
||||
refreshers: [],
|
||||
required: true,
|
||||
options: async () => {
|
||||
return {
|
||||
options: [
|
||||
{
|
||||
label: 'Public',
|
||||
value: 'PUBLIC',
|
||||
},
|
||||
{
|
||||
label: 'Connections Only',
|
||||
value: 'CONNECTIONS',
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
}),
|
||||
|
||||
company: Property.Dropdown({
|
||||
auth: linkedinAuth,
|
||||
displayName: 'Company Page',
|
||||
required: true,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Connect your account',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const authProp = auth as { access_token: string };
|
||||
|
||||
const companies: any = await linkedinCommon.getCompanies(
|
||||
authProp.access_token
|
||||
);
|
||||
const options = [];
|
||||
for (const company in companies) {
|
||||
options.push({
|
||||
label: companies[company].localizedName,
|
||||
value: companies[company].id,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
options: options,
|
||||
};
|
||||
},
|
||||
}),
|
||||
|
||||
getCompanies: async (accessToken: string) => {
|
||||
const companies = (
|
||||
await httpClient.sendRequest({
|
||||
url: `${linkedinCommon.baseUrl}/v2/organizationalEntityAcls`,
|
||||
method: HttpMethod.GET,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: accessToken,
|
||||
},
|
||||
queryParams: {
|
||||
q: 'roleAssignee',
|
||||
},
|
||||
})
|
||||
).body;
|
||||
|
||||
const companyIds = companies.elements.map(
|
||||
(company: { organizationalTarget: string }) => {
|
||||
return company.organizationalTarget.substr(
|
||||
company.organizationalTarget.lastIndexOf(':') + 1
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
const response = await fetch(`${linkedinCommon.baseUrl}/rest/organizations?ids=List(${companyIds.join(',')})`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
...linkedinCommon.linkedinHeaders,
|
||||
'Authorization': `Bearer ${accessToken}`
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const companySearch = await response.json();
|
||||
|
||||
return companySearch.results;
|
||||
},
|
||||
|
||||
generatePostRequestBody: (data: {
|
||||
urn: string;
|
||||
text: any;
|
||||
link?: string | undefined;
|
||||
linkTitle?: string | undefined;
|
||||
linkDescription?: string | undefined;
|
||||
visibility: string;
|
||||
image?: Image | undefined;
|
||||
}) => {
|
||||
const requestObject: Post = {
|
||||
author: `urn:li:${data.urn}`,
|
||||
lifecycleState: 'PUBLISHED',
|
||||
commentary: data.text,
|
||||
distribution: {
|
||||
feedDistribution: 'MAIN_FEED',
|
||||
},
|
||||
visibility: data.visibility,
|
||||
isReshareDisabledByAuthor: false,
|
||||
};
|
||||
|
||||
if (data.link) {
|
||||
requestObject.content = {
|
||||
article: {
|
||||
source: data.link,
|
||||
title: data.linkTitle,
|
||||
description: data.linkDescription,
|
||||
thumbnail: data.image?.value.image,
|
||||
},
|
||||
};
|
||||
} else if (data.image) {
|
||||
requestObject.content = {
|
||||
media: {
|
||||
id: data.image.value.image,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return requestObject;
|
||||
},
|
||||
|
||||
uploadImage: async (
|
||||
accessToken: string,
|
||||
urn: string,
|
||||
image: ApFile
|
||||
): Promise<Image> => {
|
||||
const uploadData = (
|
||||
await httpClient.sendRequest({
|
||||
method: HttpMethod.POST,
|
||||
url: `${linkedinCommon.baseUrl}/v2/images`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: accessToken,
|
||||
},
|
||||
queryParams: {
|
||||
action: 'initializeUpload',
|
||||
},
|
||||
body: {
|
||||
initializeUploadRequest: {
|
||||
owner: `urn:li:${urn}`,
|
||||
},
|
||||
},
|
||||
})
|
||||
).body as Image;
|
||||
|
||||
const uploadFormData = new FormData();
|
||||
const { filename, base64 } = image;
|
||||
uploadFormData.append('file', Buffer.from(base64, 'base64'), filename);
|
||||
|
||||
await httpClient.sendRequest({
|
||||
url: uploadData.value.uploadUrl,
|
||||
method: HttpMethod.POST,
|
||||
body: uploadFormData,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: accessToken,
|
||||
},
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
});
|
||||
|
||||
return uploadData;
|
||||
},
|
||||
};
|
||||
export interface UgcPost {
|
||||
author: string;
|
||||
lifecycleState: string;
|
||||
specificContent: {
|
||||
'com.linkedin.ugc.ShareContent': {
|
||||
shareCommentary: {
|
||||
text?: string;
|
||||
};
|
||||
shareMediaCategory: string;
|
||||
media?: [
|
||||
{
|
||||
status: string;
|
||||
description?: {
|
||||
text: string;
|
||||
};
|
||||
originalUrl?: string;
|
||||
thumbnail?: string;
|
||||
title?: {
|
||||
text: string;
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
visibility: {
|
||||
'com.linkedin.ugc.MemberNetworkVisibility': string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface Post {
|
||||
author: string;
|
||||
commentary: string;
|
||||
lifecycleState: string;
|
||||
visibility: string;
|
||||
distribution: {
|
||||
feedDistribution: string;
|
||||
};
|
||||
content?: {
|
||||
article?: {
|
||||
source: string;
|
||||
thumbnail?: string | undefined;
|
||||
title?: string | undefined;
|
||||
description?: string | undefined;
|
||||
};
|
||||
media?: {
|
||||
id: string;
|
||||
};
|
||||
};
|
||||
isReshareDisabledByAuthor: boolean;
|
||||
}
|
||||
|
||||
export interface Image {
|
||||
value: {
|
||||
uploadUrlExpiresAt: number;
|
||||
uploadUrl: string;
|
||||
image: string;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
],
|
||||
"compilerOptions": {
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
}
|
||||
}
|
||||
@@ -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