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,50 @@
{
"AITable": "AITable",
"Interactive spreadsheets with collaboration": "Interactive spreadsheets with collaboration",
"Token": "Token",
"Instance Url": "Instance Url",
"The token of the AITable account": "The token of the AITable account",
"The url of the AITable instance.": "The url of the AITable instance.",
"\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ": "\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ",
"Create Record": "Create Record",
"Update Record": "Update Record",
"Find Records": "Find Records",
"Custom API Call": "Custom API Call",
"Creates a new record in datasheet.": "Creates a new record in datasheet.",
"Updates an existing record in datasheet.": "Updates an existing record in datasheet.",
"Finds records in datasheet.": "Finds records in datasheet.",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Space": "Space",
"Datasheet": "Datasheet",
"Fields": "Fields",
"Record ID": "Record ID",
"Record IDs": "Record IDs",
"Field Names": "Field Names",
"Max Records": "Max Records",
"Page Size": "Page Size",
"Page Number": "Page Number",
"Filter": "Filter",
"Method": "Method",
"Headers": "Headers",
"Query Parameters": "Query Parameters",
"Body": "Body",
"No Error on Failure": "No Error on Failure",
"Timeout (in seconds)": "Timeout (in seconds)",
"The fields to add to the record.": "The fields to add to the record.",
"The ID of the record to update.": "The ID of the record to update.",
"The IDs of the records to find.": "The IDs of the records to find.",
"The returned record results are limited to the specified fields": "The returned record results are limited to the specified fields",
"How many records are returned in total": "How many records are returned in total",
"How many records are returned per page (max 1000)": "How many records are returned per page (max 1000)",
"Specifies the page number of the page": "Specifies the page number of the page",
"The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)": "The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)",
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD",
"New Record": "New Record",
"Triggers when a new record is added to a datasheet.": "Triggers when a new record is added to a datasheet."
}

View File

@@ -0,0 +1,51 @@
{
"Interactive spreadsheets with collaboration": "Interaktive Tabellenkalkulationen mit Zusammenarbeit",
"Token": "Token",
"Instance Url": "Instanz Url",
"The token of the AITable account": "Das Token des AITable Accounts",
"The url of the AITable instance.": "Die Url der AITable Instanz.",
"\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ": "\n Um Ihr AITable Token zu erhalten, folgen Sie diesen Schritten:\n\n 1. Melden Sie sich bei Ihrem AITable Account an.\n 2. Besuchen Sie https://apitable.com/workbench\n 3. Klicken Sie auf Ihr Profilbild (unten links).\n 4. Klicken Sie auf \"Meine Einstellungen\".\n Klicken Sie auf \"Entwickler\".\n 6. Klicken Sie auf \"Neues Token generieren\".\n 7. Kopieren Sie den Token.\n ",
"Create Record": "Datensatz erstellen",
"Update Record": "Datensatz aktualisieren",
"Find Records": "Datensätze finden",
"Custom API Call": "Eigener API-Aufruf",
"Creates a new record in datasheet.": "Erstellt einen neuen Datensatz im Datenblatt.",
"Updates an existing record in datasheet.": "Aktualisiert einen vorhandenen Datensatz im Datenblatt.",
"Finds records in datasheet.": "Findet Datensätze im Datenblatt.",
"Make a custom API call to a specific endpoint": "Einen benutzerdefinierten API-Aufruf an einen bestimmten Endpunkt machen",
"Space": "Raum",
"Datasheet": "Datasheet",
"Fields": "Felder",
"Record ID": "Datensatz-ID",
"Record IDs": "Datensatz-IDs",
"Field Names": "Feldnamen",
"Max Records": "Max. Datensätze",
"Page Size": "Einträge pro Seite",
"Page Number": "Seitennummer",
"Filter": "Filtern",
"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)",
"The fields to add to the record.": "Die Felder, die zum Datensatz hinzugefügt werden sollen.",
"The ID of the record to update.": "Die ID des zu aktualisierenden Datensatzes.",
"The IDs of the records to find.": "Die IDs der zu findenden Datensätze.",
"The returned record results are limited to the specified fields": "Die zurückgegebenen Datensatzergebnisse sind auf die angegebenen Felder beschränkt",
"How many records are returned in total": "Wie viele Datensätze insgesamt zurückgegeben werden",
"How many records are returned per page (max 1000)": "Wie viele Datensätze pro Seite zurückgegeben werden (max. 1000)",
"Specifies the page number of the page": "Gibt die Seitennummer der Seite an",
"The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)": "Der Filter, der auf die Datensätze angewendet wird (siehe https://help.aitable.ai/docs/guide/manual-formula-field-overview/)",
"Authorization headers are injected automatically from your connection.": "Autorisierungs-Header werden automatisch von Ihrer Verbindung injiziert.",
"Enable for files like PDFs, images, etc..": "Aktivieren für Dateien wie PDFs, Bilder, etc..",
"GET": "ERHALTEN",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "LÖSCHEN",
"HEAD": "HEAD",
"New Record": "Neuer Datensatz",
"Triggers when a new record is added to a datasheet.": "Wird ausgelöst, wenn ein neuer Datensatz zu einem Datenblatt hinzugefügt wird."
}

View File

