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:
poduck
2025-12-18 22:59:37 -05:00
parent 9848268d34
commit 3aa7199503
16292 changed files with 1284892 additions and 4708 deletions

View File

@@ -0,0 +1,33 @@
{
"extends": [
"../../../../.eslintrc.base.json"
],
"ignorePatterns": [
"!**/*"
],
"overrides": [
{
"files": [
"*.ts",
"*.tsx",
"*.js",
"*.jsx"
],
"rules": {}
},
{
"files": [
"*.ts",
"*.tsx"
],
"rules": {}
},
{
"files": [
"*.js",
"*.jsx"
],
"rules": {}
}
]
}

View File

@@ -0,0 +1,39 @@
# Placid
Placid is a creative automation engine that generates dynamic images, PDFs, and videos from templates and data. This integration empowers AI agents and workflows to produce and retrieve media assets automatically.
## Features
### Actions
- **Create Image**: Generate a dynamic image from a specified template using input data
- **Create PDF**: Generate a PDF document from a specified template
- **Create Video**: Produce a video based on a template
- **Convert File to URL**: Convert uploaded file(s) into media URL(s) consumable by Placid templates
- **Get Image**: Retrieve a generated image by its ID (especially after processing delay)
- **Get PDF**: Retrieve the generated PDF by its ID
- **Get Video**: Retrieve the generated video by its ID
## Authentication
This piece requires a Placid API token. You can obtain your API token by:
1. Logging in to [placid.app](https://placid.app/login)
2. Going to your Projects overview
3. Selecting your desired project
4. Clicking "API Tokens" in the left menu
## Logo Requirements
This piece requires a logo to be uploaded to the Activepieces CDN at:
`https://cdn.activepieces.com/pieces/placid.png`
### Logo Files Included:
- `placid-logo.png` - Downloaded from Placid's official site
### For Maintainers:
Please upload the logo file to the CDN during the merge process.
## Documentation
- [Placid API Documentation](https://placid.app/docs/2.0/rest/)
- [Placid Templates](https://placid.app/templates)

View File

@@ -0,0 +1,4 @@
{
"name": "@activepieces/piece-placid",
"version": "0.0.9"
}

View File

@@ -0,0 +1,65 @@
{
"name": "pieces-placid",
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/pieces/community/placid/src",
"projectType": "library",
"release": {
"version": {
"manifestRootsToUpdate": [
"dist/{projectRoot}"
],
"currentVersionResolver": "git-tag",
"fallbackCurrentVersionResolver": "disk"
}
},
"tags": [],
"targets": {
"build": {
"executor": "@nx/js:tsc",
"outputs": [
"{options.outputPath}"
],
"options": {
"outputPath": "dist/packages/pieces/community/placid",
"tsConfig": "packages/pieces/community/placid/tsconfig.lib.json",
"packageJson": "packages/pieces/community/placid/package.json",
"main": "packages/pieces/community/placid/src/index.ts",
"assets": [
"packages/pieces/community/placid/*.md",
{
"input": "packages/pieces/community/placid/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/placid",
"command": "bun install --no-save --silent"
},
"dependsOn": [
"^build"
]
}
}
}

View File

@@ -0,0 +1,62 @@
{
"Creative automation engine that generates dynamic images, PDFs, and videos from templates and data.": "Creative Automation Engine, die dynamische Bilder, PDFs und Videos aus Vorlagen und Daten generiert.",
"\nTo obtain your Placid API token:\n\n1. Log in to [placid.app](https://placid.app/login).\n2. Go to Projects overview.\n3. Select your desired project.\n4. Click \"API Tokens\" in the left menu.\n5. Copy your API token.\n\nThe token is project-specific and will only work with templates from that project.": "\nUm Ihren Placid API Token zu erhalten:\n\n1. Melden Sie sich bei [placid.app]an (https://placid.app/login).\n2. Gehen Sie zur Projektübersicht.\n3. Wählen Sie Ihr gewünschtes Projekt.\n4. Klicken Sie im linken Menü auf \"API-Tokens\".\n5. Kopieren Sie Ihren API-Token.\n\nDer Token ist projektspezifisch und funktioniert nur mit Vorlagen aus diesem Projekt.",
"Create Image": "Bild erstellen",
"Create PDF": "PDF erstellen",
"Create Video": "Video erstellen",
"Convert File to URL": "Datei in URL konvertieren",
"Get Image": "Bild abrufen",
"Get PDF": "Get PDF",
"Get Video": "Video abrufen",
"Custom API Call": "Eigener API-Aufruf",
"Generates a dynamic image from a specified template using input data.": "Erzeugt ein dynamisches Bild aus einer bestimmten Vorlage mit Eingabedaten.",
"Generates a PDF document from a specified template.": "Erzeugt ein PDF-Dokument aus einer bestimmten Vorlage.",
"Produces a video based on a template.": "Produziert ein Video basierend auf einer Vorlage.",
"Convert uploaded file(s) into media URL(s) consumable by Placid templates.": "Konvertieren Sie hochgeladene Datei(en) in Medien-URL(s) für Placid-Vorlagen.",
"Retrieves a generated image by its ID.": "Ruft ein generiertes Bild durch seine ID ab.",
"Retrieves the generated PDF by its ID.": "Ruft das generierte PDF von seiner ID ab.",
"Retrieves the generated video by its ID.": "Ruft das generierte Video von seiner ID ab.",
"Make a custom API call to a specific endpoint": "Einen benutzerdefinierten API-Aufruf an einen bestimmten Endpunkt machen",
"Template": "Vorlage",
"Layers": "Ebenen",
"Output DPI": "Ausgabe DPI",
"Output File Name": "Dateiname ausgeben",
"Webhook URL": "Webhook-URL",
"Create Now": "Jetzt erstellen",
"Passthrough Text": "Durchlauftext",
"Output FPS": "Ausgabe FPS",
"File": "Datei",
"Filename": "Dateiname",
"Image ID": "Bild-ID",
"PDF ID": "PDF ID",
"Video ID": "Video ID",
"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)",
"Select a Placid template for image generation": "Wählen Sie eine Placid Vorlage für die Bildgenerierung",
"Optional webhook URL to receive notification when generation is complete.": "Optionale Webhook URL, um Benachrichtigungen zu erhalten, wenn die Erstellung abgeschlossen ist.",
"Whether to create the image immediately (synchronous) or queue it (asynchronous).": "Ob das Bild sofort (synchron) oder in der Warteschlange (asynchron) erstellt werden soll.",
"Select a Placid template for pdf generation": "Wählen Sie eine Placid Vorlage für die PDF-Generierung",
"Select a Placid template for video generation": "Wählen Sie eine Placid Vorlage für die Videogenerierung",
"The file to convert to a URL.": "Die Datei die in eine URL konvertiert wird.",
"Optional custom filename for the uploaded file.": "Optionaler benutzerdefinierter Dateiname für die hochgeladene Datei.",
"The ID of the image to retrieve.": "Die ID des abzufragenden Bildes.",
"The ID of the PDF to retrieve": "Die ID des abzuholenden PDF",
"The ID of the video to retrieve.": "Die ID des Videos abzurufen.",
"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..",
"72 DPI": "72 DPI",
"150 DPI": "150 DPI",
"300 DPI": "300 DPI",
"96 DPI": "96 DPI",
"GET": "ERHALTEN",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "LÖSCHEN",
"HEAD": "HEAD"
}

View File

@@ -0,0 +1,62 @@
{
"Creative automation engine that generates dynamic images, PDFs, and videos from templates and data.": "Motor de automatización creativa que genera imágenes dinámicas, PDFs y videos a partir de plantillas y datos.",
"\nTo obtain your Placid API token:\n\n1. Log in to [placid.app](https://placid.app/login).\n2. Go to Projects overview.\n3. Select your desired project.\n4. Click \"API Tokens\" in the left menu.\n5. Copy your API token.\n\nThe token is project-specific and will only work with templates from that project.": "\nTo obtain your Placid API token:\n\n1. Log in to [placid.app](https://placid.app/login).\n2. Go to Projects overview.\n3. Select your desired project.\n4. Click \"API Tokens\" in the left menu.\n5. Copy your API token.\n\nThe token is project-specific and will only work with templates from that project.",
"Create Image": "Crear imagen",
"Create PDF": "Crear PDF",
"Create Video": "Crear vídeo",
"Convert File to URL": "Convertir archivo a URL",
"Get Image": "Obtener imagen",
"Get PDF": "Get PDF",
"Get Video": "Obtener vídeo",
"Custom API Call": "Llamada API personalizada",
"Generates a dynamic image from a specified template using input data.": "Genera una imagen dinámica a partir de una plantilla especificada usando datos de entrada.",
"Generates a PDF document from a specified template.": "Genera un documento PDF a partir de una plantilla especificada.",
"Produces a video based on a template.": "Produce un vídeo basado en una plantilla.",
"Convert uploaded file(s) into media URL(s) consumable by Placid templates.": "Convierte archivo(s) subidos en URL(s) multimedia consumibles por Placid templates.",
"Retrieves a generated image by its ID.": "Recuperar una imagen generada por su ID.",
"Retrieves the generated PDF by its ID.": "Recuperar el PDF generado por su ID.",
"Retrieves the generated video by its ID.": "Recuperar el video generado por su ID.",
"Make a custom API call to a specific endpoint": "Hacer una llamada API personalizada a un extremo específico",
"Template": "Plantilla",
"Layers": "Capas",
"Output DPI": "DPI de salida",
"Output File Name": "Nombre del archivo de salida",
"Webhook URL": "URL de Webhook",
"Create Now": "Crear ahora",
"Passthrough Text": "Texto de paso",
"Output FPS": "FPS de salida",
"File": "Archivo",
"Filename": "Nombre de archivo",
"Image ID": "ID de imagen",
"PDF ID": "PDF ID",
"Video ID": "ID de vídeo",
"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)",
"Select a Placid template for image generation": "Seleccione una plantilla Placid para la generación de imágenes",
"Optional webhook URL to receive notification when generation is complete.": "URL opcional de webhook para recibir notificación cuando la generación se haya completado.",
"Whether to create the image immediately (synchronous) or queue it (asynchronous).": "Si crear la imagen inmediatamente (sincrónica) o colocarla en cola (asíncrona).",
"Select a Placid template for pdf generation": "Seleccione una plantilla Placid para la generación de pdf",
"Select a Placid template for video generation": "Seleccione una plantilla Placid para la generación de vídeo",
"The file to convert to a URL.": "El archivo a convertir a una URL.",
"Optional custom filename for the uploaded file.": "Nombre de archivo personalizado opcional para el archivo subido.",
"The ID of the image to retrieve.": "El ID de la imagen a recuperar.",
"The ID of the PDF to retrieve": "El ID del PDF para recuperar",
"The ID of the video to retrieve.": "El ID del video a recuperar.",
"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.",
"72 DPI": "72 DPI",
"150 DPI": "150 DPI",
"300 DPI": "300 DPI",
"96 DPI": "96 DPI",
"GET": "RECOGER",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "BORRAR",
"HEAD": "LIMPIO"
}

View File

@@ -0,0 +1,62 @@
{
"Creative automation engine that generates dynamic images, PDFs, and videos from templates and data.": "Moteur d'automatisation créatif qui génère des images dynamiques, des PDF et des vidéos à partir de modèles et de données.",
"\nTo obtain your Placid API token:\n\n1. Log in to [placid.app](https://placid.app/login).\n2. Go to Projects overview.\n3. Select your desired project.\n4. Click \"API Tokens\" in the left menu.\n5. Copy your API token.\n\nThe token is project-specific and will only work with templates from that project.": "\nTo obtain your Placid API token:\n\n1. Log in to [placid.app](https://placid.app/login).\n2. Go to Projects overview.\n3. Select your desired project.\n4. Click \"API Tokens\" in the left menu.\n5. Copy your API token.\n\nThe token is project-specific and will only work with templates from that project.",
"Create Image": "Créer une image",
"Create PDF": "Créer un PDF",
"Create Video": "Créer une vidéo",
"Convert File to URL": "Convertir le fichier en URL",
"Get Image": "Obtenir une image",
"Get PDF": "Get PDF",
"Get Video": "Obtenir la vidéo",
"Custom API Call": "Appel API personnalisé",
"Generates a dynamic image from a specified template using input data.": "Génère une image dynamique à partir d'un modèle spécifié en utilisant des données d'entrée.",
"Generates a PDF document from a specified template.": "Génère un document PDF à partir d'un modèle spécifié.",
"Produces a video based on a template.": "Produit une vidéo basée sur un modèle.",
"Convert uploaded file(s) into media URL(s) consumable by Placid templates.": "Convertir le(s) fichier(s) téléchargé(s) en URL(s) de média consommables par les gabarits Plact.",
"Retrieves a generated image by its ID.": "Récupère une image générée par son ID.",
"Retrieves the generated PDF by its ID.": "Récupère le PDF généré par son ID.",
"Retrieves the generated video by its ID.": "Récupère la vidéo générée par son ID.",
"Make a custom API call to a specific endpoint": "Passez un appel API personnalisé à un point de terminaison spécifique",
"Template": "Gabarit",
"Layers": "Couches",
"Output DPI": "DPI de sortie",
"Output File Name": "Nom du fichier de sortie",
"Webhook URL": "URL du Webhook",
"Create Now": "Créer maintenant",
"Passthrough Text": "Texte de passage",
"Output FPS": "FPS de sortie",
"File": "Ficher",
"Filename": "Nom du fichier",
"Image ID": "ID de l'image",
"PDF ID": "PDF ID",
"Video ID": "ID Vidéo",
"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)",
"Select a Placid template for image generation": "Sélectionnez un modèle de Placide pour la génération d'images",
"Optional webhook URL to receive notification when generation is complete.": "URL optionnelle du webhook pour recevoir une notification lorsque la génération est terminée.",
"Whether to create the image immediately (synchronous) or queue it (asynchronous).": "Que ce soit pour créer immédiatement l'image (synchronisée) ou la mettre en file d'attente (asynchrone).",
"Select a Placid template for pdf generation": "Sélectionnez un modèle de Placid pour la génération de pdf",
"Select a Placid template for video generation": "Sélectionnez un modèle de Placid pour la génération de vidéos",
"The file to convert to a URL.": "Le fichier à convertir en URL.",
"Optional custom filename for the uploaded file.": "Nom de fichier personnalisé optionnel pour le fichier téléchargé.",
"The ID of the image to retrieve.": "L'ID de l'image à récupérer.",
"The ID of the PDF to retrieve": "L'ID du PDF à récupérer",
"The ID of the video to retrieve.": "L'ID de la vidéo à récupérer.",
"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.",
"72 DPI": "72 DPI",
"150 DPI": "150 DPI",
"300 DPI": "300 DPI",
"96 DPI": "96 DPI",
"GET": "OBTENIR",
"POST": "POSTER",
"PATCH": "PATCH",
"PUT": "EFFACER",
"DELETE": "SUPPRIMER",
"HEAD": "TÊTE"
}

View File

@@ -0,0 +1,62 @@
{
"Creative automation engine that generates dynamic images, PDFs, and videos from templates and data.": "テンプレートとデータからダイナミックな画像、PDF、ビデオを生成するクリエイティブオートメーションエンジン。",
"\nTo obtain your Placid API token:\n\n1. Log in to [placid.app](https://placid.app/login).\n2. Go to Projects overview.\n3. Select your desired project.\n4. Click \"API Tokens\" in the left menu.\n5. Copy your API token.\n\nThe token is project-specific and will only work with templates from that project.": "\nTo obtain your Placid API token:\n\n1. Log in to [placid.app](https://placid.app/login).\n2. Go to Projects overview.\n3. Select your desired project.\n4. Click \"API Tokens\" in the left menu.\n5. Copy your API token.\n\nThe token is project-specific and will only work with templates from that project.",
"Create Image": "画像を作成",
"Create PDF": "PDFを作成",
"Create Video": "ビデオを作成",
"Convert File to URL": "ファイルを URL に変換する",
"Get Image": "画像を取得",
"Get PDF": "Get PDF",
"Get Video": "ビデオを取得する",
"Custom API Call": "カスタムAPI通話",
"Generates a dynamic image from a specified template using input data.": "入力データを使用して、指定したテンプレートから動的イメージを生成します。",
"Generates a PDF document from a specified template.": "指定したテンプレートから PDF ドキュメントを生成します。",
"Produces a video based on a template.": "テンプレートに基づいてビデオを作成します。",
"Convert uploaded file(s) into media URL(s) consumable by Placid templates.": "アップロードされたファイルをPlacidテンプレートが消耗できるメディア URLに変換します。",
"Retrieves a generated image by its ID.": "生成された画像を ID で取得します。",
"Retrieves the generated PDF by its ID.": "生成された PDF を ID で取得します。",
"Retrieves the generated video by its ID.": "生成されたビデオを ID で取得します。",
"Make a custom API call to a specific endpoint": "特定のエンドポイントへのカスタム API コールを実行します。",
"Template": "テンプレート",
"Layers": "レイヤー",
"Output DPI": "出力DPI",
"Output File Name": "出力ファイル名",
"Webhook URL": "Webhook URL",
"Create Now": "今すぐ作成",
"Passthrough Text": "パススルーテキスト",
"Output FPS": "出力FPS",
"File": "ファイル",
"Filename": "ファイル名",
"Image ID": "画像ID",
"PDF ID": "PDF ID",
"Video ID": "ビデオ ID",
"Method": "方法",
"Headers": "ヘッダー",
"Query Parameters": "クエリパラメータ",
"Body": "本文",
"Response is Binary ?": "応答はバイナリですか?",
"No Error on Failure": "失敗時にエラーはありません",
"Timeout (in seconds)": "タイムアウト(秒)",
"Select a Placid template for image generation": "画像生成用のPlacidテンプレートを選択してください",
"Optional webhook URL to receive notification when generation is complete.": "生成が完了したら通知を受け取るオプションの webhook URL。",
"Whether to create the image immediately (synchronous) or queue it (asynchronous).": "すぐに画像を作成するか(同期)、キューに入れるか(非同期)。",
"Select a Placid template for pdf generation": "PDF生成用のPlacidテンプレートを選択",
"Select a Placid template for video generation": "動画生成用のPlacidテンプレートを選択",
"The file to convert to a URL.": "URLに変換するファイル。",
"Optional custom filename for the uploaded file.": "アップロードされたファイルのオプションのカスタムファイル名。",
"The ID of the image to retrieve.": "取得する画像のID。",
"The ID of the PDF to retrieve": "取得するPDFのID",
"The ID of the video to retrieve.": "取得するビデオのID。",
"Authorization headers are injected automatically from your connection.": "認証ヘッダは接続から自動的に注入されます。",
"Enable for files like PDFs, images, etc..": "PDF、画像などのファイルを有効にします。",
"72 DPI": "72 DPI",
"150 DPI": "150 DPI",
"300 DPI": "300 DPI",
"96 DPI": "96 DPI",
"GET": "取得",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "削除",
"HEAD": "頭"
}

View File

@@ -0,0 +1,62 @@
{
"Creative automation engine that generates dynamic images, PDFs, and videos from templates and data.": "Creatieve automatiseringsmotor die dynamische afbeeldingen, PDF's en video's genereert.",
"\nTo obtain your Placid API token:\n\n1. Log in to [placid.app](https://placid.app/login).\n2. Go to Projects overview.\n3. Select your desired project.\n4. Click \"API Tokens\" in the left menu.\n5. Copy your API token.\n\nThe token is project-specific and will only work with templates from that project.": "\nOm je Placid API te verkrijgen:\n\n1. Log in op [placid.app](https://placid.app/login).\n2. Ga naar Projecten overzicht.\n3. Selecteer het gewenste project.\n4. Klik op \"API Tokens\" in het linkermenu.\n5. Kopieer je API-token.\n\nHet token is project-specifiek en werkt alleen met sjablonen uit dat project.",
"Create Image": "Afbeelding aanmaken",
"Create PDF": "PDF maken",
"Create Video": "Video maken",
"Convert File to URL": "Bestand omzetten naar URL",
"Get Image": "Afbeelding ophalen",
"Get PDF": "Get PDF",
"Get Video": "Video ophalen",
"Custom API Call": "Custom API Call",
"Generates a dynamic image from a specified template using input data.": "Genereert een dynamische afbeelding van een specifieke sjabloon met behulp van invoergegevens.",
"Generates a PDF document from a specified template.": "Genereert een PDF-document van een specifiek sjabloon.",
"Produces a video based on a template.": "Produceert een video gebaseerd op een sjabloon.",
"Convert uploaded file(s) into media URL(s) consumable by Placid templates.": "Converteer geüploade bestand(en) naar media URL(s) verbruikbaar door Placid sjablonen.",
"Retrieves a generated image by its ID.": "Haal een gegenereerde afbeelding op met zijn ID.",
"Retrieves the generated PDF by its ID.": "Ophalen van de gegenereerde PDF met zijn ID.",
"Retrieves the generated video by its ID.": "Ophalen van de gegenereerde video met zijn ID.",
"Make a custom API call to a specific endpoint": "Maak een aangepaste API call naar een specifiek eindpunt",
"Template": "Sjabloon",
"Layers": "Lagen",
"Output DPI": "Uitvoer DPI",
"Output File Name": "Uitvoer bestandsnaam",
"Webhook URL": "Webhook URL",
"Create Now": "Nu aanmaken",
"Passthrough Text": "Tekst doorsturen",
"Output FPS": "Uitvoer FPS",
"File": "Bestand",
"Filename": "Bestandsnaam",
"Image ID": "Afbeelding ID",
"PDF ID": "PDF ID",
"Video ID": "Video ID",
"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)",
"Select a Placid template for image generation": "Selecteer een Placid-sjabloon voor het genereren van afbeeldingen",
"Optional webhook URL to receive notification when generation is complete.": "Optionele webhook URL om een melding te ontvangen als de generatie is voltooid.",
"Whether to create the image immediately (synchronous) or queue it (asynchronous).": "Onmiddellijk de afbeelding aanmaken (gesynchroniseerd) of in de wachtrij (asynchroon gebruiken).",
"Select a Placid template for pdf generation": "Selecteer een sjabloon voor de pdf generatie",
"Select a Placid template for video generation": "Selecteer een Placid-sjabloon voor het genereren van video's",
"The file to convert to a URL.": "Het bestand om te converteren naar een URL.",
"Optional custom filename for the uploaded file.": "Optionele aangepaste bestandsnaam voor het geüploade bestand.",
"The ID of the image to retrieve.": "Het ID van de afbeelding om op te halen.",
"The ID of the PDF to retrieve": "Het op te halen ID van de PDF",
"The ID of the video to retrieve.": "Het ID van de op te halen video.",
"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..",
"72 DPI": "72 DPI",
"150 DPI": "150 DPI",
"300 DPI": "300 DPI",
"96 DPI": "96 DPI",
"GET": "KRIJG",
"POST": "POSTE",
"PATCH": "BEKIJK",
"PUT": "PUT",
"DELETE": "VERWIJDEREN",
"HEAD": "HOOFD"
}

View File

@@ -0,0 +1,62 @@
{
"Creative automation engine that generates dynamic images, PDFs, and videos from templates and data.": "Motor de automação criativo que gera imagens dinâmicas, PDFs e vídeos a partir de modelos e dados.",
"\nTo obtain your Placid API token:\n\n1. Log in to [placid.app](https://placid.app/login).\n2. Go to Projects overview.\n3. Select your desired project.\n4. Click \"API Tokens\" in the left menu.\n5. Copy your API token.\n\nThe token is project-specific and will only work with templates from that project.": "\nTo obtain your Placid API token:\n\n1. Log in to [placid.app](https://placid.app/login).\n2. Go to Projects overview.\n3. Select your desired project.\n4. Click \"API Tokens\" in the left menu.\n5. Copy your API token.\n\nThe token is project-specific and will only work with templates from that project.",
"Create Image": "Criar imagem",
"Create PDF": "Criar PDF",
"Create Video": "Criar vídeo",
"Convert File to URL": "Converter Arquivo para URL",
"Get Image": "Obter Imagem",
"Get PDF": "Get PDF",
"Get Video": "Obter vídeo",
"Custom API Call": "Chamada de API personalizada",
"Generates a dynamic image from a specified template using input data.": "Gera uma imagem dinâmica a partir de um modelo especificado usando os dados de entrada.",
"Generates a PDF document from a specified template.": "Gera um documento PDF de um modelo especificado.",
"Produces a video based on a template.": "Produz um vídeo com base em um modelo.",
"Convert uploaded file(s) into media URL(s) consumable by Placid templates.": "Converter arquivo(s) enviado(s) em URL(s) de mídia consumível por modelos Placid.",
"Retrieves a generated image by its ID.": "Recupera uma imagem gerada por seu ID.",
"Retrieves the generated PDF by its ID.": "Recupera o PDF gerado por seu ID.",
"Retrieves the generated video by its ID.": "Recupera o vídeo gerado por sua ID.",
"Make a custom API call to a specific endpoint": "Faça uma chamada de API personalizada para um ponto de extremidade específico",
"Template": "Modelo",
"Layers": "Camadas",
"Output DPI": "Saída DPI",
"Output File Name": "Nome do arquivo de saída",
"Webhook URL": "URL do webhook",
"Create Now": "Criar Agora",
"Passthrough Text": "Texto de Passagem",
"Output FPS": "FPS de saída",
"File": "Arquivo",
"Filename": "Nome",
"Image ID": "ID da imagem",
"PDF ID": "PDF ID",
"Video ID": "ID do Vídeo",
"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)",
"Select a Placid template for image generation": "Selecione um modelo de planície para a geração de imagens",
"Optional webhook URL to receive notification when generation is complete.": "URL opcional do webhook para receber notificação quando a geração estiver concluída.",
"Whether to create the image immediately (synchronous) or queue it (asynchronous).": "Se para criar a imagem imediatamente (sincronizar) ou enfileirá-la (assíncrona).",
"Select a Placid template for pdf generation": "Selecione um modelo de formatação para geração de PDF",
"Select a Placid template for video generation": "Selecione um modelo simples para geração de vídeo",
"The file to convert to a URL.": "O arquivo a ser convertido para uma URL.",
"Optional custom filename for the uploaded file.": "Nome de arquivo personalizado opcional para o arquivo enviado.",
"The ID of the image to retrieve.": "O ID da imagem a recuperar.",
"The ID of the PDF to retrieve": "A ID do PDF para recuperar",
"The ID of the video to retrieve.": "A identificação do vídeo a recuperar.",
"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..",
"72 DPI": "72 DPI",
"150 DPI": "150 DPI",
"300 DPI": "300 DPI",
"96 DPI": "96 DPI",
"GET": "OBTER",
"POST": "POSTAR",
"PATCH": "COMPRAR",
"PUT": "COLOCAR",
"DELETE": "EXCLUIR",
"HEAD": "CABEÇA"
}

View File

@@ -0,0 +1,61 @@
{
"Placid": "Пласиновый",
"Creative automation engine that generates dynamic images, PDFs, and videos from templates and data.": "Система автоматизации творчества, которая генерирует динамические изображения, PDF-файлы и видео из шаблонов и данных.",
"\nTo obtain your Placid API token:\n\n1. Log in to [placid.app](https://placid.app/login).\n2. Go to Projects overview.\n3. Select your desired project.\n4. Click \"API Tokens\" in the left menu.\n5. Copy your API token.\n\nThe token is project-specific and will only work with templates from that project.": "\nДля получения вашего ключа Placid API:\n\n1. Войдите в [placid.app](https://placid.app/login).\n2. Перейдите к обзору проектов.\n3. Выберите желаемый проект.\n4. Нажмите \"API Tokens\" в левом меню.\n5. Скопируйте ваш API токен.\n\nТокен специфичен для проекта и будет работать только с шаблонами этого проекта.",
"Create Image": "Создать изображение",
"Create PDF": "Создать PDF",
"Create Video": "Создать видео",
"Convert File to URL": "Преобразовать файл в URL",
"Get Image": "Получить изображение",
"Get PDF": "Get PDF",
"Get Video": "Скачать видео",
"Custom API Call": "Пользовательский вызов API",
"Generates a dynamic image from a specified template using input data.": "Генерирует динамическое изображение из указанного шаблона, используя входные данные.",
"Generates a PDF document from a specified template.": "Генерирует PDF документ из указанного шаблона.",
"Produces a video based on a template.": "Создает видео на основе шаблона.",
"Convert uploaded file(s) into media URL(s) consumable by Placid templates.": "Конвертируйте загруженные файлы в URL-адрес(ы) медиафайлов по шаблонам Placid.",
"Retrieves a generated image by its ID.": "Возвращает сгенерированное изображение по его ID.",
"Retrieves the generated PDF by its ID.": "Возвращает сгенерированный PDF по его ID.",
"Retrieves the generated video by its ID.": "Возвращает сгенерированное видео по его ID.",
"Make a custom API call to a specific endpoint": "Сделать пользовательский API вызов к определенной конечной точке",
"Template": "Шаблон",
"Layers": "Слои",
"Output DPI": "Вывод DPI",
"Output File Name": "Имя файла вывода",
"Webhook URL": "URL вебхука",
"Create Now": "Создать сейчас",
"Passthrough Text": "Просквозной текст",
"Output FPS": "Вывод FPS",
"File": "Файл",
"Filename": "Имя файла",
"Image ID": "ID изображения",
"PDF ID": "PDF ID",
"Video ID": "ID видео",
"Method": "Метод",
"Headers": "Заголовки",
"Query Parameters": "Параметры запроса",
"Body": "Тело",
"No Error on Failure": "Нет ошибок при ошибке",
"Timeout (in seconds)": "Таймаут (в секундах)",
"Select a Placid template for image generation": "Выберите шаблон Placid для генерации изображений",
"Optional webhook URL to receive notification when generation is complete.": "Необязательный URL-адрес webhook для получения уведомления о завершении генерации.",
"Whether to create the image immediately (synchronous) or queue it (asynchronous).": "Создать изображение немедленно (синхронизированное) или в очереди (асинхронное).",
"Select a Placid template for pdf generation": "Выберите шаблон Placid для pdf генерации",
"Select a Placid template for video generation": "Выберите шаблон Placid для генерации видео",
"The file to convert to a URL.": "Файл для преобразования в URL.",
"Optional custom filename for the uploaded file.": "Необязательное пользовательское имя файла для загруженного файла.",
"The ID of the image to retrieve.": "ID изображения для извлечения.",
"The ID of the PDF to retrieve": "ID PDF для извлечения",
"The ID of the video to retrieve.": "Идентификатор загружаемого видео.",
"Authorization headers are injected automatically from your connection.": "Заголовки авторизации включаются автоматически из вашего соединения.",
"72 DPI": "72 DPI",
"150 DPI": "150 DPI",
"300 DPI": "300 DPI",
"96 DPI": "96 DPI",
"GET": "ПОЛУЧИТЬ",
"POST": "ПОСТ",
"PATCH": "ПАТЧ",
"PUT": "ПОКУПИТЬ",
"DELETE": "УДАЛИТЬ",
"HEAD": "HEAD"
}

View File

@@ -0,0 +1,62 @@
{
"Creative automation engine that generates dynamic images, PDFs, and videos from templates and data.": "Creative automation engine that generates dynamic images, PDFs, and videos from templates and data.",
"\nTo obtain your Placid API token:\n\n1. Log in to [placid.app](https://placid.app/login).\n2. Go to Projects overview.\n3. Select your desired project.\n4. Click \"API Tokens\" in the left menu.\n5. Copy your API token.\n\nThe token is project-specific and will only work with templates from that project.": "\nTo obtain your Placid API token:\n\n1. Log in to [placid.app](https://placid.app/login).\n2. Go to Projects overview.\n3. Select your desired project.\n4. Click \"API Tokens\" in the left menu.\n5. Copy your API token.\n\nThe token is project-specific and will only work with templates from that project.",
"Create Image": "Create Image",
"Create PDF": "Create PDF",
"Create Video": "Create Video",
"Convert File to URL": "Convert File to URL",
"Get Image": "Get Image",
"Get PDF": "Get PDF",
"Get Video": "Get Video",
"Custom API Call": "Custom API Call",
"Generates a dynamic image from a specified template using input data.": "Generates a dynamic image from a specified template using input data.",
"Generates a PDF document from a specified template.": "Generates a PDF document from a specified template.",
"Produces a video based on a template.": "Produces a video based on a template.",
"Convert uploaded file(s) into media URL(s) consumable by Placid templates.": "Convert uploaded file(s) into media URL(s) consumable by Placid templates.",
"Retrieves a generated image by its ID.": "Retrieves a generated image by its ID.",
"Retrieves the generated PDF by its ID.": "Retrieves the generated PDF by its ID.",
"Retrieves the generated video by its ID.": "Retrieves the generated video by its ID.",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Template": "Template",
"Layers": "Layers",
"Output DPI": "Output DPI",
"Output File Name": "Output File Name",
"Webhook URL": "Webhook URL",
"Create Now": "Create Now",
"Passthrough Text": "Passthrough Text",
"Output FPS": "Output FPS",
"File": "File",
"Filename": "Filename",
"Image ID": "Image ID",
"PDF ID": "PDF ID",
"Video ID": "Video ID",
"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)",
"Select a Placid template for image generation": "Select a Placid template for image generation",
"Optional webhook URL to receive notification when generation is complete.": "Optional webhook URL to receive notification when generation is complete.",
"Whether to create the image immediately (synchronous) or queue it (asynchronous).": "Whether to create the image immediately (synchronous) or queue it (asynchronous).",
"Select a Placid template for pdf generation": "Select a Placid template for pdf generation",
"Select a Placid template for video generation": "Select a Placid template for video generation",
"The file to convert to a URL.": "The file to convert to a URL.",
"Optional custom filename for the uploaded file.": "Optional custom filename for the uploaded file.",
"The ID of the image to retrieve.": "The ID of the image to retrieve.",
"The ID of the PDF to retrieve": "The ID of the PDF to retrieve",
"The ID of the video to retrieve.": "The ID of the video to retrieve.",
"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..",
"72 DPI": "72 DPI",
"150 DPI": "150 DPI",
"300 DPI": "300 DPI",
"96 DPI": "96 DPI",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD"
}

View File

@@ -0,0 +1,61 @@
{
"Placid": "Placid",
"Creative automation engine that generates dynamic images, PDFs, and videos from templates and data.": "Creative automation engine that generates dynamic images, PDFs, and videos from templates and data.",
"\nTo obtain your Placid API token:\n\n1. Log in to [placid.app](https://placid.app/login).\n2. Go to Projects overview.\n3. Select your desired project.\n4. Click \"API Tokens\" in the left menu.\n5. Copy your API token.\n\nThe token is project-specific and will only work with templates from that project.": "\nTo obtain your Placid API token:\n\n1. Log in to [placid.app](https://placid.app/login).\n2. Go to Projects overview.\n3. Select your desired project.\n4. Click \"API Tokens\" in the left menu.\n5. Copy your API token.\n\nThe token is project-specific and will only work with templates from that project.",
"Create Image": "Create Image",
"Create PDF": "Create PDF",
"Create Video": "Create Video",
"Convert File to URL": "Convert File to URL",
"Get Image": "Get Image",
"Get PDF": "Get PDF",
"Get Video": "Get Video",
"Custom API Call": "Custom API Call",
"Generates a dynamic image from a specified template using input data.": "Generates a dynamic image from a specified template using input data.",
"Generates a PDF document from a specified template.": "Generates a PDF document from a specified template.",
"Produces a video based on a template.": "Produces a video based on a template.",
"Convert uploaded file(s) into media URL(s) consumable by Placid templates.": "Convert uploaded file(s) into media URL(s) consumable by Placid templates.",
"Retrieves a generated image by its ID.": "Retrieves a generated image by its ID.",
"Retrieves the generated PDF by its ID.": "Retrieves the generated PDF by its ID.",
"Retrieves the generated video by its ID.": "Retrieves the generated video by its ID.",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Template": "Template",
"Layers": "Layers",
"Output DPI": "Output DPI",
"Output File Name": "Output File Name",
"Webhook URL": "Webhook URL",
"Create Now": "Create Now",
"Passthrough Text": "Passthrough Text",
"Output FPS": "Output FPS",
"File": "File",
"Filename": "Filename",
"Image ID": "Image ID",
"PDF ID": "PDF ID",
"Video ID": "Video ID",
"Method": "Method",
"Headers": "Headers",
"Query Parameters": "Query Parameters",
"Body": "Body",
"No Error on Failure": "No Error on Failure",
"Timeout (in seconds)": "Timeout (in seconds)",
"Select a Placid template for image generation": "Select a Placid template for image generation",
"Optional webhook URL to receive notification when generation is complete.": "Optional webhook URL to receive notification when generation is complete.",
"Whether to create the image immediately (synchronous) or queue it (asynchronous).": "Whether to create the image immediately (synchronous) or queue it (asynchronous).",
"Select a Placid template for pdf generation": "Select a Placid template for pdf generation",
"Select a Placid template for video generation": "Select a Placid template for video generation",
"The file to convert to a URL.": "The file to convert to a URL.",
"Optional custom filename for the uploaded file.": "Optional custom filename for the uploaded file.",
"The ID of the image to retrieve.": "The ID of the image to retrieve.",
"The ID of the PDF to retrieve": "The ID of the PDF to retrieve",
"The ID of the video to retrieve.": "The ID of the video to retrieve.",
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
"72 DPI": "72 DPI",
"150 DPI": "150 DPI",
"300 DPI": "300 DPI",
"96 DPI": "96 DPI",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD"
}

View File

@@ -0,0 +1,62 @@
{
"Creative automation engine that generates dynamic images, PDFs, and videos from templates and data.": "Creative automation engine that generates dynamic images, PDFs, and videos from templates and data.",
"\nTo obtain your Placid API token:\n\n1. Log in to [placid.app](https://placid.app/login).\n2. Go to Projects overview.\n3. Select your desired project.\n4. Click \"API Tokens\" in the left menu.\n5. Copy your API token.\n\nThe token is project-specific and will only work with templates from that project.": "\nTo obtain your Placid API token:\n\n1. Log in to [placid.app](https://placid.app/login).\n2. Go to Projects overview.\n3. Select your desired project.\n4. Click \"API Tokens\" in the left menu.\n5. Copy your API token.\n\nThe token is project-specific and will only work with templates from that project.",
"Create Image": "Create Image",
"Create PDF": "Create PDF",
"Create Video": "Create Video",
"Convert File to URL": "Convert File to URL",
"Get Image": "Get Image",
"Get PDF": "Get PDF",
"Get Video": "Get Video",
"Custom API Call": "自定义 API 呼叫",
"Generates a dynamic image from a specified template using input data.": "Generates a dynamic image from a specified template using input data.",
"Generates a PDF document from a specified template.": "Generates a PDF document from a specified template.",
"Produces a video based on a template.": "Produces a video based on a template.",
"Convert uploaded file(s) into media URL(s) consumable by Placid templates.": "Convert uploaded file(s) into media URL(s) consumable by Placid templates.",
"Retrieves a generated image by its ID.": "Retrieves a generated image by its ID.",
"Retrieves the generated PDF by its ID.": "Retrieves the generated PDF by its ID.",
"Retrieves the generated video by its ID.": "Retrieves the generated video by its ID.",
"Make a custom API call to a specific endpoint": "将一个自定义 API 调用到一个特定的终点",
"Template": "模板",
"Layers": "Layers",
"Output DPI": "Output DPI",
"Output File Name": "Output File Name",
"Webhook URL": "Webhook URL",
"Create Now": "Create Now",
"Passthrough Text": "Passthrough Text",
"Output FPS": "Output FPS",
"File": "文件",
"Filename": "Filename",
"Image ID": "Image ID",
"PDF ID": "PDF ID",
"Video ID": "Video ID",
"Method": "方法",
"Headers": "信头",
"Query Parameters": "查询参数",
"Body": "正文内容",
"Response is Binary ?": "Response is Binary ?",
"No Error on Failure": "失败时没有错误",
"Timeout (in seconds)": "超时(秒)",
"Select a Placid template for image generation": "Select a Placid template for image generation",
"Optional webhook URL to receive notification when generation is complete.": "Optional webhook URL to receive notification when generation is complete.",
"Whether to create the image immediately (synchronous) or queue it (asynchronous).": "Whether to create the image immediately (synchronous) or queue it (asynchronous).",
"Select a Placid template for pdf generation": "Select a Placid template for pdf generation",
"Select a Placid template for video generation": "Select a Placid template for video generation",
"The file to convert to a URL.": "The file to convert to a URL.",
"Optional custom filename for the uploaded file.": "Optional custom filename for the uploaded file.",
"The ID of the image to retrieve.": "The ID of the image to retrieve.",
"The ID of the PDF to retrieve": "The ID of the PDF to retrieve",
"The ID of the video to retrieve.": "The ID of the video to retrieve.",
"Authorization headers are injected automatically from your connection.": "授权头自动从您的连接中注入。",
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
"72 DPI": "72 DPI",
"150 DPI": "150 DPI",
"300 DPI": "300 DPI",
"96 DPI": "96 DPI",
"GET": "获取",
"POST": "帖子",
"PATCH": "PATCH",
"PUT": "弹出",
"DELETE": "删除",
"HEAD": "黑色"
}

View File

@@ -0,0 +1,79 @@
import {
AuthenticationType,
HttpMethod,
createCustomApiCallAction,
httpClient,
} from '@activepieces/pieces-common';
import { PieceAuth, createPiece } from '@activepieces/pieces-framework';
import { PieceCategory } from '@activepieces/shared';
import { createImage } from './lib/actions/create-image';
import { createPdf } from './lib/actions/create-pdf';
import { createVideo } from './lib/actions/create-video';
import { convertFileToUrl } from './lib/actions/convert-file-to-url';
import { getImage } from './lib/actions/get-image';
import { getPdf } from './lib/actions/get-pdf';
import { getVideo } from './lib/actions/get-video';
import { PLACID_BASE_URL } from './lib/common';
export const placidAuth = PieceAuth.SecretText({
description: `
To obtain your Placid API token:
1. Log in to [placid.app](https://placid.app/login).
2. Go to Projects overview.
3. Select your desired project.
4. Click "API Tokens" in the left menu.
5. Copy your API token.
The token is project-specific and will only work with templates from that project.`,
displayName: 'API Token',
required: true,
validate: async (auth) => {
try {
await httpClient.sendRequest({
url: `${PLACID_BASE_URL}/templates`,
method: HttpMethod.GET,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: auth.auth,
},
});
return {
valid: true,
};
} catch (e) {
return {
valid: false,
error: 'Invalid API token or failed to connect to Placid API',
};
}
},
});
export const placid = createPiece({
displayName: 'Placid',
description:
'Creative automation engine that generates dynamic images, PDFs, and videos from templates and data.',
minimumSupportedRelease: '0.30.0',
logoUrl: 'https://cdn.activepieces.com/pieces/placid.png',
categories: [PieceCategory.CONTENT_AND_FILES, PieceCategory.MARKETING],
auth: placidAuth,
actions: [
createImage,
createPdf,
createVideo,
convertFileToUrl,
getImage,
getPdf,
getVideo,
createCustomApiCallAction({
auth: placidAuth,
baseUrl: () => PLACID_BASE_URL,
authMapping: async (auth) => ({
Authorization: `Bearer ${auth.secret_text}`,
}),
}),
],
triggers: [],
authors: ['MAVRICK-1'],
});

View File

@@ -0,0 +1,68 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { placidAuth } from '../../index';
import { HttpMethod, httpClient, AuthenticationType } from '@activepieces/pieces-common';
import { PLACID_BASE_URL } from '../common';
import FormData from 'form-data';
export const convertFileToUrl = createAction({
auth: placidAuth,
name: 'convert_file_to_url',
displayName: 'Convert File to URL',
description: 'Convert uploaded file(s) into media URL(s) consumable by Placid templates.',
props: {
file: Property.File({
displayName: 'File',
description: 'The file to convert to a URL.',
required: true,
}),
filename: Property.ShortText({
displayName: 'Filename',
description: 'Optional custom filename for the uploaded file.',
required: false,
}),
},
async run(context) {
const { file, filename } = context.propsValue;
const formData = new FormData();
// Convert base64 to buffer for form-data
const buffer = Buffer.from(file.base64, 'base64');
formData.append('file', buffer, {
filename: filename || file.filename,
contentType: file.extension ? `application/${file.extension}` : 'application/octet-stream',
});
try {
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
url: `${PLACID_BASE_URL}/media`,
body: formData,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: context.auth.secret_text,
},
headers: {
...formData.getHeaders(),
},
});
return response.body;
} catch (error: any) {
if (error.response?.status === 404) {
throw new Error(
'File upload not supported. This feature may not be available for demo accounts or may require a paid Placid plan. Please check your account permissions.',
);
}
if (error.response?.status === 413) {
throw new Error('File too large. Please check Placid file size limits.');
}
if (error.response?.status === 403) {
throw new Error(
'File upload access forbidden. This feature may require additional permissions in your Placid account.',
);
}
throw error;
}
},
});

View File

@@ -0,0 +1,81 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { placidAuth } from '../../index';
import { PlacidClient } from '../common/client';
import {
imageTemplateDropdown,
webhookProperty,
createNowProperty,
passthroughProperty,
templateLayersProperty,
} from '../common/props';
import { isNil } from '@activepieces/shared';
import { PlacidCreateImageRequest } from '../common';
export const createImage = createAction({
auth: placidAuth,
name: 'create_image',
displayName: 'Create Image',
description: 'Generates a dynamic image from a specified template using input data.',
props: {
template: imageTemplateDropdown,
layers: templateLayersProperty('image'),
outputDpi: Property.StaticDropdown({
displayName: 'Output DPI',
required: false,
options: {
disabled: false,
options: [
{ label: '72 DPI', value: 72 },
{ label: '150 DPI', value: 150 },
{ label: '300 DPI', value: 300 },
],
},
}),
outputFilename: Property.ShortText({
displayName: 'Output File Name',
required: false,
}),
webhook_success: webhookProperty,
create_now: createNowProperty,
passthrough: passthroughProperty,
},
async run(context) {
const { template, webhook_success, create_now, passthrough, outputDpi, outputFilename } =
context.propsValue;
const layers = context.propsValue.layers ?? {};
const modifiedLayers: Record<string, any> = {};
for (const [key, value] of Object.entries(layers)) {
if (value === '' || isNil(value)) continue;
const [mainKey, subKey] = key.split(':::');
if (!mainKey || !subKey) continue;
if (!modifiedLayers[mainKey]) {
modifiedLayers[mainKey] = {};
}
modifiedLayers[mainKey][subKey] = value;
}
const client = new PlacidClient(context.auth);
const modifications = {
...(outputFilename && { filename: outputFilename }),
...(outputDpi && { dpi: outputDpi }),
};
const request: PlacidCreateImageRequest = {
template_uuid: template,
...(modifiedLayers && { layers: modifiedLayers }),
...(webhook_success && { webhook_success }),
...(create_now !== undefined && { create_now }),
...(passthrough && { passthrough }),
...(Object.keys(modifications).length && { modifications }),
};
return await client.createImage(request);
},
});

View File

@@ -0,0 +1,86 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { placidAuth } from '../../index';
import { PlacidClient } from '../common/client';
import {
pdfTemplateDropdown,
webhookProperty,
createNowProperty,
passthroughProperty,
templateLayersProperty,
} from '../common/props';
import { isNil } from '@activepieces/shared';
import { PlacidCreatePdfRequest } from '../common';
export const createPdf = createAction({
auth: placidAuth,
name: 'create_pdf',
displayName: 'Create PDF',
description: 'Generates a PDF document from a specified template.',
props: {
template: pdfTemplateDropdown,
layers: templateLayersProperty('pdf'),
outputDpi: Property.StaticDropdown({
displayName: 'Output DPI',
required: false,
options: {
disabled: false,
options: [
{ label: '96 DPI', value: 96 },
{ label: '150 DPI', value: 150 },
{ label: '300 DPI', value: 300 },
],
},
}),
outputFilename: Property.ShortText({
displayName: 'Output File Name',
required: false,
}),
webhook_success: webhookProperty,
create_now: createNowProperty,
passthrough: passthroughProperty,
},
async run(context) {
const { template, outputDpi, outputFilename, webhook_success, create_now, passthrough } =
context.propsValue;
const layers = context.propsValue.layers ?? {};
const modifiedLayers: Record<string, any> = {};
for (const [key, value] of Object.entries(layers)) {
if (value === '' || isNil(value)) continue;
const [mainKey, subKey] = key.split(':::');
if (!mainKey || !subKey) continue;
if (!modifiedLayers[mainKey]) {
modifiedLayers[mainKey] = {};
}
modifiedLayers[mainKey][subKey] = value;
}
const client = new PlacidClient(context.auth);
const modifications = {
...(outputFilename && { filename: outputFilename }),
...(outputDpi && { dpi: outputDpi }),
};
// PDFs require a pages array structure
const request: PlacidCreatePdfRequest = {
pages: [
{
template_uuid: template,
...(modifiedLayers && { layers: modifiedLayers }),
},
],
...(Object.keys(modifications).length && { modifications }),
...(webhook_success && { webhook_success }),
...(create_now !== undefined && { create_now }),
...(passthrough && { passthrough }),
};
return await client.createPdf(request);
},
});

View File

@@ -0,0 +1,79 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { placidAuth } from '../../index';
import { PlacidClient } from '../common/client';
import {
videoTemplateDropdown,
webhookProperty,
createNowProperty,
passthroughProperty,
templateLayersProperty,
} from '../common/props';
import { isNil } from '@activepieces/shared';
import { PlacidCreateVideoRequest } from '../common';
export const createVideo = createAction({
auth: placidAuth,
name: 'create_video',
displayName: 'Create Video',
description: 'Produces a video based on a template.',
props: {
template: videoTemplateDropdown,
layers: templateLayersProperty('video'),
outputFps: Property.Number({
displayName: 'Output FPS',
required: false,
defaultValue: 25,
}),
outputFilename: Property.ShortText({
displayName: 'Output File Name',
required: false,
}),
webhook_success: webhookProperty,
create_now: createNowProperty,
passthrough: passthroughProperty,
},
async run(context) {
const { template, outputFps, outputFilename, webhook_success, create_now, passthrough } =
context.propsValue;
const layers = context.propsValue.layers ?? {};
const modifiedLayers: Record<string, any> = {};
for (const [key, value] of Object.entries(layers)) {
if (value === '' || isNil(value)) continue;
const [mainKey, subKey] = key.split(':::');
if (!mainKey || !subKey) continue;
if (!modifiedLayers[mainKey]) {
modifiedLayers[mainKey] = {};
}
modifiedLayers[mainKey][subKey] = value;
}
const client = new PlacidClient(context.auth);
const modifications = {
...(outputFilename && { filename: outputFilename }),
...(outputFps && { fps: outputFps }),
};
// Videos require a clips array structure
const request: PlacidCreateVideoRequest = {
clips: [
{
template_uuid: template,
...(modifiedLayers && { layers: modifiedLayers }),
},
],
...(Object.keys(modifications).length && { modifications }),
...(webhook_success && { webhook_success }),
...(create_now !== undefined && { create_now }),
...(passthrough && { passthrough }),
};
return await client.createVideo(request);
},
});

View File

@@ -0,0 +1,22 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { placidAuth } from '../../index';
import { PlacidClient } from '../common/client';
export const getImage = createAction({
auth: placidAuth,
name: 'get_image',
displayName: 'Get Image',
description: 'Retrieves a generated image by its ID.',
props: {
imageId: Property.ShortText({
displayName: 'Image ID',
description: 'The ID of the image to retrieve.',
required: true,
}),
},
async run(context) {
const { imageId } = context.propsValue;
const client = new PlacidClient(context.auth);
return await client.getImage(imageId);
},
});

View File

@@ -0,0 +1,22 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { placidAuth } from '../../index';
import { PlacidClient } from '../common/client';
export const getPdf = createAction({
auth: placidAuth,
name: 'get_pdf',
displayName: 'Get PDF',
description: 'Retrieves the generated PDF by its ID.',
props: {
pdfId: Property.ShortText({
displayName: 'PDF ID',
description: 'The ID of the PDF to retrieve',
required: true,
}),
},
async run(context) {
const { pdfId } = context.propsValue;
const client = new PlacidClient(context.auth);
return await client.getPdf(pdfId);
},
});

View File

@@ -0,0 +1,22 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { placidAuth } from '../../index';
import { PlacidClient } from '../common/client';
export const getVideo = createAction({
auth: placidAuth,
name: 'get_video',
displayName: 'Get Video',
description: 'Retrieves the generated video by its ID.',
props: {
videoId: Property.ShortText({
displayName: 'Video ID',
description: 'The ID of the video to retrieve.',
required: true,
}),
},
async run(context) {
const { videoId } = context.propsValue;
const client = new PlacidClient(context.auth);
return await client.getVideo(videoId);
},
});

View File

@@ -0,0 +1,266 @@
import { AuthenticationType, HttpMethod, httpClient } from '@activepieces/pieces-common';
import {
PLACID_BASE_URL,
PlacidTemplate,
PlacidImage,
PlacidCreateImageRequest,
PlacidCreatePdfRequest,
PlacidCreateVideoRequest,
} from './index';
import { AppConnectionValueForAuthProperty } from '@activepieces/pieces-framework';
import { placidAuth } from '../..';
export class PlacidClient {
constructor(private apiKey: AppConnectionValueForAuthProperty<typeof placidAuth>) {}
async listTemplates(): Promise<PlacidTemplate[]> {
const templates = [];
let nextUrl: string | undefined = `${PLACID_BASE_URL}/templates`;
do {
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url: nextUrl,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.apiKey.secret_text,
},
});
const { data, links } = response.body as { data: PlacidTemplate[]; links: { next?: string } };
templates.push(...data);
nextUrl = links.next;
} while (nextUrl);
return templates;
}
async getTemplate(templateId: string): Promise<PlacidTemplate> {
const response = await httpClient.sendRequest<PlacidTemplate>({
method: HttpMethod.GET,
url: `${PLACID_BASE_URL}/templates/${templateId}`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.apiKey.secret_text,
},
});
return response.body;
}
async createImage(request: PlacidCreateImageRequest): Promise<PlacidImage> {
const response = await httpClient.sendRequest<PlacidImage>({
method: HttpMethod.POST,
url: `${PLACID_BASE_URL}/images`,
body: request,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.apiKey.secret_text,
},
});
const result = response.body;
// If create_now is true, poll until completion
if (request.create_now && result.status === 'queued') {
return await this.pollForCompletion(result.id, 'image');
}
return result;
}
async getImage(imageId: string): Promise<PlacidImage> {
try {
const response = await httpClient.sendRequest<PlacidImage>({
method: HttpMethod.GET,
url: `${PLACID_BASE_URL}/images/${imageId}`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.apiKey.secret_text,
},
});
return response.body;
} catch (error: any) {
if (error.response?.status === 404) {
throw new Error(
`Image with ID ${imageId} not found. Please verify the image ID exists in your Placid account.`,
);
}
if (error.response?.status === 403) {
throw new Error(
`Access forbidden for image ID ${imageId}. This image may not belong to your account or may have been deleted.`,
);
}
if (error.response?.status === 500) {
throw new Error(
`Server error while retrieving image ID ${imageId}. Please try again later or contact support.`,
);
}
throw error;
}
}
async deleteImage(imageId: string): Promise<void> {
await httpClient.sendRequest({
method: HttpMethod.DELETE,
url: `${PLACID_BASE_URL}/images/${imageId}`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.apiKey.secret_text,
},
});
}
async createPdf(request: PlacidCreatePdfRequest): Promise<PlacidImage> {
const response = await httpClient.sendRequest<PlacidImage>({
method: HttpMethod.POST,
url: `${PLACID_BASE_URL}/pdfs`,
body: request,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.apiKey.secret_text,
},
});
const result = response.body;
// If create_now is true, poll until completion
if (request.create_now && result.status === 'queued') {
return await this.pollForCompletion(result.id, 'pdf');
}
return result;
}
async createVideo(request: PlacidCreateVideoRequest): Promise<PlacidImage> {
const response = await httpClient.sendRequest<PlacidImage>({
method: HttpMethod.POST,
url: `${PLACID_BASE_URL}/videos`,
body: request,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.apiKey.secret_text,
},
});
const result = response.body;
// If create_now is true, poll until completion
if (request.create_now && result.status === 'queued') {
return await this.pollForCompletion(result.id, 'video');
}
return result;
}
async pollForCompletion(id: string, type: 'image' | 'pdf' | 'video'): Promise<PlacidImage> {
const maxAttempts = 30; // 5 minutes max (10 second intervals)
const interval = 10000; // 10 seconds
for (let attempt = 0; attempt < maxAttempts; attempt++) {
try {
// Wait before polling (except first attempt)
if (attempt > 0) {
await new Promise((resolve) => setTimeout(resolve, interval));
}
// Get current status
let result: PlacidImage;
switch (type) {
case 'image':
result = await this.getImage(id);
break;
case 'pdf':
result = await this.getPdf(id);
break;
case 'video':
result = await this.getVideo(id);
break;
}
// Check if completed
if (result.status === 'finished') {
return result;
}
// Check if failed
if (result.status === 'error') {
throw new Error(`${type} generation failed: ${result.error_message || 'Unknown error'}`);
}
// Continue polling if still queued/processing
} catch (error) {
// If it's the last attempt, throw the error
if (attempt === maxAttempts - 1) {
throw new Error(`Polling timeout: ${type} generation took too long`);
}
// Otherwise, continue polling
}
}
throw new Error(`Polling timeout: ${type} generation took too long`);
}
async getPdf(pdfId: string): Promise<PlacidImage> {
try {
const response = await httpClient.sendRequest<PlacidImage>({
method: HttpMethod.GET,
url: `${PLACID_BASE_URL}/pdfs/${pdfId}`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.apiKey.secret_text,
},
});
return response.body;
} catch (error: any) {
if (error.response?.status === 404) {
throw new Error(
`PDF with ID ${pdfId} not found. Please verify the PDF ID exists in your Placid account.`,
);
}
if (error.response?.status === 403) {
throw new Error(
`Access forbidden for PDF ID ${pdfId}. This PDF may not belong to your account or may have been deleted.`,
);
}
if (error.response?.status === 500) {
throw new Error(
`Server error while retrieving PDF ID ${pdfId}. Please try again later or contact support.`,
);
}
throw error;
}
}
async getVideo(videoId: string): Promise<PlacidImage> {
try {
const response = await httpClient.sendRequest<PlacidImage>({
method: HttpMethod.GET,
url: `${PLACID_BASE_URL}/videos/${videoId}`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.apiKey.secret_text,
},
});
return response.body;
} catch (error: any) {
if (error.response?.status === 404) {
throw new Error(
`Video with ID ${videoId} not found. Please verify the video ID exists in your Placid account.`,
);
}
if (error.response?.status === 403) {
throw new Error(
`Access forbidden for video ID ${videoId}. This video may not belong to your account or may have been deleted.`,
);
}
if (error.response?.status === 500) {
throw new Error(
`Server error while retrieving video ID ${videoId}. Please try again later or contact support.`,
);
}
throw error;
}
}
}

