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,33 @@
|
||||
{
|
||||
"extends": [
|
||||
"../../../../.eslintrc.base.json"
|
||||
],
|
||||
"ignorePatterns": [
|
||||
"!**/*"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx",
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# pieces-confluence
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Building
|
||||
|
||||
Run `nx build pieces-confluence` to build the library.
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "@activepieces/piece-confluence",
|
||||
"version": "0.1.10",
|
||||
"dependencies": {
|
||||
"xml2js": "0.6.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"name": "pieces-confluence",
|
||||
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "packages/pieces/community/confluence/src",
|
||||
"projectType": "library",
|
||||
"release": {
|
||||
"version": {
|
||||
"currentVersionResolver": "git-tag",
|
||||
"preserveLocalDependencyProtocols": false,
|
||||
"manifestRootsToUpdate": [
|
||||
"dist/{projectRoot}"
|
||||
]
|
||||
}
|
||||
},
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/js:tsc",
|
||||
"outputs": [
|
||||
"{options.outputPath}"
|
||||
],
|
||||
"options": {
|
||||
"outputPath": "dist/packages/pieces/community/confluence",
|
||||
"tsConfig": "packages/pieces/community/confluence/tsconfig.lib.json",
|
||||
"packageJson": "packages/pieces/community/confluence/package.json",
|
||||
"main": "packages/pieces/community/confluence/src/index.ts",
|
||||
"assets": [
|
||||
"packages/pieces/community/confluence/*.md",
|
||||
{
|
||||
"input": "packages/pieces/community/confluence/src/i18n",
|
||||
"output": "./src/i18n",
|
||||
"glob": "**/!(i18n.json)"
|
||||
}
|
||||
],
|
||||
"buildableProjectDepsInPackageJsonType": "dependencies",
|
||||
"updateBuildableProjectDepsInPackageJson": true
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
"prebuild"
|
||||
]
|
||||
},
|
||||
"nx-release-publish": {
|
||||
"options": {
|
||||
"packageRoot": "dist/{projectRoot}"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": [
|
||||
"{options.outputFile}"
|
||||
]
|
||||
},
|
||||
"prebuild": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"cwd": "packages/pieces/community/confluence",
|
||||
"command": "bun install --no-save --silent"
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"Account Email": "Konto-E-Mail",
|
||||
"API token": "API token",
|
||||
"Confluence Domain": "Konfluenz-Domäne",
|
||||
"Account email for basic auth": "Account-E-Mail für Basis-Authentifizierung",
|
||||
"API token for basic auth": "API-Token für Basis-Authentifizierung",
|
||||
"Example value - https://your-domain.atlassian.net": "Beispielwert - https://your-domain.atlassian.net",
|
||||
"Please refer to this guide to get your api credentials: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account": "Bitte lesen Sie diese Anleitung, um Ihre Api Zugangsdaten zu erhalten: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account",
|
||||
"Get Page Content": "Get Page Content",
|
||||
"Create Page from Template": "Seite aus Vorlage erstellen",
|
||||
"Custom API Call": "Eigener API-Aufruf",
|
||||
"Get page content and optionally all its descendants": "Seiteninhalt und optional alle Nachkommen abrufen",
|
||||
"Creates a new page from a template with the given title and variables.": "Erstellt eine neue Seite aus einer Vorlage mit dem angegebenen Titel und Variablen.",
|
||||
"Make a custom API call to a specific endpoint": "Einen benutzerdefinierten API-Aufruf an einen bestimmten Endpunkt machen",
|
||||
"Page ID": "Seiten-ID",
|
||||
"Include Descendants ?": "Nachfahren einbeziehen ?",
|
||||
"Dynamic Properties": "Dynamische Eigenschaften",
|
||||
"Space": "Raum",
|
||||
"Template": "Vorlage",
|
||||
"Parent Folder": "Eltern-Ordner",
|
||||
"Title": "Titel",
|
||||
"Status": "Status",
|
||||
"Template Variables": "Template-Variablen",
|
||||
"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)",
|
||||
"Get this from the page URL of your Confluence Cloud": "Holen Sie sich dies von der URL Ihrer Confluence Cloud",
|
||||
"If checked, will fetch all child pages recursively.": "Wenn aktiviert, werden alle Unterseiten rekursiv abgerufen.",
|
||||
"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..",
|
||||
"Published ": "Veröffentlicht ",
|
||||
"Draft": "Entwurf",
|
||||
"GET": "ERHALTEN",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "LÖSCHEN",
|
||||
"HEAD": "HEAD",
|
||||
"New Page": "Neue Seite",
|
||||
"Triggers when a new page is created.": "Wird ausgelöst, wenn eine neue Seite erstellt wird."
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"Account Email": "Email de cuenta",
|
||||
"API token": "API token",
|
||||
"Confluence Domain": "Dominio de Confluencia",
|
||||
"Account email for basic auth": "Email de cuenta para la autenticación básica",
|
||||
"API token for basic auth": "Token API para autenticación básica",
|
||||
"Example value - https://your-domain.atlassian.net": "Valor de ejemplo - https://your-domain.atlassian.net",
|
||||
"Please refer to this guide to get your api credentials: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account": "Por favor, consulta esta guía para obtener tus credenciales de api: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account",
|
||||
"Get Page Content": "Get Page Content",
|
||||
"Create Page from Template": "Crear página desde plantilla",
|
||||
"Custom API Call": "Llamada API personalizada",
|
||||
"Get page content and optionally all its descendants": "Obtener contenido de página y opcionalmente todos sus descendientes",
|
||||
"Creates a new page from a template with the given title and variables.": "Crea una nueva página desde una plantilla con el título y las variables dadas.",
|
||||
"Make a custom API call to a specific endpoint": "Hacer una llamada API personalizada a un extremo específico",
|
||||
"Page ID": "ID de página",
|
||||
"Include Descendants ?": "¿Incluye a los descendientes?",
|
||||
"Dynamic Properties": "Propiedades dinámicas",
|
||||
"Space": "Espacio",
|
||||
"Template": "Plantilla",
|
||||
"Parent Folder": "Carpeta padre",
|
||||
"Title": "Título",
|
||||
"Status": "Estado",
|
||||
"Template Variables": "Variables de Plantilla",
|
||||
"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)",
|
||||
"Get this from the page URL of your Confluence Cloud": "Obtén esto de la URL de la página de tu Confluence Cloud",
|
||||
"If checked, will fetch all child pages recursively.": "Si está marcado, se obtendrán todas las páginas hijas de forma recursiva.",
|
||||
"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.",
|
||||
"Published ": "Publicado ",
|
||||
"Draft": "Borrador",
|
||||
"GET": "RECOGER",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "BORRAR",
|
||||
"HEAD": "LIMPIO",
|
||||
"New Page": "Nueva página",
|
||||
"Triggers when a new page is created.": "Dispara cuando se crea una nueva página."
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"Account Email": "E-mail du compte",
|
||||
"API token": "API token",
|
||||
"Confluence Domain": "Domaine de Confluence",
|
||||
"Account email for basic auth": "E-mail du compte pour l'authentification de base",
|
||||
"API token for basic auth": "Jeton d'API pour l'authentification de base",
|
||||
"Example value - https://your-domain.atlassian.net": "Valeur de l'exemple - https://votre-domaine.atlassian.net",
|
||||
"Please refer to this guide to get your api credentials: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account": "Veuillez vous référer à ce guide pour obtenir vos identifiants api : https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account",
|
||||
"Get Page Content": "Get Page Content",
|
||||
"Create Page from Template": "Créer une page à partir du modèle",
|
||||
"Custom API Call": "Appel API personnalisé",
|
||||
"Get page content and optionally all its descendants": "Obtenir le contenu de la page et, optionnellement, tous ses descendants",
|
||||
"Creates a new page from a template with the given title and variables.": "Crée une nouvelle page à partir d'un modèle avec le titre et les variables donnés.",
|
||||
"Make a custom API call to a specific endpoint": "Passez un appel API personnalisé à un point de terminaison spécifique",
|
||||
"Page ID": "ID de la page",
|
||||
"Include Descendants ?": "Inclure les descendants ?",
|
||||
"Dynamic Properties": "Propriétés dynamiques",
|
||||
"Space": "Espace libre",
|
||||
"Template": "Gabarit",
|
||||
"Parent Folder": "Dossier parent",
|
||||
"Title": "Titre de la page",
|
||||
"Status": "Statut",
|
||||
"Template Variables": "Variables de modèle",
|
||||
"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)",
|
||||
"Get this from the page URL of your Confluence Cloud": "Récupérez ceci à partir de l'URL de la page de votre Cloud Confluence",
|
||||
"If checked, will fetch all child pages recursively.": "Si cette case est cochée, toutes les pages enfants seront récupérées récursivement.",
|
||||
"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.",
|
||||
"Published ": "Publié ",
|
||||
"Draft": "Brouillon",
|
||||
"GET": "OBTENIR",
|
||||
"POST": "POSTER",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "EFFACER",
|
||||
"DELETE": "SUPPRIMER",
|
||||
"HEAD": "TÊTE",
|
||||
"New Page": "Nouvelle page",
|
||||
"Triggers when a new page is created.": "Déclenche quand une nouvelle page est créée."
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"Account Email": "アカウントのメールアドレス",
|
||||
"API token": "API token",
|
||||
"Confluence Domain": "Confluence Domain",
|
||||
"Account email for basic auth": "ベーシック認証用のアカウントメールアドレス",
|
||||
"API token for basic auth": "基本的な認証のためのAPIトークン",
|
||||
"Example value - https://your-domain.atlassian.net": "値の例 - https://your-domain.atlassian.net",
|
||||
"Please refer to this guide to get your api credentials: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account": "あなたのapi認証情報を取得するには、このガイドを参照してください: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account",
|
||||
"Get Page Content": "Get Page Content",
|
||||
"Create Page from Template": "テンプレートからページを作成",
|
||||
"Custom API Call": "カスタムAPI通話",
|
||||
"Get page content and optionally all its descendants": "ページコンテンツを取得し、必要に応じてその子孫をすべて取得します",
|
||||
"Creates a new page from a template with the given title and variables.": "指定されたタイトルと変数を持つテンプレートから新しいページを作成します。",
|
||||
"Make a custom API call to a specific endpoint": "特定のエンドポイントへのカスタム API コールを実行します。",
|
||||
"Page ID": "ページID",
|
||||
"Include Descendants ?": "子孫を含む ?",
|
||||
"Dynamic Properties": "動的プロパティ",
|
||||
"Space": "スペース",
|
||||
"Template": "テンプレート",
|
||||
"Parent Folder": "親フォルダ",
|
||||
"Title": "タイトル",
|
||||
"Status": "Status",
|
||||
"Template Variables": "テンプレート変数",
|
||||
"Method": "方法",
|
||||
"Headers": "ヘッダー",
|
||||
"Query Parameters": "クエリパラメータ",
|
||||
"Body": "本文",
|
||||
"Response is Binary ?": "応答はバイナリですか?",
|
||||
"No Error on Failure": "失敗時にエラーはありません",
|
||||
"Timeout (in seconds)": "タイムアウト(秒)",
|
||||
"Get this from the page URL of your Confluence Cloud": "Confluence CloudのページURLから入手する",
|
||||
"If checked, will fetch all child pages recursively.": "チェックした場合、すべての子ページを再帰的に取得します。",
|
||||
"Authorization headers are injected automatically from your connection.": "認証ヘッダは接続から自動的に注入されます。",
|
||||
"Enable for files like PDFs, images, etc..": "PDF、画像などのファイルを有効にします。",
|
||||
"Published ": "公開済み ",
|
||||
"Draft": "下書き",
|
||||
"GET": "取得",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "削除",
|
||||
"HEAD": "頭",
|
||||
"New Page": "新しいページ",
|
||||
"Triggers when a new page is created.": "新しいページが作成されたときにトリガーします。"
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"Account Email": "Account e-mail",
|
||||
"API token": "API token",
|
||||
"Confluence Domain": "Confluence Domein",
|
||||
"Account email for basic auth": "Account e-mail voor basis authenticatie",
|
||||
"API token for basic auth": "API token voor basis authenticatie",
|
||||
"Example value - https://your-domain.atlassian.net": "Voorbeeldwaarde - https://uw-domein.atlassian.net",
|
||||
"Please refer to this guide to get your api credentials: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account": "Raadpleeg deze handleiding om uw api referenties te krijgen: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account",
|
||||
"Get Page Content": "Get Page Content",
|
||||
"Create Page from Template": "Maak pagina van sjabloon",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Get page content and optionally all its descendants": "Pagina-inhoud en optioneel al zijn afstammelingen ophalen",
|
||||
"Creates a new page from a template with the given title and variables.": "Maakt een nieuwe pagina van een template met de opgegeven titel en variabelen.",
|
||||
"Make a custom API call to a specific endpoint": "Maak een aangepaste API call naar een specifiek eindpunt",
|
||||
"Page ID": "Pagina ID",
|
||||
"Include Descendants ?": "Inclusief Descendants ?",
|
||||
"Dynamic Properties": "Dynamische eigenschappen",
|
||||
"Space": "Spatiebalk",
|
||||
"Template": "Sjabloon",
|
||||
"Parent Folder": "Bovenliggende map",
|
||||
"Title": "Aanspreektitel",
|
||||
"Status": "status",
|
||||
"Template Variables": "Template variabelen",
|
||||
"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)",
|
||||
"Get this from the page URL of your Confluence Cloud": "Verkrijg dit van de pagina-URL van je Confluence Cloud",
|
||||
"If checked, will fetch all child pages recursively.": "Indien aangevinkt, worden alle onderliggende pagina's recursief opgehaald.",
|
||||
"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..",
|
||||
"Published ": "Gepubliceerd ",
|
||||
"Draft": "Concept",
|
||||
"GET": "KRIJG",
|
||||
"POST": "POSTE",
|
||||
"PATCH": "BEKIJK",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "VERWIJDEREN",
|
||||
"HEAD": "HOOFD",
|
||||
"New Page": "Nieuwe pagina",
|
||||
"Triggers when a new page is created.": "Triggers wanneer een nieuwe pagina is aangemaakt."
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"Account Email": "Email do Cliente",
|
||||
"API token": "API token",
|
||||
"Confluence Domain": "Domínio de Confluência",
|
||||
"Account email for basic auth": "E-mail da conta para autenticação básica",
|
||||
"API token for basic auth": "Token de API para autenticação básica",
|
||||
"Example value - https://your-domain.atlassian.net": "Exemplo de valor - https://seu-dominio.atlassian.net",
|
||||
"Please refer to this guide to get your api credentials: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account": "Por favor, consulte este guia para obter suas credenciais de api: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account",
|
||||
"Get Page Content": "Get Page Content",
|
||||
"Create Page from Template": "Criar página a partir do Modelo",
|
||||
"Custom API Call": "Chamada de API personalizada",
|
||||
"Get page content and optionally all its descendants": "Obtenha o conteúdo da página e, opcionalmente, todos os seus descendentes",
|
||||
"Creates a new page from a template with the given title and variables.": "Cria uma nova página a partir de um modelo com o título e as variáveis fornecidos.",
|
||||
"Make a custom API call to a specific endpoint": "Faça uma chamada de API personalizada para um ponto de extremidade específico",
|
||||
"Page ID": "ID da Página",
|
||||
"Include Descendants ?": "Incluir Descendentes ?",
|
||||
"Dynamic Properties": "Propriedades Dinâmicas",
|
||||
"Space": "Sala",
|
||||
"Template": "Modelo",
|
||||
"Parent Folder": "Pasta pai",
|
||||
"Title": "Título",
|
||||
"Status": "Estado",
|
||||
"Template Variables": "Variáveis de Template",
|
||||
"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)",
|
||||
"Get this from the page URL of your Confluence Cloud": "Obter isto na URL da página de sua Nuvem de Confluência",
|
||||
"If checked, will fetch all child pages recursively.": "Se marcado, irá buscar todas as páginas filhas recursivamente.",
|
||||
"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..",
|
||||
"Published ": "Publicado ",
|
||||
"Draft": "Rascunho",
|
||||
"GET": "OBTER",
|
||||
"POST": "POSTAR",
|
||||
"PATCH": "COMPRAR",
|
||||
"PUT": "COLOCAR",
|
||||
"DELETE": "EXCLUIR",
|
||||
"HEAD": "CABEÇA",
|
||||
"New Page": "Nova Página",
|
||||
"Triggers when a new page is created.": "Dispara quando uma nova página é criada."
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"Confluence": "Confluence",
|
||||
"Account Email": "Email клиента",
|
||||
"API token": "API token",
|
||||
"Confluence Domain": "Домен доверия",
|
||||
"Account email for basic auth": "Email аккаунта для базовой авторизации",
|
||||
"API token for basic auth": "API токен для базовой авторизации",
|
||||
"Example value - https://your-domain.atlassian.net": "Пример значения - https://your-domain.atlassian.net",
|
||||
"Please refer to this guide to get your api credentials: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account": "Пожалуйста, обратитесь к этому руководству, чтобы получить ваши учётные данные api: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account",
|
||||
"Get Page Content": "Get Page Content",
|
||||
"Create Page from Template": "Создать страницу из шаблона",
|
||||
"Custom API Call": "Пользовательский вызов API",
|
||||
"Get page content and optionally all its descendants": "Получить содержимое страницы и по желанию все ее потомки",
|
||||
"Creates a new page from a template with the given title and variables.": "Создает новую страницу из шаблона с заданным заголовком и переменными.",
|
||||
"Make a custom API call to a specific endpoint": "Сделать пользовательский API вызов к определенной конечной точке",
|
||||
"Page ID": "ID страницы",
|
||||
"Include Descendants ?": "Включить потомков ?",
|
||||
"Dynamic Properties": "Динамические свойства",
|
||||
"Space": "Пространство",
|
||||
"Template": "Шаблон",
|
||||
"Parent Folder": "Родительская папка",
|
||||
"Title": "Заголовок",
|
||||
"Status": "Статус",
|
||||
"Template Variables": "Переменные шаблона",
|
||||
"Method": "Метод",
|
||||
"Headers": "Заголовки",
|
||||
"Query Parameters": "Параметры запроса",
|
||||
"Body": "Тело",
|
||||
"No Error on Failure": "Нет ошибок при ошибке",
|
||||
"Timeout (in seconds)": "Таймаут (в секундах)",
|
||||
"Get this from the page URL of your Confluence Cloud": "Получить это со страницы вашего облака Confluence Cloud",
|
||||
"If checked, will fetch all child pages recursively.": "При отмеченной опции все дочерние страницы будут загружены рекурсивно.",
|
||||
"Authorization headers are injected automatically from your connection.": "Заголовки авторизации включаются автоматически из вашего соединения.",
|
||||
"Published ": "Опубликовано ",
|
||||
"Draft": "Черновик",
|
||||
"GET": "ПОЛУЧИТЬ",
|
||||
"POST": "ПОСТ",
|
||||
"PATCH": "ПАТЧ",
|
||||
"PUT": "ПОКУПИТЬ",
|
||||
"DELETE": "УДАЛИТЬ",
|
||||
"HEAD": "HEAD",
|
||||
"New Page": "Новая страница",
|
||||
"Triggers when a new page is created.": "Включает при создании новой страницы."
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"Account Email": "Account Email",
|
||||
"API token": "API token",
|
||||
"Confluence Domain": "Confluence Domain",
|
||||
"Account email for basic auth": "Account email for basic auth",
|
||||
"API token for basic auth": "API token for basic auth",
|
||||
"Example value - https://your-domain.atlassian.net": "Example value - https://your-domain.atlassian.net",
|
||||
"Please refer to this guide to get your api credentials: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account": "Please refer to this guide to get your api credentials: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account",
|
||||
"Get Page Content": "Get Page Content",
|
||||
"Create Page from Template": "Create Page from Template",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Get page content and optionally all its descendants": "Get page content and optionally all its descendants",
|
||||
"Creates a new page from a template with the given title and variables.": "Creates a new page from a template with the given title and variables.",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Page ID": "Page ID",
|
||||
"Include Descendants ?": "Include Descendants ?",
|
||||
"Dynamic Properties": "Dynamic Properties",
|
||||
"Space": "Space",
|
||||
"Template": "Template",
|
||||
"Parent Folder": "Parent Folder",
|
||||
"Title": "Title",
|
||||
"Status": "Status",
|
||||
"Template Variables": "Template Variables",
|
||||
"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)",
|
||||
"Get this from the page URL of your Confluence Cloud": "Get this from the page URL of your Confluence Cloud",
|
||||
"If checked, will fetch all child pages recursively.": "If checked, will fetch all child pages recursively.",
|
||||
"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..",
|
||||
"Published ": "Published ",
|
||||
"Draft": "Draft",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD",
|
||||
"New Page": "New Page",
|
||||
"Triggers when a new page is created.": "Triggers when a new page is created."
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"Confluence": "Confluence",
|
||||
"Account Email": "Account Email",
|
||||
"API token": "API token",
|
||||
"Confluence Domain": "Confluence Domain",
|
||||
"Account email for basic auth": "Account email for basic auth",
|
||||
"API token for basic auth": "API token for basic auth",
|
||||
"Example value - https://your-domain.atlassian.net": "Example value - https://your-domain.atlassian.net",
|
||||
"Please refer to this guide to get your api credentials: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account": "Please refer to this guide to get your api credentials: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account",
|
||||
"Get Page Content": "Get Page Content",
|
||||
"Create Page from Template": "Create Page from Template",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Get page content and optionally all its descendants": "Get page content and optionally all its descendants",
|
||||
"Creates a new page from a template with the given title and variables.": "Creates a new page from a template with the given title and variables.",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Page ID": "Page ID",
|
||||
"Include Descendants ?": "Include Descendants ?",
|
||||
"Dynamic Properties": "Dynamic Properties",
|
||||
"Space": "Space",
|
||||
"Template": "Template",
|
||||
"Parent Folder": "Parent Folder",
|
||||
"Title": "Title",
|
||||
"Status": "Status",
|
||||
"Template Variables": "Template Variables",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"Get this from the page URL of your Confluence Cloud": "Get this from the page URL of your Confluence Cloud",
|
||||
"If checked, will fetch all child pages recursively.": "If checked, will fetch all child pages recursively.",
|
||||
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
|
||||
"Published ": "Đã xuất bản ",
|
||||
"Draft": "Bản nháp",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD",
|
||||
"New Page": "New Page",
|
||||
"Triggers when a new page is created.": "Triggers when a new page is created."
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"Account Email": "Account Email",
|
||||
"API token": "API token",
|
||||
"Confluence Domain": "Confluence Domain",
|
||||
"Account email for basic auth": "Account email for basic auth",
|
||||
"API token for basic auth": "API token for basic auth",
|
||||
"Example value - https://your-domain.atlassian.net": "Example value - https://your-domain.atlassian.net",
|
||||
"Please refer to this guide to get your api credentials: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account": "Please refer to this guide to get your api credentials: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account",
|
||||
"Get Page Content": "Get Page Content",
|
||||
"Create Page from Template": "Create Page from Template",
|
||||
"Custom API Call": "自定义 API 呼叫",
|
||||
"Get page content and optionally all its descendants": "Get page content and optionally all its descendants",
|
||||
"Creates a new page from a template with the given title and variables.": "Creates a new page from a template with the given title and variables.",
|
||||
"Make a custom API call to a specific endpoint": "将一个自定义 API 调用到一个特定的终点",
|
||||
"Page ID": "Page ID",
|
||||
"Include Descendants ?": "Include Descendants ?",
|
||||
"Dynamic Properties": "Dynamic Properties",
|
||||
"Space": "Space",
|
||||
"Template": "模板",
|
||||
"Parent Folder": "父文件夹",
|
||||
"Title": "标题",
|
||||
"Status": "状态",
|
||||
"Template Variables": "Template Variables",
|
||||
"Method": "方法",
|
||||
"Headers": "信头",
|
||||
"Query Parameters": "查询参数",
|
||||
"Body": "正文内容",
|
||||
"Response is Binary ?": "Response is Binary ?",
|
||||
"No Error on Failure": "失败时没有错误",
|
||||
"Timeout (in seconds)": "超时(秒)",
|
||||
"Get this from the page URL of your Confluence Cloud": "Get this from the page URL of your Confluence Cloud",
|
||||
"If checked, will fetch all child pages recursively.": "If checked, will fetch all child pages recursively.",
|
||||
"Authorization headers are injected automatically from your connection.": "授权头自动从您的连接中注入。",
|
||||
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
|
||||
"Published ": "已发布 ",
|
||||
"Draft": "草稿",
|
||||
"GET": "获取",
|
||||
"POST": "帖子",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "弹出",
|
||||
"DELETE": "删除",
|
||||
"HEAD": "黑色",
|
||||
"New Page": "New Page",
|
||||
"Triggers when a new page is created.": "Triggers when a new page is created."
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import { createPiece, PieceAuth, Property ,PiecePropValueSchema, Piece} from "@activepieces/pieces-framework";
|
||||
import { getPageContent } from "./lib/actions/get-page-content";
|
||||
import { newPageTrigger } from "./lib/triggers/new-page";
|
||||
import { PieceCategory } from "@activepieces/shared";
|
||||
import { createCustomApiCallAction } from "@activepieces/pieces-common";
|
||||
import { createPageFromTemplateAction } from "./lib/actions/create-page-from-template";
|
||||
|
||||
export const confluenceAuth = PieceAuth.CustomAuth({
|
||||
description: 'Please refer to this guide to get your api credentials: https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account',
|
||||
required: true,
|
||||
props: {
|
||||
username: PieceAuth.SecretText({
|
||||
displayName: 'Account Email',
|
||||
required: true,
|
||||
description: 'Account email for basic auth',
|
||||
}),
|
||||
password: PieceAuth.SecretText({
|
||||
displayName: 'API token',
|
||||
required: true,
|
||||
description: 'API token for basic auth',
|
||||
}),
|
||||
confluenceDomain: Property.ShortText({
|
||||
displayName: 'Confluence Domain',
|
||||
required: true,
|
||||
description: 'Example value - https://your-domain.atlassian.net',
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
export const confluence = createPiece({
|
||||
displayName: "Confluence",
|
||||
auth: confluenceAuth,
|
||||
minimumSupportedRelease: '0.30.0',
|
||||
logoUrl: "https://cdn.activepieces.com/pieces/confluence.png",
|
||||
authors: ["geekyme"],
|
||||
actions: [getPageContent,createPageFromTemplateAction,
|
||||
createCustomApiCallAction({
|
||||
baseUrl:(auth)=>{
|
||||
return `${ auth?.props.confluenceDomain?? ''}/wiki/api/v2`;
|
||||
},
|
||||
auth: confluenceAuth,
|
||||
authMapping: async (auth) => {
|
||||
const authValue = auth.props
|
||||
return {
|
||||
Authorization: `Basic ${Buffer.from(`${authValue.username}:${authValue.password}`).toString('base64')}`,
|
||||
};
|
||||
},
|
||||
})
|
||||
],
|
||||
categories: [PieceCategory.CONTENT_AND_FILES],
|
||||
triggers: [newPageTrigger],
|
||||
});
|
||||
@@ -0,0 +1,82 @@
|
||||
import { confluenceAuth } from "../../index";
|
||||
import { createAction, Property } from "@activepieces/pieces-framework";
|
||||
import { folderIdProp, spaceIdProp, templateIdProp, templateVariablesProp } from "../common/props";
|
||||
import { confluenceApiCall } from "../common";
|
||||
import { HttpMethod } from "@activepieces/pieces-common";
|
||||
|
||||
export const createPageFromTemplateAction = createAction({
|
||||
auth:confluenceAuth,
|
||||
name:'create-page-from-template',
|
||||
displayName:'Create Page from Template',
|
||||
description:'Creates a new page from a template with the given title and variables.',
|
||||
props:{
|
||||
spaceId:spaceIdProp,
|
||||
templateId:templateIdProp,
|
||||
folderId:folderIdProp,
|
||||
title:Property.ShortText({
|
||||
displayName:'Title',
|
||||
required:true,
|
||||
}),
|
||||
status:Property.StaticDropdown({
|
||||
displayName:'Status',
|
||||
required:true,
|
||||
defaultValue:'draft',
|
||||
options:{
|
||||
disabled:false,
|
||||
options:[
|
||||
{
|
||||
label:'Published ',
|
||||
value:'current'
|
||||
},
|
||||
{
|
||||
label:'Draft',
|
||||
value:'draft'
|
||||
}
|
||||
]
|
||||
}
|
||||
}),
|
||||
templateVariables:templateVariablesProp,
|
||||
},
|
||||
async run(context){
|
||||
const {spaceId,templateId,title,status,folderId} = context.propsValue;
|
||||
const variables = context.propsValue.templateVariables ??{};
|
||||
|
||||
const template = await confluenceApiCall<{ body: { storage: { value: string } } }>({
|
||||
domain: context.auth.props.confluenceDomain,
|
||||
username: context.auth.props.username,
|
||||
password: context.auth.props.password,
|
||||
method: HttpMethod.GET,
|
||||
version: 'v1',
|
||||
resourceUri: `/template/${templateId}`,
|
||||
});
|
||||
|
||||
const body = template.body.storage.value;
|
||||
|
||||
let content = body.replace(/<at:declarations>[\s\S]*?<\/at:declarations>/, "").trim();
|
||||
Object.entries(variables).forEach(([key, value]) => {
|
||||
const varRegex = new RegExp(`<at:var at:name=(['"])${key}\\1\\s*\\/?>`, "g");
|
||||
content = content.replace(varRegex, value);
|
||||
});
|
||||
|
||||
const response = await confluenceApiCall({
|
||||
domain: context.auth.props.confluenceDomain,
|
||||
username: context.auth.props.username,
|
||||
password: context.auth.props.password,
|
||||
method: HttpMethod.POST,
|
||||
version: 'v2',
|
||||
resourceUri: '/pages',
|
||||
body: {
|
||||
spaceId:spaceId,
|
||||
title,
|
||||
parentId:folderId,
|
||||
status,
|
||||
body:{
|
||||
representation:'storage',
|
||||
value:content,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return response;
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,149 @@
|
||||
import {
|
||||
createAction,
|
||||
Property,
|
||||
DynamicPropsValue,
|
||||
PiecePropValueSchema,
|
||||
AppConnectionValueForAuthProperty,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { confluenceAuth } from '../..';
|
||||
import { confluenceApiCall } from '../common';
|
||||
|
||||
interface ConfluencePage {
|
||||
id: string;
|
||||
title: string;
|
||||
body: any;
|
||||
children?: ConfluencePage[];
|
||||
}
|
||||
|
||||
async function getPageWithContent(
|
||||
auth: AppConnectionValueForAuthProperty<typeof confluenceAuth>,
|
||||
pageId: string,
|
||||
): Promise<ConfluencePage> {
|
||||
try {
|
||||
const response = await confluenceApiCall<ConfluencePage>({
|
||||
domain: auth.props.confluenceDomain,
|
||||
username: auth.props.username,
|
||||
password: auth.props.password,
|
||||
method: HttpMethod.GET,
|
||||
version: 'v2',
|
||||
resourceUri: `/pages/${pageId}`,
|
||||
query: {
|
||||
'body-format': 'storage',
|
||||
},
|
||||
});
|
||||
return response;
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to fetch page ${pageId}: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function getChildPages(
|
||||
auth: AppConnectionValueForAuthProperty<typeof confluenceAuth>,
|
||||
parentId: string,
|
||||
currentDepth: number,
|
||||
maxDepth: number,
|
||||
): Promise<ConfluencePage[]> {
|
||||
if (currentDepth >= maxDepth) {
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
const childrenResponse = await confluenceApiCall<{ results: ConfluencePage[] }>({
|
||||
domain: auth.props.confluenceDomain,
|
||||
username: auth.props.username,
|
||||
password: auth.props.password,
|
||||
method: HttpMethod.GET,
|
||||
version: 'v2',
|
||||
resourceUri: `/pages/${parentId}/children`,
|
||||
});
|
||||
|
||||
const childPages = await Promise.all(
|
||||
childrenResponse.results.map(async (childPage) => {
|
||||
const pageWithContent = await getPageWithContent(auth, childPage.id);
|
||||
const children = await getChildPages(auth, childPage.id, currentDepth + 1, maxDepth);
|
||||
return {
|
||||
...pageWithContent,
|
||||
children,
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
return childPages;
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to fetch children for page ${parentId}: ${
|
||||
error instanceof Error ? error.message : 'Unknown error'
|
||||
}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const getPageContent = createAction({
|
||||
name: 'getPageContent',
|
||||
displayName: 'Get Page Content',
|
||||
description: 'Get page content and optionally all its descendants',
|
||||
auth: confluenceAuth,
|
||||
props: {
|
||||
pageId: Property.ShortText({
|
||||
displayName: 'Page ID',
|
||||
description: 'Get this from the page URL of your Confluence Cloud',
|
||||
required: true,
|
||||
}),
|
||||
includeDescendants: Property.Checkbox({
|
||||
displayName: 'Include Descendants ?',
|
||||
description: 'If checked, will fetch all child pages recursively.',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
dynamic: Property.DynamicProperties({
|
||||
auth: confluenceAuth,
|
||||
displayName: 'Dynamic Properties',
|
||||
refreshers: ['includeDescendants'],
|
||||
required: true,
|
||||
props: async ({ includeDescendants }) => {
|
||||
if (!includeDescendants) {
|
||||
return {};
|
||||
}
|
||||
const fields: DynamicPropsValue = {
|
||||
maxDepth: Property.Number({
|
||||
displayName: 'Maximum Depth',
|
||||
description: 'Maximum depth of child pages to fetch.',
|
||||
required: true,
|
||||
defaultValue: 5,
|
||||
}),
|
||||
};
|
||||
return fields;
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
try {
|
||||
const page = await getPageWithContent(context.auth, context.propsValue.pageId);
|
||||
|
||||
if (!context.propsValue.includeDescendants) {
|
||||
return page;
|
||||
}
|
||||
|
||||
const children = await getChildPages(
|
||||
context.auth,
|
||||
context.propsValue.pageId,
|
||||
1,
|
||||
context.propsValue.dynamic['maxDepth'],
|
||||
);
|
||||
|
||||
return {
|
||||
...page,
|
||||
children,
|
||||
};
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to fetch page ${context.propsValue.pageId}: ${
|
||||
error instanceof Error ? error.message : 'Unknown error'
|
||||
}`,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,118 @@
|
||||
import {
|
||||
AuthenticationType,
|
||||
httpClient,
|
||||
HttpMessageBody,
|
||||
HttpMethod,
|
||||
HttpRequest,
|
||||
QueryParams,
|
||||
} from '@activepieces/pieces-common';
|
||||
import { isNil } from '@activepieces/shared';
|
||||
|
||||
export type ConfluenceApiCallParams = {
|
||||
domain: string;
|
||||
username: string;
|
||||
password: string;
|
||||
version: 'v1' | 'v2';
|
||||
method: HttpMethod;
|
||||
resourceUri: string;
|
||||
query?: QueryParams;
|
||||
body?: any;
|
||||
};
|
||||
|
||||
export type PaginatedResponse<T> = {
|
||||
results: T[];
|
||||
_links?: {
|
||||
next?: string;
|
||||
};
|
||||
};
|
||||
|
||||
export async function confluenceApiCall<T extends HttpMessageBody>({
|
||||
domain,
|
||||
username,
|
||||
password,
|
||||
method,
|
||||
version,
|
||||
resourceUri,
|
||||
query,
|
||||
body,
|
||||
}: ConfluenceApiCallParams): Promise<T> {
|
||||
const baseUrl = version === 'v2' ? `${domain}/wiki/api/v2` : `${domain}/wiki/rest/api`;
|
||||
|
||||
const request: HttpRequest = {
|
||||
method,
|
||||
url: baseUrl + resourceUri,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username,
|
||||
password,
|
||||
},
|
||||
queryParams: query,
|
||||
body: body,
|
||||
};
|
||||
|
||||
const response = await httpClient.sendRequest<T>(request);
|
||||
return response.body;
|
||||
}
|
||||
|
||||
export async function confluencePaginatedApiCall<T extends HttpMessageBody>({
|
||||
domain,
|
||||
username,
|
||||
password,
|
||||
method,
|
||||
version,
|
||||
resourceUri,
|
||||
query,
|
||||
body,
|
||||
}: ConfluenceApiCallParams): Promise<T[]> {
|
||||
const qs = query ? query : {};
|
||||
const resultData: T[] = [];
|
||||
|
||||
if (version === 'v2') {
|
||||
let nextUrl = `${domain}/wiki/api/v2${resourceUri}?limit=200`;
|
||||
|
||||
do {
|
||||
const response = await httpClient.sendRequest<PaginatedResponse<T>>({
|
||||
method,
|
||||
url: nextUrl,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username,
|
||||
password,
|
||||
},
|
||||
queryParams: qs,
|
||||
body,
|
||||
});
|
||||
|
||||
if (isNil(response.body.results)) {
|
||||
break;
|
||||
}
|
||||
resultData.push(...response.body.results);
|
||||
nextUrl = response.body?._links?.next ? `${domain}${response.body._links.next}` : '';
|
||||
} while (nextUrl);
|
||||
} else {
|
||||
let start = 0;
|
||||
let hasMoreData = true;
|
||||
|
||||
do {
|
||||
const response = await httpClient.sendRequest<{ results: T[] }>({
|
||||
method,
|
||||
url: `${domain}/wiki/rest/api${resourceUri}?start=${start}&limit=100`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BASIC,
|
||||
username,
|
||||
password,
|
||||
},
|
||||
queryParams: qs,
|
||||
body,
|
||||
});
|
||||
if (isNil(response.body.results) || response.body.results.length === 0) {
|
||||
hasMoreData = false;
|
||||
} else {
|
||||
resultData.push(...response.body.results);
|
||||
start += 100;
|
||||
}
|
||||
} while (hasMoreData);
|
||||
}
|
||||
|
||||
return resultData;
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { confluenceApiCall, confluencePaginatedApiCall } from '.';
|
||||
import { confluenceAuth } from '../../index';
|
||||
import {
|
||||
DropdownOption,
|
||||
DynamicPropsValue,
|
||||
PiecePropValueSchema,
|
||||
Property,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { parseStringPromise } from 'xml2js';
|
||||
|
||||
export const spaceIdProp = Property.Dropdown({
|
||||
auth: confluenceAuth,
|
||||
displayName: 'Space',
|
||||
refreshers: [],
|
||||
required: true,
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please connect your account first.',
|
||||
};
|
||||
}
|
||||
|
||||
const spaces = await confluencePaginatedApiCall<{ id: string; name: string }>({
|
||||
domain: auth.props.confluenceDomain,
|
||||
username: auth.props.username,
|
||||
password: auth.props.password,
|
||||
version: 'v2',
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: '/spaces',
|
||||
});
|
||||
|
||||
const options: DropdownOption<string>[] = [];
|
||||
for (const space of spaces) {
|
||||
options.push({
|
||||
label: space.name,
|
||||
value: space.id,
|
||||
});
|
||||
}
|
||||
return {
|
||||
disabled: false,
|
||||
options,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const templateIdProp = Property.Dropdown({
|
||||
displayName: 'Template',
|
||||
auth: confluenceAuth,
|
||||
refreshers: ['spaceId'],
|
||||
required: true,
|
||||
options: async ({ auth, spaceId }) => {
|
||||
if (!auth || !spaceId) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please connect your account first and select a space.',
|
||||
};
|
||||
}
|
||||
|
||||
const space = await confluenceApiCall<{ id: string; name: string; key: string }>({
|
||||
domain: auth.props.confluenceDomain,
|
||||
username: auth.props.username,
|
||||
password: auth.props.password,
|
||||
method: HttpMethod.GET,
|
||||
version: 'v2',
|
||||
resourceUri: `/spaces/${spaceId}`,
|
||||
});
|
||||
|
||||
const templates = await confluencePaginatedApiCall<{ templateId: string; name: string }>({
|
||||
domain: auth.props.confluenceDomain,
|
||||
username: auth.props.username,
|
||||
password: auth.props.password,
|
||||
version: 'v1',
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/template/page`,
|
||||
query: { spaceKey: space.key },
|
||||
});
|
||||
|
||||
const options: DropdownOption<string>[] = [];
|
||||
for (const template of templates) {
|
||||
options.push({
|
||||
label: template.name,
|
||||
value: template.templateId,
|
||||
});
|
||||
}
|
||||
return {
|
||||
disabled: false,
|
||||
options,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const folderIdProp = Property.Dropdown({
|
||||
displayName:'Parent Folder',
|
||||
auth: confluenceAuth,
|
||||
refreshers:['spaceId'],
|
||||
required:false,
|
||||
options:async ({auth,spaceId})=>{
|
||||
if (!auth || !spaceId) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Please connect your account first and select a space.',
|
||||
};
|
||||
}
|
||||
|
||||
const space = await confluenceApiCall<{ id: string; name: string; key: string,homepageId:string }>({
|
||||
domain: auth.props.confluenceDomain,
|
||||
username: auth.props.username,
|
||||
password: auth.props.password,
|
||||
method: HttpMethod.GET,
|
||||
version: 'v2',
|
||||
resourceUri: `/spaces/${spaceId}`,
|
||||
});
|
||||
|
||||
const folders = await confluencePaginatedApiCall<{id:string,title:string}>({
|
||||
domain:auth.props.confluenceDomain,
|
||||
username:auth.props.username,
|
||||
password:auth.props.password,
|
||||
version:'v1',
|
||||
method:HttpMethod.GET,
|
||||
resourceUri:`/content/${space.homepageId}/descendant/folder`,
|
||||
})
|
||||
|
||||
const options:DropdownOption<string>[] = [];
|
||||
for(const folder of folders){
|
||||
options.push({
|
||||
label:folder.title,
|
||||
value:folder.id
|
||||
})
|
||||
}
|
||||
return{
|
||||
disabled:false,
|
||||
options
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export const templateVariablesProp = Property.DynamicProperties({
|
||||
displayName: 'Template Variables',
|
||||
auth: confluenceAuth,
|
||||
refreshers: ['templateId'],
|
||||
required: true,
|
||||
props: async ({ auth, templateId }) => {
|
||||
if (!auth) return {};
|
||||
if (!templateId) return {};
|
||||
|
||||
const props: DynamicPropsValue = {};
|
||||
|
||||
const response = await confluenceApiCall<{ body: { storage: { value: string } } }>({
|
||||
domain: auth.props.confluenceDomain,
|
||||
username: auth.props.username,
|
||||
password: auth.props.password,
|
||||
method: HttpMethod.GET,
|
||||
version: 'v1',
|
||||
resourceUri: `/template/${templateId}`,
|
||||
});
|
||||
|
||||
const parsedXml = await parseStringPromise(response.body.storage.value, {
|
||||
explicitArray: false,
|
||||
});
|
||||
const declarations = parsedXml['at:declarations'];
|
||||
|
||||
if (!declarations) return {};
|
||||
|
||||
const variables: Array<{ name: string; type: string; options?: string[] }> = [];
|
||||
|
||||
Object.entries(declarations).forEach(([key, value]: [string, any]) => {
|
||||
const type = key.replace('at:', '');
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach((item) => {
|
||||
if (item['$']) {
|
||||
const varName = item['$']['at:name'];
|
||||
let options: string[] | undefined;
|
||||
|
||||
if (type === 'list' && item['at:option']) {
|
||||
options = item['at:option'].map((opt: any) => opt['$']['at:value']);
|
||||
}
|
||||
|
||||
if (varName && type) {
|
||||
variables.push({
|
||||
name: varName,
|
||||
type: type,
|
||||
options: options,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (value['$']) {
|
||||
const varName = value['$']['at:name'];
|
||||
let options: string[] | undefined;
|
||||
|
||||
if (type === 'list' && value['at:option']) {
|
||||
options = value['at:option'].map((opt: any) => opt['$']['at:value']);
|
||||
}
|
||||
|
||||
if (varName && type) {
|
||||
variables.push({
|
||||
name: varName,
|
||||
type: type,
|
||||
options: options,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
for (const variable of variables) {
|
||||
switch (variable.type) {
|
||||
case 'list':
|
||||
props[variable.name] = Property.StaticDropdown({
|
||||
displayName: variable.name,
|
||||
required: false,
|
||||
defaultValue: '',
|
||||
options: {
|
||||
disabled: false,
|
||||
options: variable.options
|
||||
? variable.options.map((option) => {
|
||||
return {
|
||||
label: option,
|
||||
value: option,
|
||||
};
|
||||
})
|
||||
: [],
|
||||
},
|
||||
});
|
||||
break;
|
||||
case 'string':
|
||||
props[variable.name] = Property.ShortText({
|
||||
displayName: variable.name,
|
||||
required: false,
|
||||
defaultValue: '',
|
||||
});
|
||||
break;
|
||||
case 'textarea':
|
||||
props[variable.name] = Property.LongText({
|
||||
displayName: variable.name,
|
||||
required: false,
|
||||
defaultValue: '',
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return props;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,126 @@
|
||||
import {
|
||||
createTrigger,
|
||||
TriggerStrategy,
|
||||
PiecePropValueSchema,
|
||||
AppConnectionValueForAuthProperty,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { DedupeStrategy, Polling, pollingHelper, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { confluenceAuth } from '../../index';
|
||||
import { confluenceApiCall, confluencePaginatedApiCall, PaginatedResponse } from '../common';
|
||||
import { isNil } from '@activepieces/shared';
|
||||
import { spaceIdProp } from '../common/props';
|
||||
|
||||
interface ConfluencePage {
|
||||
id: string;
|
||||
status: string;
|
||||
title: string;
|
||||
spaceId: string;
|
||||
createdAt: string;
|
||||
version: {
|
||||
number: number;
|
||||
createdAt: string;
|
||||
};
|
||||
}
|
||||
|
||||
type Props = {
|
||||
spaceId: string;
|
||||
};
|
||||
|
||||
const polling: Polling<AppConnectionValueForAuthProperty<typeof confluenceAuth>, Props> = {
|
||||
strategy: DedupeStrategy.TIMEBASED,
|
||||
async items({ auth, propsValue, lastFetchEpochMS }) {
|
||||
const pages = [];
|
||||
if (lastFetchEpochMS === 0) {
|
||||
const response = await confluenceApiCall<PaginatedResponse<ConfluencePage>>({
|
||||
domain: auth.props.confluenceDomain,
|
||||
username: auth.props.username,
|
||||
password: auth.props.password,
|
||||
version: 'v2',
|
||||
method: HttpMethod.GET,
|
||||
resourceUri: `/spaces/${propsValue.spaceId}/pages`,
|
||||
query: {
|
||||
limit: '10',
|
||||
sort: '-created-date',
|
||||
},
|
||||
});
|
||||
if (isNil(response.results)) {
|
||||
return [];
|
||||
}
|
||||
pages.push(...response.results);
|
||||
} else {
|
||||
const response = await confluencePaginatedApiCall<ConfluencePage>({
|
||||
domain: auth.props.confluenceDomain,
|
||||
username: auth.props.username,
|
||||
password: auth.props.password,
|
||||
method: HttpMethod.GET,
|
||||
version: 'v2',
|
||||
resourceUri: `/spaces/${propsValue.spaceId}/pages`,
|
||||
query: {
|
||||
sort: '-created-date',
|
||||
},
|
||||
});
|
||||
if (isNil(response)) {
|
||||
return [];
|
||||
}
|
||||
pages.push(...response);
|
||||
}
|
||||
|
||||
return pages.map((page) => {
|
||||
return {
|
||||
epochMilliSeconds: new Date(page.createdAt).getTime(),
|
||||
data: page,
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const newPageTrigger = createTrigger({
|
||||
name: 'new-page',
|
||||
displayName: 'New Page',
|
||||
description: 'Triggers when a new page is created.',
|
||||
auth: confluenceAuth,
|
||||
type: TriggerStrategy.POLLING,
|
||||
props: {
|
||||
spaceId: spaceIdProp,
|
||||
},
|
||||
|
||||
async onEnable(context) {
|
||||
await pollingHelper.onEnable(polling, context);
|
||||
},
|
||||
async onDisable(context) {
|
||||
await pollingHelper.onDisable(polling, context);
|
||||
},
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context);
|
||||
},
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context);
|
||||
},
|
||||
sampleData: {
|
||||
parentType: 'page',
|
||||
parentId: '123456',
|
||||
spaceId: 'SAMPLE123',
|
||||
ownerId: '12345678abcd',
|
||||
lastOwnerId: null,
|
||||
createdAt: '2024-01-01T12:00:00.000Z',
|
||||
authorId: '12345678abcd',
|
||||
position: 1000,
|
||||
version: {
|
||||
number: 1,
|
||||
message: 'Initial version',
|
||||
minorEdit: false,
|
||||
authorId: '12345678abcd',
|
||||
createdAt: '2024-01-01T12:00:00.000Z',
|
||||
},
|
||||
body: {},
|
||||
status: 'current',
|
||||
title: 'Sample Confluence Page',
|
||||
id: '987654321',
|
||||
_links: {
|
||||
editui: '/pages/resumedraft.action?draftId=987654321',
|
||||
webui: '/spaces/SAMPLE/pages/987654321/Sample+Confluence+Page',
|
||||
edituiv2: '/spaces/SAMPLE/pages/edit-v2/987654321',
|
||||
tinyui: '/x/abcd123',
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -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