@@ -0,0 +1,51 @@
{
"Interactive spreadsheets with collaboration": "Hojas de cálculo interactivas con colaboración",
"Token": "Token",
"Instance Url": "Url de Instancia",
"The token of the AITable account": "El token de la cuenta AITable",
"The url of the AITable instance.": "La url de la instancia de AITable.",
"\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ": "\n Para obtener su token AITable, siga estos pasos:\n\n 1. Inicie sesión en su cuenta de AITable.\n 2. Visite https://apitable.com/workbench\n 3. Haz clic en tu foto de perfil (parte inferior izquierda).\n 4. Haz clic en \"Mis Ajustes\".\n 5. Haz clic en \"Desarrollador\".\n 6. Haz clic en \"Generar nuevo token\".\n 7. Copia el token.\n ",
"Create Record": "Crear registro",
"Update Record": "Actualizar registro",
"Find Records": "Buscar registros",
"Custom API Call": "Llamada API personalizada",
"Creates a new record in datasheet.": "Crea un nuevo registro en la hoja de datos.",
"Updates an existing record in datasheet.": "Actualiza un registro existente en la hoja de datos.",
"Finds records in datasheet.": "Encuentra registros en la hoja de datos.",
"Make a custom API call to a specific endpoint": "Hacer una llamada API personalizada a un extremo específico",
"Space": "Espacio",
"Datasheet": "Datasheet",
"Fields": "Campos",
"Record ID": "ID de registro",
"Record IDs": "ID de registro",
"Field Names": "Nombres de campos",
"Max Records": "Grabaciones máximas",
"Page Size": "Tamaño de página",
"Page Number": "Número de página",
"Filter": "Filtro",
"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)",
"The fields to add to the record.": "Los campos a agregar al registro.",
"The ID of the record to update.": "El ID del registro a actualizar.",
"The IDs of the records to find.": "Los IDs de los registros a encontrar.",
"The returned record results are limited to the specified fields": "Los resultados del registro devuelto están limitados a los campos especificados",
"How many records are returned in total": "Cuántos registros se devuelven en total",
"How many records are returned per page (max 1000)": "Cuántos registros se devuelven por página (máx. 1000)",
"Specifies the page number of the page": "Especifica el número de página de la página",
"The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)": "El filtro a aplicar a los registros (ver https://help.aitable.ai/docs/guide/manual-formula-field-overview/)",
"Authorization headers are injected automatically from your connection.": "Las cabeceras de autorización se inyectan automáticamente desde tu conexión.",
"Enable for files like PDFs, images, etc..": "Activar para archivos como PDFs, imágenes, etc.",
"GET": "RECOGER",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "BORRAR",
"HEAD": "LIMPIO",
"New Record": "Nuevo registro",
"Triggers when a new record is added to a datasheet.": "Se activa cuando se añade un nuevo registro a una hoja de datos."
}

View File

@@ -0,0 +1,51 @@
{
"Interactive spreadsheets with collaboration": "Feuilles de calcul interactives avec collaboration",
"Token": "Jeton",
"Instance Url": "Url de l'instance",
"The token of the AITable account": "Le jeton du compte AITable",
"The url of the AITable instance.": "L'url de l'instance AITable.",
"\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ": "\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ",
"Create Record": "Créer un enregistrement",
"Update Record": "Mettre à jour l'enregistrement",
"Find Records": "Trouver des enregistrements",
"Custom API Call": "Appel d'API personnalisé",
"Creates a new record in datasheet.": "Crée un nouvel enregistrement dans la feuille de données.",
"Updates an existing record in datasheet.": "Met à jour un enregistrement existant dans la feuille de données.",
"Finds records in datasheet.": "Trouve les enregistrements dans la feuille de données.",
"Make a custom API call to a specific endpoint": "Passer un appel API personnalisé à un endpoint spécifique",
"Space": "Espace libre",
"Datasheet": "Datasheet",
"Fields": "Champs",
"Record ID": "ID de l'enregistrement",
"Record IDs": "ID d'enregistrement",
"Field Names": "Noms des champs",
"Max Records": "Nombre maximum d'enregistrements",
"Page Size": "Nombre d'élément",
"Page Number": "Numéro de page",
"Filter": "Filtre",
"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'expiration (en secondes)",
"The fields to add to the record.": "Les champs à ajouter à l'enregistrement.",
"The ID of the record to update.": "L'ID de l'enregistrement à mettre à jour.",
"The IDs of the records to find.": "Les identifiants des enregistrements à trouver.",
"The returned record results are limited to the specified fields": "Les résultats de l'enregistrement retourné sont limités aux champs spécifiés",
"How many records are returned in total": "Combien d'enregistrements sont retournés au total",
"How many records are returned per page (max 1000)": "Combien d'enregistrements sont retournés par page (max 1000)",
"Specifies the page number of the page": "Spécifie le numéro de page de la page",
"The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)": "Le filtre à appliquer aux enregistrements (voir https://help.aitable.ai/docs/guide/manual-formula-field-overview/)",
"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 PDF, les images, etc.",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD",
"New Record": "Nouvel enregistrement",
"Triggers when a new record is added to a datasheet.": "Déclenche lorsqu'un nouvel enregistrement est ajouté à une fiche de données."
}

View File

@@ -0,0 +1,50 @@
{
"AITable": "AITable",
"Interactive spreadsheets with collaboration": "Interactive spreadsheets with collaboration",
"Token": "Token",
"Instance Url": "Instance Url",
"The token of the AITable account": "The token of the AITable account",
"The url of the AITable instance.": "The url of the AITable instance.",
"\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ": "\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ",
"Create Record": "Create Record",
"Update Record": "Update Record",
"Find Records": "Find Records",
"Custom API Call": "Custom API Call",
"Creates a new record in datasheet.": "Creates a new record in datasheet.",
"Updates an existing record in datasheet.": "Updates an existing record in datasheet.",
"Finds records in datasheet.": "Finds records in datasheet.",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Space": "Space",
"Datasheet": "Datasheet",
"Fields": "Fields",
"Record ID": "Record ID",
"Record IDs": "Record IDs",
"Field Names": "Field Names",
"Max Records": "Max Records",
"Page Size": "Page Size",
"Page Number": "Page Number",
"Filter": "Filter",
"Method": "Method",
"Headers": "Headers",
"Query Parameters": "Query Parameters",
"Body": "Body",
"No Error on Failure": "No Error on Failure",
"Timeout (in seconds)": "Timeout (in seconds)",
"The fields to add to the record.": "The fields to add to the record.",
"The ID of the record to update.": "The ID of the record to update.",
"The IDs of the records to find.": "The IDs of the records to find.",
"The returned record results are limited to the specified fields": "The returned record results are limited to the specified fields",
"How many records are returned in total": "How many records are returned in total",
"How many records are returned per page (max 1000)": "How many records are returned per page (max 1000)",
"Specifies the page number of the page": "Specifies the page number of the page",
"The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)": "The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)",
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD",
"New Record": "New Record",
"Triggers when a new record is added to a datasheet.": "Triggers when a new record is added to a datasheet."
}

View File