View File

@@ -0,0 +1,80 @@
export const PLACID_BASE_URL = 'https://api.placid.app/api/rest';
export interface PlacidTemplate {
uuid: string;
title: string;
thumbnail?: string;
width?: number;
height?: number;
tags?: string[];
custom_data?: any;
collections?: any[];
layers: PlacidLayer[];
}
export interface PlacidLayer {
name: string;
type: 'text' | 'picture' | 'shape' | 'browserframe' | 'subtitle' | 'barcode' | 'rating';
}
export interface PlacidImage {
id: string;
status: 'queued' | 'finished' | 'error';
image_url?: string;
polling_url: string;
error_message?: string;
}
export interface PlacidCreateImageRequest {
template_uuid: string;
layers?: Record<string, any>;
modifications?: {
width?: number;
height?: number;
filename?: string;
dpi?: number;
};
webhook_success?: string;
create_now?: boolean;
passthrough?: Record<string, any> | string;
}
export interface PlacidCreatePdfRequest {
pages: Array<{
template_uuid: string;
layers?: Record<string, any>;
}>;
modifications?: {
filename?: string;
quality?: number;
dpi?: number;
};
webhook_success?: string;
create_now?: boolean;
passthrough?: Record<string, any> | string;
}
export interface PlacidCreateVideoRequest {
clips: Array<{
template_uuid: string;
layers?: Record<string, any>;
}>;
modifications?: {
width?: number;
height?: number;
filename?: string;
canvas_background?: string;
fps?: number;
};
webhook_success?: string;
create_now?: boolean;
passthrough?: Record<string, any> | string;
}
export interface PlacidWebhookPayload {
id: string;
status: string;
image_url?: string;
template_uuid: string;
passthrough?: Record<string, any>;
}