@@ -0,0 +1,50 @@
{
"AITable": "AITable",
"Interactive spreadsheets with collaboration": "Interactive spreadsheets with collaboration",
"Token": "Token",
"Instance Url": "Instance Url",
"The token of the AITable account": "The token of the AITable account",
"The url of the AITable instance.": "The url of the AITable instance.",
"\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ": "\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ",
"Create Record": "Create Record",
"Update Record": "Update Record",
"Find Records": "Find Records",
"Custom API Call": "Custom API Call",
"Creates a new record in datasheet.": "Creates a new record in datasheet.",
"Updates an existing record in datasheet.": "Updates an existing record in datasheet.",
"Finds records in datasheet.": "Finds records in datasheet.",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Space": "Space",
"Datasheet": "Datasheet",
"Fields": "Fields",
"Record ID": "Record ID",
"Record IDs": "Record IDs",
"Field Names": "Field Names",
"Max Records": "Max Records",
"Page Size": "Ukuran Halaman",
"Page Number": "Page Number",
"Filter": "Filter",
"Method": "Method",
"Headers": "Headers",
"Query Parameters": "Query Parameters",
"Body": "Body",
"No Error on Failure": "No Error on Failure",
"Timeout (in seconds)": "Timeout (in seconds)",
"The fields to add to the record.": "The fields to add to the record.",
"The ID of the record to update.": "The ID of the record to update.",
"The IDs of the records to find.": "The IDs of the records to find.",
"The returned record results are limited to the specified fields": "The returned record results are limited to the specified fields",
"How many records are returned in total": "How many records are returned in total",
"How many records are returned per page (max 1000)": "How many records are returned per page (max 1000)",
"Specifies the page number of the page": "Specifies the page number of the page",
"The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)": "The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)",
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD",
"New Record": "New Record",
"Triggers when a new record is added to a datasheet.": "Triggers when a new record is added to a datasheet."
}

View File

@@ -0,0 +1,51 @@
{
"Interactive spreadsheets with collaboration": "コラボレーションによるインタラクティブな表計算ドキュメント",
"Token": "トークン",
"Instance Url": "インスタンスURL",
"The token of the AITable account": "AITableアカウントのトークン",
"The url of the AITable instance.": "AITableインスタンスのURL。",
"\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ": "\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ",
"Create Record": "レコードを作成",
"Update Record": "更新記録",
"Find Records": "レコードを検索",
"Custom API Call": "カスタムAPI通話",
"Creates a new record in datasheet.": "データシートに新しいレコードを作成します。",
"Updates an existing record in datasheet.": "データシートの既存のレコードを更新します。",
"Finds records in datasheet.": "データシートのレコードを検索します。",
"Make a custom API call to a specific endpoint": "特定のエンドポイントへのカスタム API コールを実行します。",
"Space": "スペース",
"Datasheet": "Datasheet",
"Fields": "フィールド",
"Record ID": "レコードID",
"Record IDs": "レコードID",
"Field Names": "フィールド名",
"Max Records": "最大レコード",
"Page Size": "ページサイズ",
"Page Number": "ページ番号",
"Filter": "フィルター",
"Method": "方法",
"Headers": "ヘッダー",
"Query Parameters": "クエリパラメータ",
"Body": "本文",
"Response is Binary ?": "応答はバイナリですか?",
"No Error on Failure": "失敗時にエラーはありません",
"Timeout (in seconds)": "タイムアウト(秒)",
"The fields to add to the record.": "レコードに追加するフィールド。",
"The ID of the record to update.": "更新するレコードのID。",
"The IDs of the records to find.": "検索するレコードのID。",
"The returned record results are limited to the specified fields": "返されたレコードの結果は指定されたフィールドに制限されています",
"How many records are returned in total": "返されるレコードの合計数",
"How many records are returned per page (max 1000)": "1ページあたりのレコードの返却回数最大1000回",
"Specifies the page number of the page": "ページのページ番号を指定します",
"The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)": "レコードに適用するフィルター (https://help.aitable.ai/docs/guide/manual-formula-field-overview/を参照)",
"Authorization headers are injected automatically from your connection.": "認証ヘッダは接続から自動的に注入されます。",
"Enable for files like PDFs, images, etc..": "PDF、画像などのファイルを有効にします。",
"GET": "取得",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "削除",
"HEAD": "頭",
"New Record": "新しいレコード",
"Triggers when a new record is added to a datasheet.": "新しいレコードがデータシートに追加されたときにトリガーされます。"
}

View File

@@ -0,0 +1,51 @@
{
"Interactive spreadsheets with collaboration": "Interactieve spreadsheets met samenwerking",
"Token": "Token",
"Instance Url": "Instantie URL",
"The token of the AITable account": "Het token van het AITable account",
"The url of the AITable instance.": "De URL van de AITable instantie.",
"\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ": "\n Om je AITable token te verkrijgen, volg deze stappen:\n\n 1. Log in op uw AITable account.\n 2. Bezoek https://apitable.com/workbench\n 3. Klik op je profielfoto (Bottom links).\n 4. Klik op \"Mijn instellingen\".\n 5. Klik op \"Ontwikkelaar\".\n 6. Klik op \"Genereer nieuwe token\".\n 7. Kopieer de token.\n ",
"Create Record": "Record Maken",
"Update Record": "Update Record",
"Find Records": "Records zoeken",
"Custom API Call": "Custom API Call",
"Creates a new record in datasheet.": "Maakt een nieuw record in datasheet.",
"Updates an existing record in datasheet.": "Werkt een bestaand record bij in datasheet.",
"Finds records in datasheet.": "Gevonden records in datasheet.",
"Make a custom API call to a specific endpoint": "Maak een aangepaste API call naar een specifiek eindpunt",
"Space": "Spatiebalk",
"Datasheet": "Datasheet",
"Fields": "Velden",
"Record ID": "Record ID",
"Record IDs": "ID's opnemen",
"Field Names": "Veldnamen",
"Max Records": "Max Records",
"Page Size": "Paginagrootte",
"Page Number": "Pagina Nummer",
"Filter": "Filteren",
"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)",
"The fields to add to the record.": "De velden om toe te voegen aan het record.",
"The ID of the record to update.": "Het ID van het te updaten record",
"The IDs of the records to find.": "De ID's van de records om te vinden.",
"The returned record results are limited to the specified fields": "De geretourneerde record resultaten zijn beperkt tot de opgegeven velden",
"How many records are returned in total": "Hoeveel records worden geretourneerd in totaal",
"How many records are returned per page (max 1000)": "Hoeveel records worden geretourneerd per pagina (max 1000)",
"Specifies the page number of the page": "Specificeert het paginanummer van de pagina",
"The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)": "Het filter om toe te passen op de records (zie https://help.aitable.ai/docs/guide/manual-forma-field-overview/)",
"Authorization headers are injected automatically from your connection.": "Autorisatie headers worden automatisch geïnjecteerd vanuit uw verbinding.",
"Enable for files like PDFs, images, etc..": "Inschakelen voor bestanden zoals PDF's, afbeeldingen etc..",
"GET": "KRIJG",
"POST": "POSTE",
"PATCH": "BEKIJK",
"PUT": "PUT",
"DELETE": "VERWIJDEREN",
"HEAD": "HOOFD",
"New Record": "Nieuwe Record",
"Triggers when a new record is added to a datasheet.": "Triggert wanneer een nieuw record wordt toegevoegd aan een datasheet."
}

View File

@@ -0,0 +1,51 @@
{
"Interactive spreadsheets with collaboration": "Planilhas interativas com colaboração",
"Token": "Identificador",
"Instance Url": "URL da Instância",
"The token of the AITable account": "O token da conta AITable",
"The url of the AITable instance.": "A url da instância AITable.",
"\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ": "Para obter seu \"AiTable Token\", siga os seguintes passos:\n\n1. Entre na sua conta \"AiTable\".\n2. Acesse https://apitable.com/workbench\n3. Clique na sua foto de perfil (com o botão esquerdo)\n4. Vá para \"Minhas configurações\"\n5. Clique em \"Desenvolvedor\"\n6. Clique em \"Gerar novo Token\".\n7. Copie o Token gerado.",
"Create Record": "Criar Registro",
"Update Record": "Atualizar Registro",
"Find Records": "Encontrar registros",
"Custom API Call": "Chamada de API personalizada",
"Creates a new record in datasheet.": "Cria um novo registro na folha de dados.",
"Updates an existing record in datasheet.": "Atualiza um registro existente na ficha técnica.",
"Finds records in datasheet.": "Encontrar registros na ficha técnica.",
"Make a custom API call to a specific endpoint": "Faça uma chamada de API personalizada para um ponto de extremidade específico",
"Space": "Sala",
"Datasheet": "Datasheet",
"Fields": "campos",
"Record ID": "ID do Registro",
"Record IDs": "IDs de Registro",
"Field Names": "Nomes Campos",
"Max Records": "Registros Máx.",
"Page Size": "Tamanho da página",
"Page Number": "Número da página",
"Filter": "filtro",
"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)",
"The fields to add to the record.": "Os campos para adicionar ao registro.",
"The ID of the record to update.": "A ID do registro a ser atualizada.",
"The IDs of the records to find.": "Os IDs dos registros a serem encontrados.",
"The returned record results are limited to the specified fields": "Os resultados dos registros retornados são limitados aos campos especificados",
"How many records are returned in total": "Quantos registros são devolvidos no total",
"How many records are returned per page (max 1000)": "Quantos registros são devolvidos por página (máx. 1000)",
"Specifies the page number of the page": "Especifica o número da página da página",
"The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)": "O filtro a ser aplicado aos registros (consulte https://help.aitable.ai/docs/guide/manual-formula-field-overview/)",
"Authorization headers are injected automatically from your connection.": "Os cabeçalhos de autorização são inseridos automaticamente a partir da sua conexão.",
"Enable for files like PDFs, images, etc..": "Habilitar para arquivos como PDFs, imagens, etc..",
"GET": "OBTER",
"POST": "POSTAR",
"PATCH": "COMPRAR",
"PUT": "COLOCAR",
"DELETE": "EXCLUIR",
"HEAD": "CABEÇA",
"New Record": "Novo Registro",
"Triggers when a new record is added to a datasheet.": "Aciona quando um novo registro é adicionado a uma ficha técnica."
}

View File

@@ -0,0 +1,50 @@
{
"AITable": "Доступно",
"Interactive spreadsheets with collaboration": "Интерактивные электронные таблицы с сотрудничеством",
"Token": "Токен",
"Instance Url": "Ссылка экземпляра",
"The token of the AITable account": "Токен учетной записи AITable",
"The url of the AITable instance.": "Адрес url экземпляра AITable .",
"\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ": "\n Для получения токена AITable выполните следующие действия:\n\n 1. Войдите в свою учетную запись AITable.\n 2. Посетите https://apitable.com/workbench\n 3. Нажмите на изображение вашего профиля (слева вниз).\n 4. Нажмите на \"Мои настройки\".\n 5. Нажмите на \"Разработчик\".\n 6. Нажмите на \"Создать новый токен\".\n 7. Скопируйте токен.\n ",
"Create Record": "Создать запись",
"Update Record": "Обновить запись",
"Find Records": "Найти записи",
"Custom API Call": "Пользовательский вызов API",
"Creates a new record in datasheet.": "Создает новую запись в datasheet.",
"Updates an existing record in datasheet.": "Обновляет существующую запись в datasheet.",
"Finds records in datasheet.": "Ищет записи в хранилище.",
"Make a custom API call to a specific endpoint": "Сделать пользовательский API вызов к определенной конечной точке",
"Space": "Пространство",
"Datasheet": "Datasheet",
"Fields": "Поля",
"Record ID": "ID записи",
"Record IDs": "ID записи",
"Field Names": "Имена полей",
"Max Records": "Макс. записей",
"Page Size": "Размер страницы",
"Page Number": "Номер страницы",
"Filter": "Фильтр",
"Method": "Метод",
"Headers": "Заголовки",
"Query Parameters": "Параметры запроса",
"Body": "Тело",
"No Error on Failure": "Нет ошибок при ошибке",
"Timeout (in seconds)": "Таймаут (в секундах)",
"The fields to add to the record.": "Поля для добавления в запись.",
"The ID of the record to update.": "ID записи для обновления.",
"The IDs of the records to find.": "Идентификаторы записей, которые нужно найти.",
"The returned record results are limited to the specified fields": "Результаты возвращенной записи ограничены указанными полями",
"How many records are returned in total": "Сколько записей возвращено в общей сложности",
"How many records are returned per page (max 1000)": "Сколько записей возвращено на страницу (не более 1000)",
"Specifies the page number of the page": "Номер страницы",
"The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)": "Фильтр для применения к записям (см. https://help.aitable.ai/docs/guide/manual-formula-field-overview/)",
"Authorization headers are injected automatically from your connection.": "Заголовки авторизации включаются автоматически из вашего соединения.",
"GET": "ПОЛУЧИТЬ",
"POST": "ПОСТ",
"PATCH": "ПАТЧ",
"PUT": "ПОКУПИТЬ",
"DELETE": "УДАЛИТЬ",
"HEAD": "HEAD",
"New Record": "Новая запись",
"Triggers when a new record is added to a datasheet.": "Включает при добавлении новой записи в таблицу."
}

View File