View File

@@ -0,0 +1,232 @@
import { DynamicPropsValue, Property } from '@activepieces/pieces-framework';
import { PlacidClient } from './client';
import { placidAuth } from '../..';
const createTemplateDropdown = (outputType?: 'image' | 'pdf' | 'video') =>
Property.Dropdown({
auth: placidAuth,
displayName: 'Template',
description: `Select a Placid template${outputType ? ` for ${outputType} generation` : ''}`,
required: true,
refreshers: ['auth'],
options: async ({ auth }) => {
if (!auth) {
return {
disabled: true,
options: [],
placeholder: 'Please connect your account first',
};
}
try {
const client = new PlacidClient(auth);
const templates = await client.listTemplates();
if (!templates || templates.length === 0) {
return {
options: [],
placeholder: 'No templates found in your Placid project',
};
}
// Filter templates by tags or naming if outputType is specified
let filteredTemplates = templates;
if (outputType) {
filteredTemplates = templates.filter((template) => {
const title = template.title.toLowerCase();
const tags = template.tags?.map((tag) => tag.toLowerCase()) || [];
// Check if template title or tags indicate it's for this output type
return (
title.includes(outputType) ||
tags.includes(outputType) ||
tags.includes(`${outputType}s`) ||
// For backwards compatibility, if no specific filtering matches, include all
(!title.includes('image') &&
!title.includes('pdf') &&
!title.includes('video') &&
!tags.some((tag) =>
['image', 'pdf', 'video', 'images', 'pdfs', 'videos'].includes(tag),
))
);
});
}
// If filtering resulted in no templates, show all templates with a note
if (outputType && filteredTemplates.length === 0) {
filteredTemplates = templates;
}
return {
options: filteredTemplates.map((template) => {
return {
label: template.title,
value: template.uuid,
};
}),
};
} catch (error) {
return {
disabled: true,
options: [],
placeholder: `Failed to load templates: ${
error instanceof Error ? error.message : 'Unknown error'
}`,
};
}
},
});
// General template dropdown for all types
export const templateDropdown = createTemplateDropdown();
// Specific template dropdowns for each output type
export const imageTemplateDropdown = createTemplateDropdown('image');
export const pdfTemplateDropdown = createTemplateDropdown('pdf');
export const videoTemplateDropdown = createTemplateDropdown('video');
export const modificationsProperty = Property.Object({
displayName: 'Modifications',
description: 'Optional modifications to the generated image (width, height, filename)',
required: false,
});
export const webhookProperty = Property.ShortText({
displayName: 'Webhook URL',
description: 'Optional webhook URL to receive notification when generation is complete.',
required: false,
});
export const createNowProperty = Property.Checkbox({
displayName: 'Create Now',
description: 'Whether to create the image immediately (synchronous) or queue it (asynchronous).',
required: false,
defaultValue: false,
});
export const passthroughProperty = Property.ShortText({
displayName: 'Passthrough Text',
required: false,
});
export const templateLayersProperty = (type: string) =>
Property.DynamicProperties({
auth: placidAuth,
displayName: 'Layers',
refreshers: ['template'],
required: false,
props: async ({ auth, template }) => {
if (!auth || !template) return {};
const props: DynamicPropsValue = {};
const client = new PlacidClient(auth);
const response = await client.getTemplate(template as unknown as string);
for (const layer of response.layers) {
switch (layer.type) {
case 'text': {
props[`${layer.name}:::text`] = Property.ShortText({
displayName: `${layer.name} : Text`,
required: false,
});
props[`${layer.name}:::text_color`] = Property.ShortText({
displayName: `${layer.name} : Text Color`,
required: false,
});
props[`${layer.name}:::font`] = Property.ShortText({
displayName: `${layer.name} : Text Font`,
required: false,
});
props[`${layer.name}:::alt_text_color`] = Property.ShortText({
displayName: `${layer.name} : Alternate Text Color`,
required: false,
});
props[`${layer.name}:::alt_font`] = Property.ShortText({
displayName: `${layer.name} : Alternate Text Font`,
required: false,
});
props[`${layer.name}:::hide`] = Property.Checkbox({
displayName: `${layer.name} : Hide Layer`,
required: false,
});
break;
}
case 'shape': {
props[`${layer.name}:::background_color`] = Property.ShortText({
displayName: `${layer.name} : Background Color`,
required: false,
});
props[`${layer.name}:::hide`] = Property.Checkbox({
displayName: `${layer.name} : Hide Layer`,
required: false,
});
break;
}
case 'picture': {
if (type === 'video') {
props[`${layer.name}:::video`] = Property.ShortText({
displayName: `${layer.name} : Video`,
required: false,
});
}
props[`${layer.name}:::image`] = Property.ShortText({
displayName: `${layer.name} : Image`,
required: false,
});
props[`${layer.name}:::hide`] = Property.Checkbox({
displayName: `${layer.name} : Hide Layer`,
required: false,
});
break;
}
case 'browserframe': {
props[`${layer.name}:::image`] = Property.ShortText({
displayName: `${layer.name} : Image`,
required: false,
});
props[`${layer.name}:::url`] = Property.ShortText({
displayName: `${layer.name} : URL Text`,
required: false,
});
props[`${layer.name}:::hide`] = Property.Checkbox({
displayName: `${layer.name} : Hide Layer`,
required: false,
});
break;
}
case 'barcode': {
props[`${layer.name}:::value`] = Property.ShortText({
displayName: `${layer.name} : Value`,
required: false,
});
props[`${layer.name}:::color`] = Property.ShortText({
displayName: `${layer.name} : Color`,
required: false,
});
props[`${layer.name}:::hide`] = Property.Checkbox({
displayName: `${layer.name} : Hide Layer`,
required: false,
});
break;
}
case 'rating': {
props[`${layer.name}:::value`] = Property.ShortText({
displayName: `${layer.name} : Value`,
required: false,
});
props[`${layer.name}:::hide`] = Property.Checkbox({
displayName: `${layer.name} : Hide Layer`,
required: false,
});
break;
}
default:
break;
}
}
return props;
},
});

View File

@@ -0,0 +1,16 @@
{
"extends": "../../../../tsconfig.base.json",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
}
],
"compilerOptions": {
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
}
}

View File

@@ -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"]
}