@@ -0,0 +1,51 @@
{
"Interactive spreadsheets with collaboration": "Interactive spreadsheets with collaboration",
"Token": "Token",
"Instance Url": "Instance Url",
"The token of the AITable account": "The token of the AITable account",
"The url of the AITable instance.": "The url of the AITable instance.",
"\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ": "\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ",
"Create Record": "Create Record",
"Update Record": "Update Record",
"Find Records": "Find Records",
"Custom API Call": "Custom API Call",
"Creates a new record in datasheet.": "Creates a new record in datasheet.",
"Updates an existing record in datasheet.": "Updates an existing record in datasheet.",
"Finds records in datasheet.": "Finds records in datasheet.",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Space": "Space",
"Datasheet": "Datasheet",
"Fields": "Fields",
"Record ID": "Record ID",
"Record IDs": "Record IDs",
"Field Names": "Field Names",
"Max Records": "Max Records",
"Page Size": "Page Size",
"Page Number": "Page Number",
"Filter": "Filter",
"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)",
"The fields to add to the record.": "The fields to add to the record.",
"The ID of the record to update.": "The ID of the record to update.",
"The IDs of the records to find.": "The IDs of the records to find.",
"The returned record results are limited to the specified fields": "The returned record results are limited to the specified fields",
"How many records are returned in total": "How many records are returned in total",
"How many records are returned per page (max 1000)": "How many records are returned per page (max 1000)",
"Specifies the page number of the page": "Specifies the page number of the page",
"The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)": "The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)",
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD",
"New Record": "New Record",
"Triggers when a new record is added to a datasheet.": "Triggers when a new record is added to a datasheet."
}

View File

@@ -0,0 +1,50 @@
{
"AITable": "AITable",
"Interactive spreadsheets with collaboration": "Interactive spreadsheets with collaboration",
"Token": "Token",
"Instance Url": "Instance Url",
"The token of the AITable account": "The token of the AITable account",
"The url of the AITable instance.": "The url of the AITable instance.",
"\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ": "\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ",
"Create Record": "Create Record",
"Update Record": "Update Record",
"Find Records": "Find Records",
"Custom API Call": "Custom API Call",
"Creates a new record in datasheet.": "Creates a new record in datasheet.",
"Updates an existing record in datasheet.": "Updates an existing record in datasheet.",
"Finds records in datasheet.": "Finds records in datasheet.",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Space": "Space",
"Datasheet": "Datasheet",
"Fields": "Fields",
"Record ID": "Record ID",
"Record IDs": "Record IDs",
"Field Names": "Field Names",
"Max Records": "Max Records",
"Page Size": "Phân trang",
"Page Number": "Page Number",
"Filter": "Filter",
"Method": "Method",
"Headers": "Headers",
"Query Parameters": "Query Parameters",
"Body": "Body",
"No Error on Failure": "No Error on Failure",
"Timeout (in seconds)": "Timeout (in seconds)",
"The fields to add to the record.": "The fields to add to the record.",
"The ID of the record to update.": "The ID of the record to update.",
"The IDs of the records to find.": "The IDs of the records to find.",
"The returned record results are limited to the specified fields": "The returned record results are limited to the specified fields",
"How many records are returned in total": "How many records are returned in total",
"How many records are returned per page (max 1000)": "How many records are returned per page (max 1000)",
"Specifies the page number of the page": "Specifies the page number of the page",
"The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)": "The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)",
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD",
"New Record": "New Record",
"Triggers when a new record is added to a datasheet.": "Triggers when a new record is added to a datasheet."
}

View File

@@ -0,0 +1,51 @@
{
"Interactive spreadsheets with collaboration": "Interactive spreadsheets with collaboration",
"Token": "Token",
"Instance Url": "Instance Url",
"The token of the AITable account": "The token of the AITable account",
"The url of the AITable instance.": "The url of the AITable instance.",
"\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ": "\n To obtain your AITable token, follow these steps:\n\n 1. Log in to your AITable account.\n 2. Visit https://apitable.com/workbench\n 3. Click on your profile picture (Bottom left).\n 4. Click on \"My Settings\".\n 5. Click on \"Developer\".\n 6. Click on \"Generate new token\".\n 7. Copy the token.\n ",
"Create Record": "Create Record",
"Update Record": "Update Record",
"Find Records": "Find Records",
"Custom API Call": "自定义 API 呼叫",
"Creates a new record in datasheet.": "Creates a new record in datasheet.",
"Updates an existing record in datasheet.": "Updates an existing record in datasheet.",
"Finds records in datasheet.": "Finds records in datasheet.",
"Make a custom API call to a specific endpoint": "将一个自定义 API 调用到一个特定的终点",
"Space": "Space",
"Datasheet": "Datasheet",
"Fields": "Fields",
"Record ID": "Record ID",
"Record IDs": "Record IDs",
"Field Names": "Field Names",
"Max Records": "Max Records",
"Page Size": "Page Size",
"Page Number": "Page Number",
"Filter": "Filter",
"Method": "方法",
"Headers": "信头",
"Query Parameters": "查询参数",
"Body": "正文内容",
"Response is Binary ?": "Response is Binary ?",
"No Error on Failure": "失败时没有错误",
"Timeout (in seconds)": "超时(秒)",
"The fields to add to the record.": "The fields to add to the record.",
"The ID of the record to update.": "The ID of the record to update.",
"The IDs of the records to find.": "The IDs of the records to find.",
"The returned record results are limited to the specified fields": "The returned record results are limited to the specified fields",
"How many records are returned in total": "How many records are returned in total",
"How many records are returned per page (max 1000)": "How many records are returned per page (max 1000)",
"Specifies the page number of the page": "Specifies the page number of the page",
"The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)": "The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)",
"Authorization headers are injected automatically from your connection.": "授权头自动从您的连接中注入。",
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
"GET": "获取",
"POST": "帖子",
"PATCH": "PATCH",
"PUT": "弹出",
"DELETE": "删除",
"HEAD": "黑色",
"New Record": "New Record",
"Triggers when a new record is added to a datasheet.": "Triggers when a new record is added to a datasheet."
}

View File

@@ -0,0 +1,88 @@
import { createCustomApiCallAction } from '@activepieces/pieces-common';
import {
createPiece,
PieceAuth,
PiecePropValueSchema,
Property,
} from '@activepieces/pieces-framework';
import { PieceCategory } from '@activepieces/shared';
import { createRecordAction } from './lib/actions/create-record';
import { findRecordAction } from './lib/actions/find-record';
import { updateRecordAction } from './lib/actions/update-record';
import { newRecordTrigger } from './lib/triggers/new-record';
import { makeClient } from './lib/common';
export const APITableAuth = PieceAuth.CustomAuth({
required: true,
description: `
To obtain your AITable token, follow these steps:
1. Log in to your AITable account.
2. Visit https://apitable.com/workbench
3. Click on your profile picture (Bottom left).
4. Click on "My Settings".
5. Click on "Developer".
6. Click on "Generate new token".
7. Copy the token.
`,
props: {
token: PieceAuth.SecretText({
displayName: 'Token',
description: 'The token of the AITable account',
required: true,
}),
apiTableUrl: Property.ShortText({
displayName: 'Instance Url',
description: 'The url of the AITable instance.',
required: true,
defaultValue: 'https://aitable.ai',
}),
},
validate: async ({ auth }) => {
try {
const client = makeClient(
auth as PiecePropValueSchema<typeof APITableAuth>
);
await client.listSpaces();
return {
valid: true,
};
} catch (e) {
return {
valid: false,
error: 'Invalid Token or Instance URL.',
};
}
},
});
export const apitable = createPiece({
displayName: 'AITable',
auth: APITableAuth,
description: `Interactive spreadsheets with collaboration`,
minimumSupportedRelease: '0.30.0',
logoUrl: 'https://cdn.activepieces.com/pieces/apitable.png',
categories: [PieceCategory.PRODUCTIVITY],
authors: [
'alerdenisov',
'Abdallah-Alwarawreh',
'kishanprmr',
'MoShizzle',
'abuaboud',
],
actions: [
createRecordAction,
updateRecordAction,
findRecordAction,
createCustomApiCallAction({
baseUrl: (auth) => {
return (auth?.props.apiTableUrl ?? '');
},
auth: APITableAuth,
authMapping: async (auth) => ({
Authorization: `Bearer ${(auth?.props.token ?? '')}`,
}),
}),
],
triggers: [newRecordTrigger],
});

View File

@@ -0,0 +1,58 @@
import {
DynamicPropsValue,
PiecePropValueSchema,
createAction,
} from '@activepieces/pieces-framework';
import { APITableCommon, createNewFields, makeClient } from '../common';
import { APITableAuth } from '../../index';
export const createRecordAction = createAction({
auth: APITableAuth,
name: 'apitable_create_record',
displayName: 'Create Record',
description: 'Creates a new record in datasheet.',
props: {
space_id: APITableCommon.space_id,
datasheet_id: APITableCommon.datasheet_id,
fields: APITableCommon.fields,
},
async run(context) {
const auth = context.auth;
const datasheetId = context.propsValue.datasheet_id;
const dynamicFields: DynamicPropsValue = context.propsValue.fields;
const fields: {
[n: string]: string;
} = {};
const props = Object.entries(dynamicFields);
for (const [propertyKey, propertyValue] of props) {
if (propertyValue !== undefined && propertyValue !== '') {
fields[propertyKey] = propertyValue;
}
}
const newFields: Record<string, unknown> = await createNewFields(
auth.props,
datasheetId,
fields
);
const client = makeClient(
context.auth.props
);
const response: any = await client.createRecord(datasheetId as string, {
records: [
{
fields: {
...newFields,
},
},
],
});
if (!response.success) {
throw new Error(JSON.stringify(response, undefined, 2));
}
return response;
},
});

View File

@@ -0,0 +1,80 @@
import {
PiecePropValueSchema,
Property,
createAction,
} from '@activepieces/pieces-framework';
import { APITableCommon, makeClient } from '../common';
import { APITableAuth } from '../../index';
import { prepareQuery } from '../common/client';
export const findRecordAction = createAction({
auth: APITableAuth,
name: 'apitable_find_record',
displayName: 'Find Records',
description: 'Finds records in datasheet.',
props: {
space_id: APITableCommon.space_id,
datasheet_id: APITableCommon.datasheet_id,
recordIds: Property.Array({
displayName: 'Record IDs',
description: 'The IDs of the records to find.',
required: false,
}),
fieldNames: Property.Array({
displayName: 'Field Names',
description:
'The returned record results are limited to the specified fields',
required: false,
}),
maxRecords: Property.Number({
displayName: 'Max Records',
description: 'How many records are returned in total',
required: false,
}),
pageSize: Property.Number({
displayName: 'Page Size',
description: 'How many records are returned per page (max 1000)',
required: false,
}),
pageNum: Property.Number({
displayName: 'Page Number',
description: 'Specifies the page number of the page',
required: false,
}),
filter: Property.LongText({
displayName: 'Filter',
description:
'The filter to apply to the records (see https://help.aitable.ai/docs/guide/manual-formula-field-overview/)',
required: false,
}),
},
async run(context) {
const datasheetId = context.propsValue.datasheet_id;
const recordIds = context.propsValue.recordIds ?? []
const fieldNames = context.propsValue.fieldNames ?? []
const maxRecords = context.propsValue.maxRecords;
const pageSize = context.propsValue.pageSize ?? 100;
const pageNum = context.propsValue.pageNum ?? 1;
const filter = context.propsValue.filter;
const client = makeClient(
context.auth.props
);
const response: any = await client.listRecords(
datasheetId as string,
prepareQuery({
pageSize: pageSize,
pageNum: pageNum,
recordIds: recordIds.join(','),
fieldNames: fieldNames.join(','),
maxRecords: maxRecords,
filterByFormula: filter,
})
);
if (!response.success) {
throw new Error(JSON.stringify(response, undefined, 2));
}
return response;
},
});

View File

@@ -0,0 +1,66 @@
import {
DynamicPropsValue,
PiecePropValueSchema,
Property,
createAction,
} from '@activepieces/pieces-framework';
import { APITableCommon, createNewFields, makeClient } from '../common';
import { APITableAuth } from '../../index';
export const updateRecordAction = createAction({
auth: APITableAuth,
name: 'apitable_update_record',
displayName: 'Update Record',
description: 'Updates an existing record in datasheet.',
props: {
space_id: APITableCommon.space_id,
datasheet_id: APITableCommon.datasheet_id,
recordId: Property.ShortText({
displayName: 'Record ID',
description: 'The ID of the record to update.',
required: true,
}),
fields: APITableCommon.fields,
},
async run(context) {
const auth = context.auth;
const datasheetId = context.propsValue.datasheet_id;
const recordId = context.propsValue.recordId;
const dynamicFields: DynamicPropsValue = context.propsValue.fields;
const fields: {
[n: string]: string;
} = {};
const props = Object.entries(dynamicFields);
for (const [propertyKey, propertyValue] of props) {
if (propertyValue !== undefined && propertyValue !== '') {
fields[propertyKey] = propertyValue;
}
}
const newFields: Record<string, unknown> = await createNewFields(
auth.props,
datasheetId,
fields,
);
const client = makeClient(context.auth.props);
const response: any = await client.updateRecord(datasheetId, {
records: [
{
recordId: recordId,
fields: {
...newFields,
},
},
],
});
if (!response.success) {
throw new Error(JSON.stringify(response, undefined, 2));
}
return response;
},
});

View File

@@ -0,0 +1,129 @@
import {
HttpMessageBody,
HttpMethod,
QueryParams,
AuthenticationType,
httpClient,
} from '@activepieces/pieces-common';
import { AITableFieldType } from './constants';
function emptyValueFilter(
accessor: (key: string) => any
): (key: string) => boolean {
return (key: string) => {
const val = accessor(key);
return (
val !== null &&
val !== undefined &&
(typeof val != 'string' || val.length > 0)
);
};
}
export function prepareQuery(request?: Record<string, any>): QueryParams {
const params: QueryParams = {};
if (!request) return params;
Object.keys(request)
.filter(emptyValueFilter((k) => request[k]))
.forEach((k: string) => {
params[k] = (request as Record<string, any>)[k].toString();
});
return params;
}
export class AITableClient {
constructor(private apiTableUrl: string, private token: string) {}
async makeRequest<T extends HttpMessageBody>(
method: HttpMethod,
resourceUri: string,
query?: QueryParams,
body: any | undefined = undefined
): Promise<T> {
const baseUrl = this.apiTableUrl.replace(/\/$/, '');
const res = await httpClient.sendRequest<T>({
method: method,
url: `${baseUrl}/fusion` + resourceUri,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.token,
},
queryParams: query,
body: body,
});
return res.body;
}
async listSpaces() {
return await this.makeRequest<{
data: {
spaces: {
id: string;
name: string;
}[];
};
}>(HttpMethod.GET, '/v1/spaces');
}
async listDatasheets(space_id: string) {
return await this.makeRequest<{
data: {
nodes: {
id: string;
name: string;
}[];
};
}>(HttpMethod.GET, `/v2/spaces/${space_id}/nodes`, { type: 'Datasheet' });
}
async getDatasheetFields(datasheet_id: string) {
return await this.makeRequest<{
data: {
fields: {
id: string;
name: string;
type: AITableFieldType;
desc: string;
property?: {
format?: string;
defaultValue?: string;
options?: {
name: string;
id?: string;
}[];
};
}[];
};
}>(HttpMethod.GET, `/v1/datasheets/${datasheet_id}/fields`);
}
async createRecord(datasheet_id: string, request: object) {
return await this.makeRequest(
HttpMethod.POST,
`/v1/datasheets/${datasheet_id}/records`,
undefined,
request
);
}
async updateRecord(datasheet_id: string, request: object) {
return await this.makeRequest(
HttpMethod.PATCH,
`/v1/datasheets/${datasheet_id}/records`,
undefined,
request
);
}
async listRecords(datasheet_id: string, query?: QueryParams) {
return await this.makeRequest<{
data: {
total: number;
records: {
recordId: string;
createdAt: number;
updatedAt: number;
fields: Record<string, unknown>;
}[];
};
}>(HttpMethod.GET, `/v1/datasheets/${datasheet_id}/records`, query);
}
}

View File

@@ -0,0 +1,34 @@
export const enum AITableFieldType {
SINGLE_TEXT = 'SingleText',
ONE_WAY_LINK = 'OneWayLink',
TWO_WAY_LINK = 'TwoWayLink',
MAGIC_LOOKUP = 'MagicLookUp',
SINGLE_SELECT = 'SingleSelect',
MEMBER = 'Member',
DATETIME = 'DateTime',
NUMBER = 'Number',
FORMULA = 'Formula',
TEXT = 'Text',
MULTI_SELECT = 'MultiSelect',
CURRENCY = 'Currency',
PERCENT = 'Percent',
RATING = 'Rating',
CHECKBOX = 'Checkbox',
URL = 'URL',
PHONE = 'Phone',
EMAIL = 'Email',
AUTONUMBER = 'AutoNumber',
CREATED_BY = 'CreatedBy',
LAST_MODIFIED_BY = 'LastModifiedBy',
CASCADER = 'Cascader',
CREATED_TIME = 'CreatedTime',
LAST_MODIEFIED_TIME = 'LastModifiedTime',
ATTACHMENT = 'Attachment',
}
export const AITableNumericFieldTypes = [
AITableFieldType.NUMBER,
AITableFieldType.RATING,
AITableFieldType.CURRENCY,
AITableFieldType.PERCENT,
];

View File

@@ -0,0 +1,254 @@
import { DynamicPropsValue, PiecePropValueSchema, Property } from '@activepieces/pieces-framework';
import { APITableAuth } from '../../';
import { AITableClient } from './client';
import { AITableFieldType, AITableNumericFieldTypes } from './constants';
export function makeClient(auth: PiecePropValueSchema<typeof APITableAuth>) {
const client = new AITableClient(auth.apiTableUrl, auth.token);
return client;
}
export const APITableCommon = {
space_id: Property.Dropdown({
auth: APITableAuth,
displayName: 'Space',
required: true,
refreshers: [],
options: async ({ auth }) => {
if (!auth) {
return {
disabled: true,
options: [],
placeholder: 'Connect your account first',
};
}
const client = makeClient(auth.props);
const res = await client.listSpaces();
return {
disabled: false,
options: res.data.spaces.map((space) => {
return {
label: space.name,
value: space.id,
};
}),
};
},
}),
datasheet_id: Property.Dropdown({
auth: APITableAuth,
displayName: 'Datasheet',
required: true,
refreshers: ['space_id'],
options: async ({ auth, space_id }) => {
if (!auth || !space_id) {
return {
disabled: true,
options: [],
placeholder: 'Connect your account first and select space.',
};
}
const client = makeClient(auth.props);
const res = await client.listDatasheets(space_id as string);
return {
disabled: false,
options: res.data.nodes.map((datasheet) => {
return {
label: datasheet.name,
value: datasheet.id,
};
}),
};
},
}),
fields: Property.DynamicProperties({
auth: APITableAuth,
displayName: 'Fields',
description: 'The fields to add to the record.',
required: true,
refreshers: ['auth', 'datasheet_id'],
props: async ({ auth, datasheet_id }) => {
if(!auth)
{
return {}
}
const client = makeClient(auth.props);
const res = await client.getDatasheetFields(datasheet_id as unknown as string);
const props: DynamicPropsValue = {};
for (const field of res.data.fields) {
if (
![
AITableFieldType.ATTACHMENT,
AITableFieldType.AUTONUMBER,
AITableFieldType.CASCADER,
AITableFieldType.CREATED_BY,
AITableFieldType.CREATED_TIME,
AITableFieldType.FORMULA,
AITableFieldType.LAST_MODIEFIED_TIME,
AITableFieldType.LAST_MODIFIED_BY,
AITableFieldType.MAGIC_LOOKUP,
AITableFieldType.ONE_WAY_LINK,
].includes(field.type)
) {
switch (field.type) {
case AITableFieldType.CHECKBOX:
props[field.name] = Property.Checkbox({
displayName: field.name,
required: false,
});
break;
case AITableFieldType.CURRENCY:
case AITableFieldType.NUMBER:
case AITableFieldType.PERCENT:
case AITableFieldType.RATING:
props[field.name] = Property.Number({
displayName: field.name,
required: false,
});
break;
case AITableFieldType.DATETIME:
props[field.name] = Property.DateTime({
displayName: field.name,
required: false,
});
break;
case AITableFieldType.EMAIL:
case AITableFieldType.PHONE:
case AITableFieldType.SINGLE_TEXT:
case AITableFieldType.URL:
props[field.name] = Property.ShortText({
displayName: field.name,
required: false,
});
break;
case AITableFieldType.TEXT:
props[field.name] = Property.LongText({
displayName: field.name,
required: false,
});
break;
case AITableFieldType.MULTI_SELECT:
props[field.name] = Property.StaticMultiSelectDropdown({
displayName: field.name,
required: false,
options: {
options:
field.property?.options?.map((option) => {
return {
label: option.name,
value: option.name,
};
}) || [],
},
});
break;
case AITableFieldType.SINGLE_SELECT:
props[field.name] = Property.StaticDropdown({
displayName: field.name,
required: false,
options: {
options:
field.property?.options?.map((option) => {
return {
label: option.name,
value: option.name,
};
}) || [],
},
});
break;
case AITableFieldType.MEMBER:
props[field.name] = Property.StaticMultiSelectDropdown({
displayName: field.name,
required: false,
options: {
options:
field.property?.options?.map((option) => {
return {
label: option.name,
value: option.id,
};
}) || [],
},
});
break;
case AITableFieldType.TWO_WAY_LINK:
props[field.name] = Property.Array({
displayName: field.name,
required: false,
});
break;
}
}
}
return props;
},
}),
};
export async function createNewFields(
auth: PiecePropValueSchema<typeof APITableAuth>,
datasheet_id: string,
fields: Record<string, unknown>,
) {
if (!auth) return fields;
if (!datasheet_id) return fields;
const newFields: Record<string, unknown> = {};
const client = makeClient(auth as PiecePropValueSchema<typeof APITableAuth>);
const res = await client.getDatasheetFields(datasheet_id as string);
for(const field of res.data.fields) {
if (
[
AITableFieldType.ATTACHMENT,
AITableFieldType.AUTONUMBER,
AITableFieldType.CASCADER,
AITableFieldType.CREATED_BY,
AITableFieldType.CREATED_TIME,
AITableFieldType.FORMULA,
AITableFieldType.LAST_MODIEFIED_TIME,
AITableFieldType.LAST_MODIFIED_BY,
AITableFieldType.MAGIC_LOOKUP,
AITableFieldType.ONE_WAY_LINK,
].includes(field.type) || !(field.name in fields)
) {
continue; // Skip irrelevant or missing fields
}
const key = field.name;
// Handle numeric fields
if(AITableNumericFieldTypes.includes(field.type))
{
newFields[key] = Number(fields[key]);
}
// Handle member fields
else if(field.type === AITableFieldType.MEMBER)
{
newFields[key] = field.property?.options?.filter(
(member) => member.id === `${fields[key]}`,
);
}
// Handle multi-select and two-way-link fields
else if([AITableFieldType.MULTI_SELECT, AITableFieldType.TWO_WAY_LINK].includes(field.type))
{
if(!Array.isArray(fields[key]) || (fields[key] as Array<unknown>).length === 0)
{
continue; // Skip empty fields
}
newFields[key] = fields[key];
}
// Handle all other fields
else
{
newFields[key] = fields[key];
}
}
return newFields;
}

View File

@@ -0,0 +1,91 @@
import { APITableAuth } from '../../index';
import {
AppConnectionValueForAuthProperty,
TriggerStrategy,
createTrigger,
} from '@activepieces/pieces-framework';
import {
DedupeStrategy,
Polling,
pollingHelper,
} from '@activepieces/pieces-common';
import { APITableCommon, makeClient } from '../common';
import dayjs from 'dayjs';
const polling: Polling<
AppConnectionValueForAuthProperty<typeof APITableAuth>,
{ datasheet_id: string }
> = {
strategy: DedupeStrategy.TIMEBASED,
items: async ({ auth, propsValue: { datasheet_id }, lastFetchEpochMS }) => {
const client = makeClient(
auth.props
);
const records = await client.listRecords(datasheet_id as string, {
filterByFormula: `CREATED_TIME() > ${
lastFetchEpochMS === 0
? dayjs().subtract(1, 'day').valueOf()
: lastFetchEpochMS
}`,
});
return records.data.records.map((record) => {
return {
epochMilliSeconds: record.createdAt,
data: record,
};
});
},
};
export const newRecordTrigger = createTrigger({
auth: APITableAuth,
name: 'new_record',
displayName: 'New Record',
description: 'Triggers when a new record is added to a datasheet.',
props: {
space_id: APITableCommon.space_id,
datasheet_id: APITableCommon.datasheet_id,
},
sampleData: {
recordId: 'rec2T5ppW1Mal',
createdAt: 1689772153000,
updatedAt: 1689772153000,
fields: {
Title: 'mhm',
AmazingField: 'You are really looking at this?',
'Long text': 'veeeeeeeery long text',
},
},
type: TriggerStrategy.POLLING,
async test(context) {
return await pollingHelper.test(polling, {
store: context.store,
auth: context.auth,
propsValue: { datasheet_id: context.propsValue.datasheet_id },
files: context.files,
});
},
async onEnable(context) {
await pollingHelper.onEnable(polling, {
store: context.store,
auth: context.auth,
propsValue: { datasheet_id: context.propsValue.datasheet_id },
});
},
async onDisable(context) {
await pollingHelper.onDisable(polling, {
store: context.store,
auth: context.auth,
propsValue: { datasheet_id: context.propsValue.datasheet_id },
});
},
async run(context) {
return await pollingHelper.poll(polling, {
store: context.store,
auth: context.auth,
propsValue: { datasheet_id: context.propsValue.datasheet_id },
files: context.files,
});
},
});