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,51 @@
{
"Airtable": "Airtable",
"Lowcode platform to build apps.": "Lowcode platform to build apps.",
"\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ": "\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ",
"Create Airtable Record": "Create Airtable Record",
"Find Airtable Record": "Find Airtable Record",
"Update Airtable Record": "Update Airtable Record",
"Delete Airtable Record": "Delete Airtable Record",
"Upload File to Column": "Upload File to Column",
"Custom API Call": "Custom API Call",
"Adds a record into an airtable": "Adds a record into an airtable",
"Find a record in airtable": "Find a record in airtable",
"Update a record in airtable": "Update a record in airtable",
"Deletes a record in airtable": "Deletes a record in airtable",
"Uploads a file to attachment type column.": "Uploads a file to attachment type column.",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Base": "Base",
"Table": "Table",
"Search Field": "Search Field",
"Search Value": "Search Value",
"View": "View",
"Record ID": "Record ID",
"Attachment Column": "Attachment Column",
"File": "File",
"File Content Type": "File Content Type",
"File Name": "File Name",
"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 ID of the record you want to update. You can find the record ID by clicking on the record and then clicking on the share button. The ID will be in the URL.": "The ID of the record you want to update. You can find the record ID by clicking on the record and then clicking on the share button. The ID will be in the URL.",
"The ID of the record to which you want to upload the file.": "The ID of the record to which you want to upload the file.",
"The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.": "The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.",
"Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').": "Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').",
"The name of the file as it should appear after upload.": "The name of the file as it should appear after upload.",
"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",
"New or Updated Record": "New or Updated Record",
"Triggers when a new record is added to the selected table.": "Triggers when a new record is added to the selected table.",
"Triggers when a record is created or updated in selected table.": "Triggers when a record is created or updated in selected table.",
"Trigger field": "Trigger field",
"**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field.": "**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field."
}

View File

@@ -0,0 +1,87 @@
{
"Lowcode platform to build apps.": "Niedrig<unk> Code-Plattform zum Erstellen von Apps.",
"\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ": "\n Um Ihr persönliches Zeichen zu erhalten, folgen Sie diesen Schritten:\n\n 1. Melden Sie sich bei Ihrem Airtable Konto an.\n 2. Besuche https://airtable.com/create/tokens/ um einen\n 3 zu erstellen. Klicken Sie auf \"+ Basis hinzufügen\" und wählen Sie die Basis, die Sie verwenden möchten oder alle Basis.\n 4. Klicken Sie auf \"+ Geltungsbereich hinzufügen\" und wählen Sie \"Daten\". ecords.read\", \"data.records.write\" und \"schema.bases.read\".\n 5. Klicken Sie auf \"Token erstellen\" und kopieren Sie den Token.\n ",
"Create Airtable Record": "Airtable Datensatz erstellen",
"Find Airtable Record": "Airtable Datensatz finden",
"Update Airtable Record": "Airtable Datensatz aktualisieren",
"Delete Airtable Record": "Airtable Eintrag löschen",
"Upload File to Column": "Datei in Spalte hochladen",
"Add Comment to Record": "Kommentar zum Datensatz hinzufügen",
"Create Base": "Basis erstellen",
"Create Table": "Tabelle erstellen",
"Find Base": "Basis suchen",
"Find Table by ID": "Tabelle über ID finden",
"Get Record by ID": "Datensatz per ID abrufen",
"Find Table": "Tabelle finden",
"Get Base Schema": "Basis-Schema abrufen",
"Custom API Call": "Eigener API-Aufruf",
"Adds a record into an airtable": "Fügt einen Datensatz zu einer Airtable hinzu",
"Find a record in airtable": "Finde einen Eintrag in Airtable",
"Update a record in airtable": "Eintrag in Airtable aktualisieren",
"Deletes a record in airtable": "Löscht einen Eintrag in der Airtable",
"Uploads a file to attachment type column.": "Lade eine Datei in die Spalte des Anhangs hoch.",
"Adds a comment to an existing record.": "Fügt einen Kommentar zu einem bestehenden Datensatz hinzu.",
"Create a new base with a specified table structure.": "Erstellen Sie eine neue Basis mit einer bestimmten Tabellenstruktur.",
"Create a new table in an existing base.": "Erstellen Sie eine neue Tabelle in einer existierenden Basis.",
"Find a base by its name or a keyword.": "Finden Sie eine Basis mit ihrem Namen oder einem Schlüsselwort.",
"Get a table's details and schema using its ID.": "Ruft die Details einer Tabelle und ein Schema mit seiner ID ab.",
"Retrieve a single record from a table by its unique ID.": "Holen Sie einen einzigen Datensatz aus einer Tabelle mit einer eindeutigen ID.",
"Find a table in a given base by its name.": "Finden Sie eine Tabelle in einer bestimmten Basis mit ihrem Namen.",
"Retrieve the schema for a specific base, including all its tables and fields.": "Abrufen des Schemas für eine bestimmte Basis, einschließlich aller Tabellen und Felder.",
"Make a custom API call to a specific endpoint": "Einen benutzerdefinierten API-Aufruf an einen bestimmten Endpunkt machen",
"Base": "Basis",
"Table": "Tisch",
"Search Field": "Suchfeld",
"Search Value": "Suchwert",
"View": "Ansicht",
"Record ID": "Datensatz-ID",
"Attachment Column": "Anhangspalte",
"File": "Datei",
"File Content Type": "Datei-Content-Typ",
"File Name": "Dateiname",
"Comment Text": "Kommentartext",
"Parent Comment ID": "Übergeordnete Kommentar-ID",
"Workspace": "Arbeitsbereich",
"Base Name": "Basisname",
"Tables": "Tabellen",
"Table Name": "Tabellenname",
"Description": "Beschreibung",
"Fields": "Felder",
"Base Name or Keyword": "Basis-Name oder Schlüsselwort",
"Record": "Datensatz",
"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 ID of the record.": "Die ID des Datensatzes.",
"The ID of the record to which you want to upload the file.": "Die ID des Datensatzes, in den Sie die Datei hochladen möchten.",
"The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.": "Die hochzuladende Datei, die entweder als öffentliche Datei-URL oder im Base64-kodierten Format zur Verfügung gestellt werden kann.",
"Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').": "Gibt den MIME-Typ der hochzuladenden Datei an (z.B. 'image/png', 'application/pdf').",
"The name of the file as it should appear after upload.": "Der Name der Datei, wie sie nach dem Hochladen erscheinen soll.",
"The content of the comment. To mention a user, use the format `@[userId]` or `@[userEmail]`.": "Der Inhalt des Kommentars. Um einen Benutzer zu erwähnen, verwende das Format `@[userId]` oder `@[userEmail]`.",
"Optional. The ID of a parent comment to create a threaded reply.": "Optional. Die ID eines übergeordneten Kommentars, um eine Antwort zu erstellen.",
"The name for the new base.": "Der Name für die neue Basis.",
"Define the tables for the new base. Use the default value as a template. The first field for each table will be its primary field.": "Definieren Sie die Tabellen für die neue Basis. Verwenden Sie den Standardwert als Vorlage. Das erste Feld für jede Tabelle ist das primäre Feld.",
"The name for the new table.": "Der Name für die neue Tabelle.",
"An optional description for the new table.": "Eine optionale Beschreibung für die neue Tabelle.",
"A JSON array of fields for the new table. The first field in the array will become the primary field.": "Ein JSON-Array von Feldern für die neue Tabelle. Das erste Feld im Array wird das primäre Feld.",
"The name or keyword to search for within your base names.": "Der Name oder das Keyword, nach dem Sie innerhalb Ihrer Basisnamen suchen möchten.",
"The exact name of the table you want to find.": "Der genaue Name der Tabelle, die Sie finden möchten.",
"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",
"New or Updated Record": "Neuer oder aktualisierter Datensatz",
"Triggers when a new record is added to the selected table.": "Wird ausgelöst, wenn ein neuer Datensatz zur ausgewählten Tabelle hinzugefügt wird.",
"Triggers when a record is created or updated in selected table.": "Wird ausgelöst, wenn ein Datensatz in der ausgewählten Tabelle erstellt oder aktualisiert wird.",
"Trigger field": "Auslösefeld",
"**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field.": "**Zuletzt geändertes Zeit** Feld wird verwendet, um neue oder aktualisierte Datensätze zu sehen. Leasing erstellen Sie das **Zuletzt geänderte Zeit** Feld in Ihrem Schema, wenn Sie kein Zeitstempelfeld haben."
}

View File

@@ -0,0 +1,87 @@
{
"Lowcode platform to build apps.": "Plataforma de bajo código para construir aplicaciones.",
"\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ": "\n Para obtener tu token personal, sigue estos pasos:\n\n 1. Inicie sesión en su cuenta Airtable.\n 2. Visita https://airtable.com/create/tokens/ para crear una\n 3. Haga clic en \"+ Añadir una base\" y seleccione la base que desea utilizar o todas las bases.\n 4. Haga clic en \"+ Añadir un ámbito de aplicación\" y seleccione \"datos. ecords.read\", \"data.records.write\" y \"schema.bases.read\".\n 5. Haga clic en \"Crear token\" y copie el token.\n ",
"Create Airtable Record": "Crear registro Airtable",
"Find Airtable Record": "Encontrar registro Airtable",
"Update Airtable Record": "Actualizar registro Airtable",
"Delete Airtable Record": "Eliminar registro Airtable",
"Upload File to Column": "Subir archivo a Column",
"Add Comment to Record": "Añadir comentario al registro",
"Create Base": "Crear Base",
"Create Table": "Crear tabla",
"Find Base": "Buscar Base",
"Find Table by ID": "Buscar tabla por ID",
"Get Record by ID": "Obtener registro por ID",
"Find Table": "Buscar tabla",
"Get Base Schema": "Obtener Esquema Base",
"Custom API Call": "Llamada API personalizada",
"Adds a record into an airtable": "Añade un registro a una tabla aérea",
"Find a record in airtable": "Encontrar un registro en la tabla aérea",
"Update a record in airtable": "Actualizar un registro en tabla aérea",
"Deletes a record in airtable": "Elimina un registro de la tabla aérea",
"Uploads a file to attachment type column.": "Sube un archivo a columna de tipo adjunto.",
"Adds a comment to an existing record.": "Añade un comentario a un registro existente.",
"Create a new base with a specified table structure.": "Crear una nueva base con una estructura de tabla especificada.",
"Create a new table in an existing base.": "Crear una nueva tabla en una base existente.",
"Find a base by its name or a keyword.": "Encuentre una base por su nombre o una palabra clave.",
"Get a table's details and schema using its ID.": "Obtenga los detalles y el esquema de una tabla usando su ID.",
"Retrieve a single record from a table by its unique ID.": "Recuperar un solo registro de una tabla por su ID único.",
"Find a table in a given base by its name.": "Encuentre una tabla en una base dada por su nombre.",
"Retrieve the schema for a specific base, including all its tables and fields.": "Recuperar el esquema para una base específica, incluyendo todas sus tablas y campos.",
"Make a custom API call to a specific endpoint": "Hacer una llamada API personalizada a un extremo específico",
"Base": "Base",
"Table": "Tabla",
"Search Field": "Campo de búsqueda",
"Search Value": "Valor de búsqueda",
"View": "Ver",
"Record ID": "ID de registro",
"Attachment Column": "Columna de adjunto",
"File": "Archivo",
"File Content Type": "Tipo de contenido de archivo",
"File Name": "Nombre del archivo",
"Comment Text": "Comentario",
"Parent Comment ID": "ID de comentario padre",
"Workspace": "Espacio de trabajo",
"Base Name": "Nombre Base",
"Tables": "Tablas",
"Table Name": "Nombre de tabla",
"Description": "Descripción",
"Fields": "Campos",
"Base Name or Keyword": "Nombre base o palabra clave",
"Record": "Grabar",
"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 ID of the record.": "El ID del registro.",
"The ID of the record to which you want to upload the file.": "El ID del registro al que desea subir el archivo.",
"The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.": "El archivo a cargar, que puede ser proporcionado ya sea como una URL de archivo público o en formato codificado Base64.",
"Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').": "Especifica el tipo MIME del archivo que se está subiendo (por ejemplo, 'image/png', 'application/pdf').",
"The name of the file as it should appear after upload.": "El nombre del archivo tal y como debería aparecer después de subir.",
"The content of the comment. To mention a user, use the format `@[userId]` or `@[userEmail]`.": "El contenido del comentario. Para mencionar a un usuario, utiliza el formato `@[userId]` o `@[userEmail]`.",
"Optional. The ID of a parent comment to create a threaded reply.": "Opcional. El ID de un comentario padre para crear una respuesta del hilo.",
"The name for the new base.": "El nombre de la nueva base.",
"Define the tables for the new base. Use the default value as a template. The first field for each table will be its primary field.": "Defina las tablas para la nueva base. Utilice el valor por defecto como una plantilla. El primer campo para cada tabla será su campo principal.",
"The name for the new table.": "El nombre para la nueva tabla.",
"An optional description for the new table.": "Una descripción opcional para la nueva tabla.",
"A JSON array of fields for the new table. The first field in the array will become the primary field.": "Un array JSON de campos para la nueva tabla. El primer campo de la matriz se convertirá en el campo primario.",
"The name or keyword to search for within your base names.": "El nombre o palabra clave a buscar dentro de sus nombres base.",
"The exact name of the table you want to find.": "El nombre exacto de la tabla que desea encontrar.",
"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",
"New or Updated Record": "Registro nuevo o actualizado",
"Triggers when a new record is added to the selected table.": "Se activa cuando se añade un nuevo registro a la tabla seleccionada.",
"Triggers when a record is created or updated in selected table.": "Se activa cuando se crea o actualiza un registro en la tabla seleccionada.",
"Trigger field": "Campo de activación",
"**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field.": "El campo **Última Hora Modificada** se utilizará para ver registros nuevos o actualizados. lease create **Last Modified Time** field in your schema,if you don't have any timestamp field."
}

View File

@@ -0,0 +1,87 @@
{
"Lowcode platform to build apps.": "Plateforme de code faible pour construire des applications.",
"\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ": "\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ",
"Create Airtable Record": "Créer un enregistrement Airtable",
"Find Airtable Record": "Trouver un enregistrement Airtable",
"Update Airtable Record": "Mise à jour de l'enregistrement Airtable",
"Delete Airtable Record": "Supprimer l'enregistrement Airtable",
"Upload File to Column": "Télécharger le fichier vers la colonne",
"Add Comment to Record": "Ajouter un commentaire à l'enregistrement",
"Create Base": "Créer une base",
"Create Table": "Créer une table",
"Find Base": "Trouver la Base",
"Find Table by ID": "Rechercher un tableau par ID",
"Get Record by ID": "Obtenir l'enregistrement par ID",
"Find Table": "Trouver une table",
"Get Base Schema": "Obtenir le Schéma de Base",
"Custom API Call": "Appel d'API personnalisé",
"Adds a record into an airtable": "Ajoute un enregistrement dans une table d'air",
"Find a record in airtable": "Trouver un enregistrement dans la table d'antenne",
"Update a record in airtable": "Mettre à jour un enregistrement dans la table d'antenne",
"Deletes a record in airtable": "Supprime un enregistrement dans la table d'antenne",
"Uploads a file to attachment type column.": "Télécharge un fichier dans la colonne de type de pièce jointe.",
"Adds a comment to an existing record.": "Ajoute un commentaire à un enregistrement existant.",
"Create a new base with a specified table structure.": "Créer une nouvelle base avec une structure de table spécifiée.",
"Create a new table in an existing base.": "Créer une nouvelle table dans une base existante.",
"Find a base by its name or a keyword.": "Trouvez une base par son nom ou un mot-clé.",
"Get a table's details and schema using its ID.": "Récupère les détails et le schéma d'une table en utilisant son ID.",
"Retrieve a single record from a table by its unique ID.": "Récupère un seul enregistrement dans une table par son ID unique.",
"Find a table in a given base by its name.": "Trouver une table dans une base donnée par son nom.",
"Retrieve the schema for a specific base, including all its tables and fields.": "Récupère le schéma pour une base spécifique, y compris tous ses tables et champs.",
"Make a custom API call to a specific endpoint": "Passer un appel API personnalisé à un endpoint spécifique",
"Base": "Base",
"Table": "Tableau",
"Search Field": "Champ de recherche",
"Search Value": "Valeur de la recherche",
"View": "Afficher",
"Record ID": "ID de l'enregistrement",
"Attachment Column": "Colonne de pièce jointe",
"File": "Ficher",
"File Content Type": "Type de contenu du fichier",
"File Name": "Nom du fichier",
"Comment Text": "Texte du commentaire",
"Parent Comment ID": "ID du commentaire parent",
"Workspace": "Espace de travail",
"Base Name": "Nom de base",
"Tables": "Tables",
"Table Name": "Nom de la table",
"Description": "Libellé",
"Fields": "Champs",
"Base Name or Keyword": "Nom de base ou mot-clé",
"Record": "Enregistrements",
"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 ID of the record.": "L'ID de l'enregistrement.",
"The ID of the record to which you want to upload the file.": "L'ID de l'enregistrement vers lequel vous voulez télécharger le fichier.",
"The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.": "Le fichier à télécharger, qui peut être fourni sous forme d'URL de fichier publique ou au format encodé en Base64.",
"Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').": "Spécifie le type MIME du fichier en cours d'envoi (par exemple, 'image/png', 'application/pdf').",
"The name of the file as it should appear after upload.": "Le nom du fichier tel qu'il devrait apparaître après le téléchargement.",
"The content of the comment. To mention a user, use the format `@[userId]` or `@[userEmail]`.": "Le contenu du commentaire. Pour mentionner un utilisateur, utilisez le format `@[userId]` ou `@[userEmail]`.",
"Optional. The ID of a parent comment to create a threaded reply.": "Optionnel. L'ID d'un commentaire parent pour créer une réponse threadée.",
"The name for the new base.": "Le nom de la nouvelle base.",
"Define the tables for the new base. Use the default value as a template. The first field for each table will be its primary field.": "Définissez les tables pour la nouvelle base. Utilisez la valeur par défaut comme modèle. Le premier champ pour chaque table sera son champ primaire.",
"The name for the new table.": "Le nom de la nouvelle table.",
"An optional description for the new table.": "Une description optionnelle pour la nouvelle table.",
"A JSON array of fields for the new table. The first field in the array will become the primary field.": "Un tableau JSON de champs pour la nouvelle table. Le premier champ du tableau deviendra le champ primaire.",
"The name or keyword to search for within your base names.": "Le nom ou le mot clé à rechercher dans vos noms de base.",
"The exact name of the table you want to find.": "Le nom exact de la table que vous voulez trouver.",
"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",
"New or Updated Record": "Nouvel enregistrement ou mis à jour",
"Triggers when a new record is added to the selected table.": "Déclenche lorsqu'un nouvel enregistrement est ajouté à la table sélectionnée.",
"Triggers when a record is created or updated in selected table.": "Déclenche lorsqu'un enregistrement est créé ou mis à jour dans la table sélectionnée.",
"Trigger field": "Champ de déclenchement",
"**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field.": "Le champ **Dernière Modification** sera utilisé pour regarder les enregistrements nouveaux ou mis à jour. créer un champ **Dernière modification** dans votre schéma, si vous n'avez pas de champ d'horodatage."
}

View File

@@ -0,0 +1,51 @@
{
"Airtable": "Airtable",
"Lowcode platform to build apps.": "Lowcode platform to build apps.",
"\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ": "\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ",
"Create Airtable Record": "Create Airtable Record",
"Find Airtable Record": "Find Airtable Record",
"Update Airtable Record": "Update Airtable Record",
"Delete Airtable Record": "Delete Airtable Record",
"Upload File to Column": "Upload File to Column",
"Custom API Call": "Custom API Call",
"Adds a record into an airtable": "Adds a record into an airtable",
"Find a record in airtable": "Find a record in airtable",
"Update a record in airtable": "Update a record in airtable",
"Deletes a record in airtable": "Deletes a record in airtable",
"Uploads a file to attachment type column.": "Uploads a file to attachment type column.",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Base": "Base",
"Table": "Table",
"Search Field": "Search Field",
"Search Value": "Search Value",
"View": "View",
"Record ID": "Record ID",
"Attachment Column": "Attachment Column",
"File": "File",
"File Content Type": "File Content Type",
"File Name": "File Name",
"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 ID of the record you want to update. You can find the record ID by clicking on the record and then clicking on the share button. The ID will be in the URL.": "The ID of the record you want to update. You can find the record ID by clicking on the record and then clicking on the share button. The ID will be in the URL.",
"The ID of the record to which you want to upload the file.": "The ID of the record to which you want to upload the file.",
"The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.": "The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.",
"Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').": "Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').",
"The name of the file as it should appear after upload.": "The name of the file as it should appear after upload.",
"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",
"New or Updated Record": "New or Updated Record",
"Triggers when a new record is added to the selected table.": "Triggers when a new record is added to the selected table.",
"Triggers when a record is created or updated in selected table.": "Triggers when a record is created or updated in selected table.",
"Trigger field": "Trigger field",
"**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field.": "**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field."
}

View File

@@ -0,0 +1,51 @@
{
"Airtable": "Airtable",
"Lowcode platform to build apps.": "Lowcode platform to build apps.",
"\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ": "\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ",
"Create Airtable Record": "Create Airtable Record",
"Find Airtable Record": "Find Airtable Record",
"Update Airtable Record": "Update Airtable Record",
"Delete Airtable Record": "Delete Airtable Record",
"Upload File to Column": "Upload File to Column",
"Custom API Call": "Custom API Call",
"Adds a record into an airtable": "Adds a record into an airtable",
"Find a record in airtable": "Find a record in airtable",
"Update a record in airtable": "Update a record in airtable",
"Deletes a record in airtable": "Deletes a record in airtable",
"Uploads a file to attachment type column.": "Uploads a file to attachment type column.",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Base": "Base",
"Table": "Table",
"Search Field": "Search Field",
"Search Value": "Search Value",
"View": "View",
"Record ID": "Record ID",
"Attachment Column": "Attachment Column",
"File": "File",
"File Content Type": "File Content Type",
"File Name": "File Name",
"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 ID of the record you want to update. You can find the record ID by clicking on the record and then clicking on the share button. The ID will be in the URL.": "The ID of the record you want to update. You can find the record ID by clicking on the record and then clicking on the share button. The ID will be in the URL.",
"The ID of the record to which you want to upload the file.": "The ID of the record to which you want to upload the file.",
"The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.": "The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.",
"Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').": "Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').",
"The name of the file as it should appear after upload.": "The name of the file as it should appear after upload.",
"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",
"New or Updated Record": "New or Updated Record",
"Triggers when a new record is added to the selected table.": "Triggers when a new record is added to the selected table.",
"Triggers when a record is created or updated in selected table.": "Triggers when a record is created or updated in selected table.",
"Trigger field": "Trigger field",
"**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field.": "**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field."
}

View File

@@ -0,0 +1,87 @@
{
"Lowcode platform to build apps.": "アプリを構築するためのプラットフォームをローコードします。",
"\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ": "\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ",
"Create Airtable Record": "対応可能な記録を作成",
"Find Airtable Record": "対空式記録を検索",
"Update Airtable Record": "対空式記録を更新",
"Delete Airtable Record": "空気の記録を削除",
"Upload File to Column": "列にファイルをアップロード",
"Add Comment to Record": "コメントをレコードに追加",
"Create Base": "ベースを作成",
"Create Table": "テーブルを作成",
"Find Base": "ベースを検索",
"Find Table by ID": "IDでテーブルを検索",
"Get Record by ID": "IDでレコードを取得する",
"Find Table": "テーブルを検索",
"Get Base Schema": "ベーススキーマの取得",
"Custom API Call": "カスタムAPI通話",
"Adds a record into an airtable": "エアーテーブルにレコードを追加",
"Find a record in airtable": "エアテーブルでレコードを見つける",
"Update a record in airtable": "エアテーブルのレコードを更新",
"Deletes a record in airtable": "エアテーブル内のレコードを削除",
"Uploads a file to attachment type column.": "添付ファイルの種類の列にファイルをアップロードします。",
"Adds a comment to an existing record.": "既存のレコードにコメントを追加します。",
"Create a new base with a specified table structure.": "指定されたテーブル構造を持つ新しいベースを作成します。",
"Create a new table in an existing base.": "既存のベースに新しいテーブルを作成します。",
"Find a base by its name or a keyword.": "名前またはキーワードでベースを検索します。",
"Get a table's details and schema using its ID.": "テーブルの ID を使用してテーブルの詳細とスキーマを取得します。",
"Retrieve a single record from a table by its unique ID.": "一意の ID でテーブルから単一レコードを取得します。",
"Find a table in a given base by its name.": "指定されたベース名でテーブルを検索します。",
"Retrieve the schema for a specific base, including all its tables and fields.": "すべてのテーブルとフィールドを含む特定のベースのスキーマを取得します。",
"Make a custom API call to a specific endpoint": "特定のエンドポイントへのカスタム API コールを実行します。",
"Base": "Base",
"Table": "表",
"Search Field": "検索フィールド",
"Search Value": "検索値",
"View": "表示",
"Record ID": "レコードID",
"Attachment Column": "添付ファイルの列",
"File": "ファイル",
"File Content Type": "ファイルコンテンツタイプ",
"File Name": "ファイル名",
"Comment Text": "コメントテキスト",
"Parent Comment ID": "親コメントID",
"Workspace": "ワークスペース",
"Base Name": "ベース名",
"Tables": "テーブル",
"Table Name": "テーブル名",
"Description": "説明",
"Fields": "フィールド",
"Base Name or Keyword": "ベース名またはキーワード",
"Record": "レコード",
"Method": "方法",
"Headers": "ヘッダー",
"Query Parameters": "クエリパラメータ",
"Body": "本文",
"Response is Binary ?": "応答はバイナリですか?",
"No Error on Failure": "失敗時にエラーはありません",
"Timeout (in seconds)": "タイムアウト(秒)",
"The ID of the record.": "レコードの ID",
"The ID of the record to which you want to upload the file.": "ファイルをアップロードするレコードの ID 。",
"The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.": "アップロードするファイルは、公開ファイルの URL または Base64 エンコード形式のいずれかで指定できます。",
"Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').": "アップロードするファイルの MIME タイプを指定します(例: 'image/png', 'application/pdf')。",
"The name of the file as it should appear after upload.": "アップロード後にファイル名が表示されます。",
"The content of the comment. To mention a user, use the format `@[userId]` or `@[userEmail]`.": "コメントの内容。ユーザーに言及するには、`@[userId]` または `@[userEmail] ` 形式を使用します。",
"Optional. The ID of a parent comment to create a threaded reply.": "オプション。スレッドの返信を作成するための親コメントの ID です。",
"The name for the new base.": "新しいベースの名前",
"Define the tables for the new base. Use the default value as a template. The first field for each table will be its primary field.": "新しいベースのテーブルを定義します。テンプレートとしてデフォルト値を使用します。各テーブルの最初のフィールドは、そのプライマリフィールドになります。",
"The name for the new table.": "新しいテーブルの名前。",
"An optional description for the new table.": "新しいテーブルのオプション説明。",
"A JSON array of fields for the new table. The first field in the array will become the primary field.": "新しいテーブルのフィールドの JSON 配列。配列の最初のフィールドはプライマリフィールドになります。",
"The name or keyword to search for within your base names.": "ベース名内を検索するための名前またはキーワード。",
"The exact name of the table you want to find.": "見つけたいテーブルの正確な名前。",
"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": "新しいレコード",
"New or Updated Record": "新規または更新されたレコード",
"Triggers when a new record is added to the selected table.": "選択したテーブルに新しいレコードが追加されたときにトリガーされます。",
"Triggers when a record is created or updated in selected table.": "選択したテーブルでレコードを作成または更新したときにトリガーします。",
"Trigger field": "トリガーフィールド",
"**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field.": "**最終更新時刻** フィールドは、新しいレコードや更新を見るために使用されます。 リース作成**最終更新時刻** あなたのスキーマにタイムスタンプフィールドがなければ、あなたのスキーマにフィールドを作成します。"
}

View File

@@ -0,0 +1,87 @@
{
"Lowcode platform to build apps.": "LowØ code platform om apps te bouwen.",
"\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ": "\n Om je persoonlijke token te krijgen, volg je deze stappen:\n\n 1. Log in op uw Airtable account.\n 2. Bezoek https://airtable.com/create/tokens/ om een\n 3 aan te maken. Klik op \"+ Voeg een basis toe\" en selecteer de basis die je wilt gebruiken of alle basissen.\n 4. Klik op \"+ Een scope toevoegen\" en selecteer \"gegevens\" ecords.read\", \"data.records.write\" en \"schema.bases.read\".\n 5. Klik op \"Maak token\" en kopieer het token.\n ",
"Create Airtable Record": "Airtable Record Maken",
"Find Airtable Record": "Vind Airtable Record",
"Update Airtable Record": "Airtable Record bijwerken",
"Delete Airtable Record": "Airtable Record verwijderen",
"Upload File to Column": "Bestand naar kolom uploaden",
"Add Comment to Record": "Opmerking toevoegen aan record",
"Create Base": "Basis maken",
"Create Table": "Tabel maken",
"Find Base": "Basis zoeken",
"Find Table by ID": "Tabel zoeken op ID",
"Get Record by ID": "Krijg Record via ID",
"Find Table": "Tabel zoeken",
"Get Base Schema": "Verkrijg Basis Schema",
"Custom API Call": "Custom API Call",
"Adds a record into an airtable": "Voegt een record toe in een airtable",
"Find a record in airtable": "Vind een record in airtable",
"Update a record in airtable": "Een record in airtable bijwerken",
"Deletes a record in airtable": "Verwijdert een record in de luchtbel",
"Uploads a file to attachment type column.": "Uploaden van een bestand naar kolom bijlagentype.",
"Adds a comment to an existing record.": "Voegt een opmerking toe aan een bestaand record.",
"Create a new base with a specified table structure.": "Maak een nieuwe basis met een opgegeven tabelstructuur.",
"Create a new table in an existing base.": "Maak een nieuwe tabel aan in een bestaande basis.",
"Find a base by its name or a keyword.": "Zoek een basis op naam of trefwoord.",
"Get a table's details and schema using its ID.": "Ontvang details van de tabel en schema met behulp van de ID.",
"Retrieve a single record from a table by its unique ID.": "Haal een enkel record op uit een tabel met zijn unieke ID.",
"Find a table in a given base by its name.": "Zoek een tabel in een bepaalde basis op de naam.",
"Retrieve the schema for a specific base, including all its tables and fields.": "Haal het schema op voor een specifieke basis, inclusief al zijn tabellen en velden.",
"Make a custom API call to a specific endpoint": "Maak een aangepaste API call naar een specifiek eindpunt",
"Base": "Basis",
"Table": "Tabel",
"Search Field": "Zoek veld",
"Search Value": "Waarde zoeken",
"View": "Weergave",
"Record ID": "Record ID",
"Attachment Column": "Bijlage kolom",
"File": "Bestand",
"File Content Type": "Bestand Content Type",
"File Name": "File Name",
"Comment Text": "Commentaar tekst",
"Parent Comment ID": "Bovenliggende Reactie ID",
"Workspace": "werkruimte",
"Base Name": "Basis naam",
"Tables": "Tabellen",
"Table Name": "Tafel naam",
"Description": "Beschrijving",
"Fields": "Velden",
"Base Name or Keyword": "Basisnaam of sleutelwoord",
"Record": "Opnemen",
"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 ID of the record.": "Het ID van het record.",
"The ID of the record to which you want to upload the file.": "Het ID van het record waarnaar u het bestand wilt uploaden.",
"The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.": "Het te uploaden bestand, dat kan worden verstrekt als een URL van een publiek bestand of in Base64 gecodeerde formaat.",
"Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').": "Geeft het MIME-type op van het bestand dat wordt geüpload (bijv. 'image/png', 'application/pdf').",
"The name of the file as it should appear after upload.": "De naam van het bestand zoals het moet worden weergegeven na uploaden.",
"The content of the comment. To mention a user, use the format `@[userId]` or `@[userEmail]`.": "De inhoud van de opmerking. Om een gebruiker te vermelden, gebruik het formaat `@[userId]` of `@[userEmail]`.",
"Optional. The ID of a parent comment to create a threaded reply.": "Optioneel. De ID van een bovenliggende opmerking om een threaded antwoord te maken.",
"The name for the new base.": "De naam voor de nieuwe basis.",
"Define the tables for the new base. Use the default value as a template. The first field for each table will be its primary field.": "Definieer de tabellen voor de nieuwe basis. Gebruik de standaard waarde als een sjabloon. Het eerste veld voor elke tabel is het primaire veld.",
"The name for the new table.": "De naam van de nieuwe tabel.",
"An optional description for the new table.": "Een optionele beschrijving van de nieuwe tabel.",
"A JSON array of fields for the new table. The first field in the array will become the primary field.": "Een JSON reeks velden voor de nieuwe tabel. Het eerste veld in de array zal het primaire veld worden.",
"The name or keyword to search for within your base names.": "De naam of trefwoord om naar binnen je basisnamen te zoeken.",
"The exact name of the table you want to find.": "De exacte naam van de tabel die u wilt vinden.",
"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",
"New or Updated Record": "Nieuwe of bijgewerkte record",
"Triggers when a new record is added to the selected table.": "Activeert wanneer een nieuwe record wordt toegevoegd aan de geselecteerde tabel.",
"Triggers when a record is created or updated in selected table.": "Triggert wanneer een record wordt aangemaakt of bijgewerkt in de geselecteerde tabel.",
"Trigger field": "Trigger veld",
"**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field.": "**Laatst gewijzigde tijd** veld zal worden gebruikt om nieuwe of bijgewerkte records te bekijken. lease creëer **Last Modified Time** veld in je schema, als je geen timestamp veld hebt."
}

View File

@@ -0,0 +1,87 @@
{
"Lowcode platform to build apps.": "Baixa plataforma de código para construir aplicativos.",
"\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ": "\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ",
"Create Airtable Record": "Criar Registro Airtable",
"Find Airtable Record": "Encontrar Registro Airtable",
"Update Airtable Record": "Atualizar Registro Airtable",
"Delete Airtable Record": "Excluir registro da Airtable",
"Upload File to Column": "Carregar Arquivo para Coluna",
"Add Comment to Record": "Adicionar Comentário para Registrar",
"Create Base": "Criar Base",
"Create Table": "Criar tabela",
"Find Base": "Encontrar Base",
"Find Table by ID": "Encontrar tabela por ID",
"Get Record by ID": "Obter registro por ID",
"Find Table": "Encontrar a tabela",
"Get Base Schema": "Obter Esquema Base",
"Custom API Call": "Chamada de API personalizada",
"Adds a record into an airtable": "Adiciona um registro a uma tabela aérea",
"Find a record in airtable": "Encontrar um registro na tabela aérea",
"Update a record in airtable": "Atualizar um registro no airtable",
"Deletes a record in airtable": "Exclui um registro na tabela aérea",
"Uploads a file to attachment type column.": "Carrega um arquivo para anexar coluna de tipos.",
"Adds a comment to an existing record.": "Adiciona um comentário a um registro existente.",
"Create a new base with a specified table structure.": "Criar uma nova base com uma estrutura de tabela especificada.",
"Create a new table in an existing base.": "Criar uma nova tabela em uma base existente.",
"Find a base by its name or a keyword.": "Encontre uma base pelo seu nome ou palavra-chave.",
"Get a table's details and schema using its ID.": "Obtenha detalhes e esquemas de uma tabela usando seu ID.",
"Retrieve a single record from a table by its unique ID.": "Recuperar um único registro de uma tabela com sua ID única.",
"Find a table in a given base by its name.": "Encontre uma tabela em uma determinada base pelo seu nome.",
"Retrieve the schema for a specific base, including all its tables and fields.": "Recupere o esquema para uma base específica, incluindo todas as suas tabelas e campos.",
"Make a custom API call to a specific endpoint": "Faça uma chamada de API personalizada para um ponto de extremidade específico",
"Base": "Base",
"Table": "Classificações",
"Search Field": "Campo de pesquisa",
"Search Value": "Pesquisar Valor",
"View": "Visualizar",
"Record ID": "ID do Registro",
"Attachment Column": "Coluna de anexos",
"File": "Arquivo",
"File Content Type": "Tipo de Conteúdo",
"File Name": "Nome do arquivo",
"Comment Text": "Texto do comentário",
"Parent Comment ID": "ID do Comentário Pai",
"Workspace": "Workspace",
"Base Name": "Nome Base",
"Tables": "Tabelas",
"Table Name": "Nome da Tabela",
"Description": "Descrição",
"Fields": "campos",
"Base Name or Keyword": "Nome Base ou Palavra-Chave",
"Record": "Gravar",
"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 ID of the record.": "A ID do registro.",
"The ID of the record to which you want to upload the file.": "O ID do registro para o qual você deseja fazer upload do arquivo.",
"The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.": "O arquivo a ser carregado, que pode ser fornecido como uma URL de arquivo público ou no formato codificado em Base64.",
"Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').": "Especifica o tipo MIME do arquivo que está sendo enviado (por exemplo, 'image/png', 'application/pdf').",
"The name of the file as it should appear after upload.": "O nome do arquivo como ele deve aparecer após o upload.",
"The content of the comment. To mention a user, use the format `@[userId]` or `@[userEmail]`.": "O conteúdo do comentário. Para mencionar um usuário, use o formato `@[userId]` ou `@[userEmail]`.",
"Optional. The ID of a parent comment to create a threaded reply.": "Opcional. O ID de um comentário pai para criar uma resposta em discussão.",
"The name for the new base.": "O nome da nova base.",
"Define the tables for the new base. Use the default value as a template. The first field for each table will be its primary field.": "Defina as tabelas para a nova base. Use o valor padrão como um modelo. O primeiro campo para cada tabela será seu campo primário.",
"The name for the new table.": "O nome para a nova tabela.",
"An optional description for the new table.": "Uma descrição opcional para a nova tabela.",
"A JSON array of fields for the new table. The first field in the array will become the primary field.": "Uma matriz JSON de campos para a nova tabela. O primeiro campo no array se tornará o campo primário.",
"The name or keyword to search for within your base names.": "O nome ou palavra-chave para pesquisar dentro dos nomes de sua base.",
"The exact name of the table you want to find.": "O nome exato da tabela que você quer encontrar.",
"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",
"New or Updated Record": "Registro novo ou atualizado",
"Triggers when a new record is added to the selected table.": "Dispara quando um novo registro é adicionado à tabela selecionada.",
"Triggers when a record is created or updated in selected table.": "Dispara quando um registro é criado ou atualizado na tabela selecionada.",
"Trigger field": "Campo gatilho",
"**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field.": "O campo **Última Modificação** será usado para assistir registros novos ou atualizados. crie campo **Hora Última Modificação** em seu esquema, se você não tiver nenhum campo de carimbo de data."
}

View File

@@ -0,0 +1,51 @@
{
"Airtable": "Airtable",
"Lowcode platform to build apps.": "Низкая платформа для создания приложений.",
"\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ": "\n Для получения личного токена выполните следующие действия:\n\n 1. Войдите в свой аккаунт Airtable.\n 2. Посетите https://airtable.com/create/tokens/ для создания одной\n 3. Нажмите на \"+ Добавить базу\" и выберите базу, которую вы хотите использовать или все базы.\n 4. Нажмите \"+ Добавить область\" и выберите \"данные. ecords.read\", \"data.records.write\" и \"schema.bases.read\".\n 5. Нажмите на \"Create token\" и скопируйте токен.\n ",
"Create Airtable Record": "Создать запись Airtable",
"Find Airtable Record": "Найти запись Airtable",
"Update Airtable Record": "Обновить запись Airtable",
"Delete Airtable Record": "Удалить запись Airtable",
"Upload File to Column": "Загрузить файл в столбец",
"Custom API Call": "Пользовательский вызов API",
"Adds a record into an airtable": "Добавляет запись в авиатаблицу",
"Find a record in airtable": "Найти запись в авиатаблице",
"Update a record in airtable": "Изменить запись в авиатаблице",
"Deletes a record in airtable": "Удаляет запись в авиационной таблице",
"Uploads a file to attachment type column.": "Загружает файл для типа вложения столбца.",
"Make a custom API call to a specific endpoint": "Сделать пользовательский API вызов к определенной конечной точке",
"Base": "Основание",
"Table": "Таблица",
"Search Field": "Поле поиска",
"Search Value": "Поисковое значение",
"View": "View",
"Record ID": "ID записи",
"Attachment Column": "Столбец вложения",
"File": "Файл",
"File Content Type": "Тип содержимого файла",
"File Name": "Имя файла",
"Method": "Метод",
"Headers": "Заголовки",
"Query Parameters": "Параметры запроса",
"Body": "Тело",
"No Error on Failure": "Нет ошибок при ошибке",
"Timeout (in seconds)": "Таймаут (в секундах)",
"The ID of the record you want to update. You can find the record ID by clicking on the record and then clicking on the share button. The ID will be in the URL.": "ID записи, которую вы хотите обновить. Вы можете найти идентификатор записи, нажав на запись, а затем нажав на кнопку \"Поделиться\".",
"The ID of the record to which you want to upload the file.": "ID записи, в которую вы хотите загрузить файл.",
"The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.": "Загружаемый файл, который может быть предоставлен как публичный URL файла, так и в кодировке Base64.",
"Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').": "Тип MIME загружаемого файла (например, 'image/png', 'application/pdf').",
"The name of the file as it should appear after upload.": "Имя файла, которое должно появиться после загрузки.",
"Authorization headers are injected automatically from your connection.": "Заголовки авторизации включаются автоматически из вашего соединения.",
"GET": "ПОЛУЧИТЬ",
"POST": "ПОСТ",
"PATCH": "ПАТЧ",
"PUT": "ПОКУПИТЬ",
"DELETE": "УДАЛИТЬ",
"HEAD": "HEAD",
"New Record": "Новая запись",
"New or Updated Record": "Новая или Обновленная запись",
"Triggers when a new record is added to the selected table.": "Включает при добавлении новой записи в выбранную таблицу.",
"Triggers when a record is created or updated in selected table.": "Триггеры при создании или обновлении записи в выбранной таблице.",
"Trigger field": "Триггер поле",
"**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field.": "Поле **Время последнего изменения** будет использоваться для просмотра новых или обновленных записей. в аренде создайте поле **Последнее Изменённое время** в вашей схеме, если у вас нет поля отметки времени."
}

View File

@@ -0,0 +1,87 @@
{
"Lowcode platform to build apps.": "Lowcode platform to build apps.",
"\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ": "\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ",
"Create Airtable Record": "Create Airtable Record",
"Find Airtable Record": "Find Airtable Record",
"Update Airtable Record": "Update Airtable Record",
"Delete Airtable Record": "Delete Airtable Record",
"Upload File to Column": "Upload File to Column",
"Add Comment to Record": "Add Comment to Record",
"Create Base": "Create Base",
"Create Table": "Create Table",
"Find Base": "Find Base",
"Find Table by ID": "Find Table by ID",
"Get Record by ID": "Get Record by ID",
"Find Table": "Find Table",
"Get Base Schema": "Get Base Schema",
"Custom API Call": "Custom API Call",
"Adds a record into an airtable": "Adds a record into an airtable",
"Find a record in airtable": "Find a record in airtable",
"Update a record in airtable": "Update a record in airtable",
"Deletes a record in airtable": "Deletes a record in airtable",
"Uploads a file to attachment type column.": "Uploads a file to attachment type column.",
"Adds a comment to an existing record.": "Adds a comment to an existing record.",
"Create a new base with a specified table structure.": "Create a new base with a specified table structure.",
"Create a new table in an existing base.": "Create a new table in an existing base.",
"Find a base by its name or a keyword.": "Find a base by its name or a keyword.",
"Get a table's details and schema using its ID.": "Get a table's details and schema using its ID.",
"Retrieve a single record from a table by its unique ID.": "Retrieve a single record from a table by its unique ID.",
"Find a table in a given base by its name.": "Find a table in a given base by its name.",
"Retrieve the schema for a specific base, including all its tables and fields.": "Retrieve the schema for a specific base, including all its tables and fields.",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Base": "Base",
"Table": "Table",
"Search Field": "Search Field",
"Search Value": "Search Value",
"View": "View",
"Record ID": "Record ID",
"Attachment Column": "Attachment Column",
"File": "File",
"File Content Type": "File Content Type",
"File Name": "File Name",
"Comment Text": "Comment Text",
"Parent Comment ID": "Parent Comment ID",
"Workspace": "Workspace",
"Base Name": "Base Name",
"Tables": "Tables",
"Table Name": "Table Name",
"Description": "Description",
"Fields": "Fields",
"Base Name or Keyword": "Base Name or Keyword",
"Record": "Record",
"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 ID of the record.": "The ID of the record.",
"The ID of the record to which you want to upload the file.": "The ID of the record to which you want to upload the file.",
"The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.": "The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.",
"Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').": "Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').",
"The name of the file as it should appear after upload.": "The name of the file as it should appear after upload.",
"The content of the comment. To mention a user, use the format `@[userId]` or `@[userEmail]`.": "The content of the comment. To mention a user, use the format `@[userId]` or `@[userEmail]`.",
"Optional. The ID of a parent comment to create a threaded reply.": "Optional. The ID of a parent comment to create a threaded reply.",
"The name for the new base.": "The name for the new base.",
"Define the tables for the new base. Use the default value as a template. The first field for each table will be its primary field.": "Define the tables for the new base. Use the default value as a template. The first field for each table will be its primary field.",
"The name for the new table.": "The name for the new table.",
"An optional description for the new table.": "An optional description for the new table.",
"A JSON array of fields for the new table. The first field in the array will become the primary field.": "A JSON array of fields for the new table. The first field in the array will become the primary field.",
"The name or keyword to search for within your base names.": "The name or keyword to search for within your base names.",
"The exact name of the table you want to find.": "The exact name of the table you want to find.",
"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",
"New or Updated Record": "New or Updated Record",
"Triggers when a new record is added to the selected table.": "Triggers when a new record is added to the selected table.",
"Triggers when a record is created or updated in selected table.": "Triggers when a record is created or updated in selected table.",
"Trigger field": "Trigger field",
"**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field.": "**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field."
}

View File

@@ -0,0 +1,51 @@
{
"Airtable": "Airtable",
"Lowcode platform to build apps.": "Lowcode platform to build apps.",
"\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ": "\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ",
"Create Airtable Record": "Create Airtable Record",
"Find Airtable Record": "Find Airtable Record",
"Update Airtable Record": "Update Airtable Record",
"Delete Airtable Record": "Delete Airtable Record",
"Upload File to Column": "Upload File to Column",
"Custom API Call": "Custom API Call",
"Adds a record into an airtable": "Adds a record into an airtable",
"Find a record in airtable": "Find a record in airtable",
"Update a record in airtable": "Update a record in airtable",
"Deletes a record in airtable": "Deletes a record in airtable",
"Uploads a file to attachment type column.": "Uploads a file to attachment type column.",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Base": "Base",
"Table": "Table",
"Search Field": "Search Field",
"Search Value": "Search Value",
"View": "View",
"Record ID": "Record ID",
"Attachment Column": "Attachment Column",
"File": "File",
"File Content Type": "File Content Type",
"File Name": "File Name",
"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 ID of the record you want to update. You can find the record ID by clicking on the record and then clicking on the share button. The ID will be in the URL.": "The ID of the record you want to update. You can find the record ID by clicking on the record and then clicking on the share button. The ID will be in the URL.",
"The ID of the record to which you want to upload the file.": "The ID of the record to which you want to upload the file.",
"The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.": "The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.",
"Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').": "Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').",
"The name of the file as it should appear after upload.": "The name of the file as it should appear after upload.",
"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",
"New or Updated Record": "New or Updated Record",
"Triggers when a new record is added to the selected table.": "Triggers when a new record is added to the selected table.",
"Triggers when a record is created or updated in selected table.": "Triggers when a record is created or updated in selected table.",
"Trigger field": "Trigger field",
"**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field.": "**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field."
}

View File

@@ -0,0 +1,87 @@
{
"Lowcode platform to build apps.": "Lowcode platform to build apps.",
"\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ": "\n To obtain your personal token, follow these steps:\n\n 1. Log in to your Airtable account.\n 2. Visit https://airtable.com/create/tokens/ to create one\n 3. Click on \"+ Add a base\" and select the base you want to use or all bases.\n 4. Click on \"+ Add a scope\" and select \"data.records.read\", \"data.records.write\" and \"schema.bases.read\".\n 5. Click on \"Create token\" and copy the token.\n ",
"Create Airtable Record": "Create Airtable Record",
"Find Airtable Record": "Find Airtable Record",
"Update Airtable Record": "Update Airtable Record",
"Delete Airtable Record": "Delete Airtable Record",
"Upload File to Column": "Upload File to Column",
"Add Comment to Record": "Add Comment to Record",
"Create Base": "Create Base",
"Create Table": "Create Table",
"Find Base": "Find Base",
"Find Table by ID": "Find Table by ID",
"Get Record by ID": "Get Record by ID",
"Find Table": "Find Table",
"Get Base Schema": "Get Base Schema",
"Custom API Call": "自定义 API 呼叫",
"Adds a record into an airtable": "Adds a record into an airtable",
"Find a record in airtable": "Find a record in airtable",
"Update a record in airtable": "Update a record in airtable",
"Deletes a record in airtable": "Deletes a record in airtable",
"Uploads a file to attachment type column.": "Uploads a file to attachment type column.",
"Adds a comment to an existing record.": "Adds a comment to an existing record.",
"Create a new base with a specified table structure.": "Create a new base with a specified table structure.",
"Create a new table in an existing base.": "Create a new table in an existing base.",
"Find a base by its name or a keyword.": "Find a base by its name or a keyword.",
"Get a table's details and schema using its ID.": "Get a table's details and schema using its ID.",
"Retrieve a single record from a table by its unique ID.": "Retrieve a single record from a table by its unique ID.",
"Find a table in a given base by its name.": "Find a table in a given base by its name.",
"Retrieve the schema for a specific base, including all its tables and fields.": "Retrieve the schema for a specific base, including all its tables and fields.",
"Make a custom API call to a specific endpoint": "将一个自定义 API 调用到一个特定的终点",
"Base": "Base",
"Table": "表",
"Search Field": "Search Field",
"Search Value": "搜索值",
"View": "查看",
"Record ID": "Record ID",
"Attachment Column": "Attachment Column",
"File": "文件",
"File Content Type": "File Content Type",
"File Name": "File Name",
"Comment Text": "Comment Text",
"Parent Comment ID": "Parent Comment ID",
"Workspace": "Workspace",
"Base Name": "Base Name",
"Tables": "表",
"Table Name": "Table Name",
"Description": "描述",
"Fields": "Fields",
"Base Name or Keyword": "Base Name or Keyword",
"Record": "Record",
"Method": "方法",
"Headers": "信头",
"Query Parameters": "查询参数",
"Body": "正文内容",
"Response is Binary ?": "Response is Binary ?",
"No Error on Failure": "失败时没有错误",
"Timeout (in seconds)": "超时(秒)",
"The ID of the record.": "The ID of the record.",
"The ID of the record to which you want to upload the file.": "The ID of the record to which you want to upload the file.",
"The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.": "The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.",
"Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').": "Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').",
"The name of the file as it should appear after upload.": "The name of the file as it should appear after upload.",
"The content of the comment. To mention a user, use the format `@[userId]` or `@[userEmail]`.": "The content of the comment. To mention a user, use the format `@[userId]` or `@[userEmail]`.",
"Optional. The ID of a parent comment to create a threaded reply.": "Optional. The ID of a parent comment to create a threaded reply.",
"The name for the new base.": "The name for the new base.",
"Define the tables for the new base. Use the default value as a template. The first field for each table will be its primary field.": "Define the tables for the new base. Use the default value as a template. The first field for each table will be its primary field.",
"The name for the new table.": "The name for the new table.",
"An optional description for the new table.": "An optional description for the new table.",
"A JSON array of fields for the new table. The first field in the array will become the primary field.": "A JSON array of fields for the new table. The first field in the array will become the primary field.",
"The name or keyword to search for within your base names.": "The name or keyword to search for within your base names.",
"The exact name of the table you want to find.": "The exact name of the table you want to find.",
"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",
"New or Updated Record": "New or Updated Record",
"Triggers when a new record is added to the selected table.": "Triggers when a new record is added to the selected table.",
"Triggers when a record is created or updated in selected table.": "Triggers when a record is created or updated in selected table.",
"Trigger field": "Trigger field",
"**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field.": "**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field."
}

View File

@@ -0,0 +1,105 @@
import {
AuthenticationType,
HttpMethod,
createCustomApiCallAction,
httpClient,
} from '@activepieces/pieces-common';
import { PieceAuth, createPiece } from '@activepieces/pieces-framework';
import { PieceCategory } from '@activepieces/shared';
import { airtableCreateRecordAction } from './lib/actions/create-record';
import { airtableDeleteRecordAction } from './lib/actions/delete-record';
import { airtableFindRecordAction } from './lib/actions/find-record';
import { airtableUpdateRecordAction } from './lib/actions/update-record';
import { airtableNewRecordTrigger } from './lib/trigger/new-record.trigger';
import { airtableUpdatedRecordTrigger } from './lib/trigger/update-record.trigger';
import { airtableUploadFileToColumnAction } from './lib/actions/upload-file-to-column';
import { airtableAddCommentToRecordAction } from './lib/actions/add-comment-to-record';
import { airtableCreateBaseAction } from './lib/actions/create-base';
import { airtableCreateTableAction } from './lib/actions/create-table';
import { airtableFindBaseAction } from './lib/actions/find-base';
import { airtableGetRecordByIdAction } from './lib/actions/find-record-by-id';
import { airtableFindTableByIdAction } from './lib/actions/find-table-by-id';
import { airtableFindTableAction } from './lib/actions/find-table';
import { airtableGetBaseSchemaAction } from './lib/actions/get-base-schema';
export const airtableAuth = PieceAuth.SecretText({
displayName: 'Personal Access Token',
required: true,
description: `
To obtain your personal token, follow these steps:
1. Log in to your Airtable account.
2. Visit https://airtable.com/create/tokens/ to create one
3. Click on "+ Add a base" and select the base you want to use or all bases.
4. Click on "+ Add a scope" and select "data.records.read", "data.records.write" and "schema.bases.read".
5. Click on "Create token" and copy the token.
`,
validate: async (auth) => {
try {
await httpClient.sendRequest({
method: HttpMethod.GET,
url: 'https://api.airtable.com/v0/meta/bases',
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: auth.auth,
},
});
return {
valid: true,
};
} catch (e) {
return {
valid: false,
error: 'Invalid personal access token',
};
}
},
});
export const airtable = createPiece({
displayName: 'Airtable',
description: 'Lowcode platform to build apps.',
minimumSupportedRelease: '0.30.0',
logoUrl: 'https://cdn.activepieces.com/pieces/airtable.png',
authors: [
'kanarelo',
'TaskMagicKyle',
'Salem-Alaa',
'kishanprmr',
'MoShizzle',
'AbdulTheActivePiecer',
'khaledmashaly',
'abuaboud',
'Pranith124',
'onyedikachi-david'
],
categories: [PieceCategory.PRODUCTIVITY],
auth: airtableAuth,
actions: [
airtableCreateRecordAction,
airtableFindRecordAction,
airtableUpdateRecordAction,
airtableDeleteRecordAction,
airtableUploadFileToColumnAction,
airtableAddCommentToRecordAction,
airtableCreateBaseAction,
airtableCreateTableAction,
airtableFindBaseAction,
airtableFindTableByIdAction,
airtableGetRecordByIdAction,
airtableFindTableAction,
airtableGetBaseSchemaAction,
createCustomApiCallAction({
baseUrl: () => {
return 'https://api.airtable.com/v0';
},
auth: airtableAuth,
authMapping: async (auth) => ({
Authorization: `Bearer ${auth.secret_text}`,
}),
}),
],
triggers: [airtableNewRecordTrigger, airtableUpdatedRecordTrigger],
});

View File

@@ -0,0 +1,41 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { airtableAuth } from '../../index';
import { airtableCommon } from '../common';
export const airtableAddCommentToRecordAction = createAction({
auth: airtableAuth,
name: 'airtable_add_comment_to_record',
displayName: 'Add Comment to Record',
description: 'Adds a comment to an existing record.',
props: {
base: airtableCommon.base,
tableId: airtableCommon.tableId,
recordId: airtableCommon.recordId,
text: Property.LongText({
displayName: 'Comment Text',
description:
'The content of the comment. To mention a user, use the format `@[userId]` or `@[userEmail]`.',
required: true,
}),
parentCommentId: Property.ShortText({
displayName: 'Parent Comment ID',
description:
'Optional. The ID of a parent comment to create a threaded reply.',
required: false,
}),
},
async run(context) {
const { auth: personalToken, propsValue } = context;
const { base: baseId, tableId, recordId, text, parentCommentId } =
propsValue;
return await airtableCommon.addCommentToRecord({
personalToken: personalToken.secret_text,
baseId: baseId as string,
tableId: tableId as string,
recordId: recordId as string,
text: text,
parentCommentId: parentCommentId,
});
},
});

View File

@@ -0,0 +1,58 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { airtableAuth } from '../../index';
import { airtableCommon } from '../common';
import { AirtableTableConfig } from '../common/models';
export const airtableCreateBaseAction = createAction({
auth: airtableAuth,
name: 'airtable_create_base',
displayName: 'Create Base',
description: 'Create a new base with a specified table structure.',
props: {
workspaceId: airtableCommon.workspaceId,
name: Property.ShortText({
displayName: 'Base Name',
description: 'The name for the new base.',
required: true,
}),
tables: Property.Json({
displayName: 'Tables',
description:
'Define the tables for the new base. Use the default value as a template. The first field for each table will be its primary field.',
required: true,
defaultValue: [
{
name: 'My First Table',
fields: [
{
name: 'Name',
type: 'singleLineText',
},
{
name: 'Status',
type: 'singleSelect',
options: {
choices: [
{ name: 'Todo' },
{ name: 'In Progress' },
{ name: 'Done' },
],
},
},
],
},
],
}),
},
async run(context) {
const { auth: personalToken, propsValue } = context;
const { workspaceId, name, tables } = propsValue;
return await airtableCommon.createBase({
personalToken: personalToken.secret_text,
workspaceId: workspaceId as string,
name: name as string,
tables: tables as unknown as AirtableTableConfig[],
});
},
});

View File

@@ -0,0 +1,43 @@
import {
DynamicPropsValue,
createAction,
} from '@activepieces/pieces-framework';
import { airtableCommon } from '../common';
import { airtableAuth } from '../../index';
export const airtableCreateRecordAction = createAction({
auth: airtableAuth,
name: 'airtable_create_record',
displayName: 'Create Airtable Record',
description: 'Adds a record into an airtable',
props: {
base: airtableCommon.base,
tableId: airtableCommon.tableId,
fields: airtableCommon.fields,
},
async run(context) {
const personalToken = context.auth;
const { base: baseId, tableId, fields } = context.propsValue;
const fieldsWithoutEmptyStrings: DynamicPropsValue = {};
Object.keys(fields).forEach((k) => {
if (fields[k] !== '') {
fieldsWithoutEmptyStrings[k] = fields[k];
}
});
const newFields: Record<string, unknown> =
await airtableCommon.createNewFields(
personalToken.secret_text,
baseId,
tableId as string,
fieldsWithoutEmptyStrings
);
return airtableCommon.createRecord({
personalToken: personalToken.secret_text,
baseId,
tableId: tableId as string,
fields: newFields,
});
},
});

View File

@@ -0,0 +1,53 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { airtableAuth } from '../../index';
import { airtableCommon } from '../common';
import { AirtableFieldConfig } from '../common/models';
export const airtableCreateTableAction = createAction({
auth: airtableAuth,
name: 'airtable_create_table',
displayName: 'Create Table',
description: 'Create a new table in an existing base.',
props: {
base: airtableCommon.base,
name: Property.ShortText({
displayName: 'Table Name',
description: 'The name for the new table.',
required: true,
}),
description: Property.LongText({
displayName: 'Description',
description: 'An optional description for the new table.',
required: false,
}),
fields: Property.Json({
displayName: 'Fields',
description:
'A JSON array of fields for the new table. The first field in the array will become the primary field.',
required: true,
defaultValue: [
{
name: 'Name',
type: 'singleLineText',
description: 'This will be the primary field',
},
{
name: 'Notes',
type: 'multilineText',
},
],
}),
},
async run(context) {
const { auth: personalToken, propsValue } = context;
const { base: baseId, name, description, fields } = propsValue;
return await airtableCommon.createTable({
personalToken: personalToken.secret_text,
baseId: baseId as string,
name: name as string,
description: description as string | undefined,
fields: fields as unknown as AirtableFieldConfig[],
});
},
});

View File

@@ -0,0 +1,26 @@
import { createAction } from '@activepieces/pieces-framework';
import { airtableCommon } from '../common';
import { airtableAuth } from '../../index';
export const airtableDeleteRecordAction = createAction({
auth: airtableAuth,
name: 'airtable_delete_record',
displayName: 'Delete Airtable Record',
description: 'Deletes a record in airtable',
props: {
base: airtableCommon.base,
tableId: airtableCommon.tableId,
recordId: airtableCommon.recordId,
},
async run(context) {
const personalToken = context.auth;
const { base: baseId, tableId, recordId } = context.propsValue;
return await airtableCommon.deleteRecord({
personalToken: personalToken.secret_text,
baseId: baseId as string,
tableId: tableId as string,
recordId: recordId as string,
});
},
});

View File

@@ -0,0 +1,35 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { airtableAuth } from '../../index';
import { airtableCommon } from '../common';
import { AirtableBase } from '../common/models';
export const airtableFindBaseAction = createAction({
auth: airtableAuth,
name: 'airtable_find_base',
displayName: 'Find Base',
description: 'Find a base by its name or a keyword.',
props: {
baseName: Property.ShortText({
displayName: 'Base Name or Keyword',
description: 'The name or keyword to search for within your base names.',
required: true,
}),
},
async run(context) {
const { auth: personalToken, propsValue } = context;
const { baseName } = propsValue;
const allBases: AirtableBase[] = await airtableCommon.fetchAllBases({
token: personalToken.secret_text,
});
const searchTerm = (baseName as string).toLowerCase();
const foundBases = allBases.filter((base) =>
base.name.toLowerCase().includes(searchTerm)
);
return foundBases;
},
});

View File

@@ -0,0 +1,26 @@
import { createAction } from '@activepieces/pieces-framework';
import { airtableAuth } from '../../index';
import { airtableCommon } from '../common';
export const airtableGetRecordByIdAction = createAction({
auth: airtableAuth,
name: 'airtable_get_record_by_id',
displayName: 'Get Record by ID',
description: 'Retrieve a single record from a table by its unique ID.',
props: {
base: airtableCommon.base,
tableId: airtableCommon.tableId,
recordId: airtableCommon.recordIdDropdown,
},
async run(context) {
const { auth: personalToken, propsValue } = context;
const { base: baseId, tableId, recordId } = propsValue;
return await airtableCommon.getRecordById({
personalToken: personalToken.secret_text,
baseId: baseId as string,
tableId: tableId as string,
recordId: recordId as string,
});
},
});

View File

@@ -0,0 +1,40 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { airtableCommon } from '../common';
import { airtableAuth } from '../../index';
export const airtableFindRecordAction = createAction({
auth: airtableAuth,
name: 'airtable_find_record',
displayName: 'Find Airtable Record',
description: 'Find a record in airtable',
props: {
base: airtableCommon.base,
tableId: airtableCommon.tableId,
searchField: airtableCommon.fieldNames,
searchValue: Property.ShortText({
displayName: 'Search Value',
required: true,
}),
limitToView: airtableCommon.views,
},
async run(context) {
const personalToken = context.auth;
const {
base: baseId,
tableId,
searchField,
searchValue,
limitToView,
} = context.propsValue;
return await airtableCommon.findRecord({
personalToken: personalToken.secret_text,
baseId: baseId as string,
tableId: tableId as string,
searchField: searchField as string,
searchValue: searchValue as string,
limitToView: limitToView as string,
});
},
});

View File

@@ -0,0 +1,23 @@
import { createAction } from '@activepieces/pieces-framework';
import { airtableAuth } from '../../index';
import { airtableCommon } from '../common';
export const airtableFindTableByIdAction = createAction({
auth: airtableAuth,
name: 'airtable_find_table_by_id',
displayName: 'Find Table by ID',
description: "Get a table's details and schema using its ID.",
props: {
base: airtableCommon.base,
tableId: airtableCommon.tableId,
},
async run(context) {
const { auth: personalToken, propsValue } = context;
const { base: baseId, tableId } = propsValue;
return await airtableCommon.fetchTable({
token: personalToken.secret_text,
baseId: baseId as string,
tableId: tableId as string,
});
},
});

View File

@@ -0,0 +1,36 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { airtableAuth } from '../../index';
import { airtableCommon } from '../common';
import { AirtableTable } from '../common/models';
export const airtableFindTableAction = createAction({
auth: airtableAuth,
name: 'airtable_find_table',
displayName: 'Find Table',
description: 'Find a table in a given base by its name.',
props: {
base: airtableCommon.base,
tableName: Property.ShortText({
displayName: 'Table Name',
description: 'The exact name of the table you want to find.',
required: true,
}),
},
async run(context) {
const { auth: personalToken, propsValue } = context;
const { base: baseId, tableName } = propsValue;
const tables: AirtableTable[] = await airtableCommon.fetchTableList({
token: personalToken.secret_text,
baseId: baseId as string,
});
const foundTable = tables.find(
(table) =>
table.name.toLowerCase() === (tableName as string).toLowerCase()
);
return foundTable ?? null;
},
});

View File

@@ -0,0 +1,23 @@
import { createAction } from '@activepieces/pieces-framework';
import { airtableAuth } from '../../index';
import { airtableCommon } from '../common';
export const airtableGetBaseSchemaAction = createAction({
auth: airtableAuth,
name: 'airtable_get_base_schema',
displayName: 'Get Base Schema',
description:
'Retrieve the schema for a specific base, including all its tables and fields.',
props: {
base: airtableCommon.base,
},
async run(context) {
const { auth: personalToken, propsValue } = context;
const { base: baseId } = propsValue;
return await airtableCommon.fetchTableList({
token: personalToken.secret_text,
baseId: baseId as string,
});
},
});

View File

@@ -0,0 +1,48 @@
import {
createAction,
DynamicPropsValue,
Property,
} from '@activepieces/pieces-framework';
import { airtableCommon } from '../common';
import { airtableAuth } from '../../index';
export const airtableUpdateRecordAction = createAction({
auth: airtableAuth,
name: 'airtable_update_record',
displayName: 'Update Airtable Record',
description: 'Update a record in airtable',
props: {
base: airtableCommon.base,
tableId: airtableCommon.tableId,
recordId: airtableCommon.recordId,
fields: airtableCommon.fields,
},
async run(context) {
const personalToken = context.auth;
const { base: baseId, tableId, recordId, fields } = context.propsValue;
const fieldsWithoutEmptyStrings: DynamicPropsValue = {};
Object.keys(fields).forEach((k) => {
if (fields[k] !== '') {
fieldsWithoutEmptyStrings[k] = fields[k];
}
});
const updatedFields: Record<string, unknown> =
await airtableCommon.createNewFields(
personalToken.secret_text,
baseId,
tableId as string,
fieldsWithoutEmptyStrings
);
return await airtableCommon.updateRecord({
personalToken: personalToken.secret_text,
baseId: baseId as string,
tableId: tableId as string,
recordId: recordId as string,
fields: updatedFields as Record<string, unknown>,
});
},
});

View File

@@ -0,0 +1,103 @@
import { airtableAuth } from '../..';
import { createAction, Property } from '@activepieces/pieces-framework';
import { airtableCommon } from '../common';
import { AirtableTable } from './../common/models';
import {
AuthenticationType,
httpClient,
HttpMethod,
HttpRequest,
} from '@activepieces/pieces-common';
export const airtableUploadFileToColumnAction = createAction({
auth: airtableAuth,
name: 'airtable_upload_file_to_column',
displayName: 'Upload File to Column',
description: 'Uploads a file to attachment type column.',
props: {
base: airtableCommon.base,
tableId: airtableCommon.tableId,
attachment_column: Property.Dropdown({
auth: airtableAuth,
displayName: 'Attachment Column',
required: true,
refreshers: ['base', 'tableId'],
options: async ({ auth, base, tableId }) => {
if (!auth || !base || !tableId) {
return {
placeholder: 'Please select table first',
options: [],
disabled: true,
};
}
const airtable: AirtableTable = await airtableCommon.fetchTable({
token: auth as unknown as string,
baseId: base as unknown as string,
tableId: tableId as unknown as string,
});
return {
disabled: false,
options: airtable.fields
.filter((field) => field.type === 'multipleAttachments')
.map((field) => {
return {
label: field.name,
value: field.id,
};
}),
};
},
}),
recordId: Property.ShortText({
displayName: 'Record ID',
required: true,
description: 'The ID of the record to which you want to upload the file.',
}),
file: Property.File({
displayName: 'File',
required: true,
description:
'The file to be uploaded, which can be provided either as a public file URL or in Base64 encoded format.',
}),
file_content_type: Property.ShortText({
displayName: 'File Content Type',
required: true,
description: `Specifies the MIME type of the file being uploaded (e.g., 'image/png', 'application/pdf').`,
}),
filename: Property.ShortText({
displayName: 'File Name',
description: 'The name of the file as it should appear after upload.',
required: false,
}),
},
async run(context) {
const baseId = context.propsValue.base;
const recordId = context.propsValue.recordId;
const fieldId = context.propsValue.attachment_column;
const fileInput = context.propsValue.file;
const fileName = context.propsValue.filename ?? fileInput.filename;
const fileBase64Data = fileInput.base64;
const fileContentType = context.propsValue.file_content_type;
const request: HttpRequest = {
method: HttpMethod.POST,
url: `https://content.airtable.com/v0/${baseId}/${recordId}/${fieldId}/uploadAttachment`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: context.auth.secret_text,
},
body: {
contentType: fileContentType,
file: fileBase64Data,
filename: fileName,
},
};
const response = await httpClient.sendRequest(request);
return response.body;
},
});

View File

@@ -0,0 +1,829 @@
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import {
DropdownState,
DynamicPropsValue,
Property,
} from '@activepieces/pieces-framework';
import Airtable from 'airtable';
import {
AirtableBase,
AirtableComment,
AirtableCreateBaseResponse,
AirtableTableConfig,
AirtableFieldConfig,
AirtableEnterpriseFields,
AirtableField,
AirtableFieldMapping,
AirtableRecord,
AirtableTable,
AirtableView,
} from './models';
import { isNil } from '@activepieces/shared';
import { airtableAuth } from '../..';
interface Params {
personalToken: string;
baseId: string;
tableId: string;
fields?: Record<string, unknown>;
recordId?: string;
searchValue?: string;
searchField?: string;
fieldNames?: string[];
limitToView?: string;
sortField?: string;
text?: string;
parentCommentId?: string;
workspaceId?: string;
name?: string;
tables?: AirtableTableConfig[];
}
async function fetchAllBases({
token,
}: {
token: string;
}): Promise<AirtableBase[]> {
const allBases: AirtableBase[] = [];
let offset: string | undefined = undefined;
do {
const request: HttpRequest = {
method: HttpMethod.GET,
url: 'https://api.airtable.com/v0/meta/bases',
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
queryParams: offset ? { offset } : {},
};
const response = await httpClient.sendRequest<{
bases: AirtableBase[];
offset?: string;
}>(request);
if (response.status === 200) {
allBases.push(...response.body.bases);
offset = response.body.offset;
} else {
offset = undefined;
}
} while (offset);
return allBases;
}
async function fetchBase({
token,
baseId,
}: {
token: string;
baseId: string;
}): Promise<AirtableBase> {
const request: HttpRequest = {
method: HttpMethod.GET,
url: `https://api.airtable.com/v0/meta/bases/${baseId}`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
};
const response = await httpClient.sendRequest<AirtableBase>(request);
return response.body;
}
async function listRecords({
token,
baseId,
tableId,
pageSize = 50,
}: {
token: string;
baseId: string;
tableId: string;
pageSize?: number;
}): Promise<AirtableRecord[]> {
const response = await httpClient.sendRequest<{ records: AirtableRecord[] }>({
method: HttpMethod.GET,
url: `https://api.airtable.com/v0/${baseId}/${tableId}`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
queryParams: {
pageSize: pageSize.toString(),
},
});
if (response.status === 200) {
return response.body.records;
}
return [];
}
async function fetchTableList({
token,
baseId,
}: {
token: string;
baseId: string;
}): Promise<AirtableTable[]> {
const response = await httpClient.sendRequest<{ tables: AirtableTable[] }>({
method: HttpMethod.GET,
url: `https://api.airtable.com/v0/meta/bases/${baseId}/tables`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
});
if (response.status === 200) {
return response.body.tables;
}
return [];
}
async function fetchTable({
token,
baseId,
tableId,
}: {
token: string;
baseId: string;
tableId: string;
}): Promise<AirtableTable> {
const tables = await fetchTableList({ token, baseId });
return tables.find((t) => t.id === tableId)!;
}
async function fetchViews({
token,
baseId,
tableId,
}: {
token: string;
baseId: string;
tableId: string;
}): Promise<AirtableView[]> {
const table = await fetchTable({ token, baseId, tableId });
if (table) {
return table.views;
}
return [];
}
async function createRecord({
personalToken: token,
fields,
tableId,
baseId,
}: Params) {
const request: HttpRequest = {
method: HttpMethod.POST,
url: `https://api.airtable.com/v0/${baseId}/${tableId}`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
body: {
fields,
typecast: true,
},
};
const response = await httpClient.sendRequest<AirtableRecord>(request);
if (response.status === 200) {
return response.body;
}
return response;
}
async function findRecord({
personalToken: token,
searchField,
searchValue,
tableId,
baseId,
limitToView,
}: Params) {
const request: HttpRequest = {
method: HttpMethod.GET,
url: `https://api.airtable.com/v0/${baseId}/${tableId}`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
queryParams: {
filterByFormula: `FIND("${searchValue}",{${searchField}})`,
view: limitToView ?? '',
},
};
const response = await httpClient.sendRequest<{
records: AirtableRecord[];
}>(request);
if (response.status === 200) {
return response.body.records;
}
return [];
}
async function updateRecord({
personalToken: token,
fields,
recordId,
tableId,
baseId,
}: Params) {
const request: HttpRequest = {
method: HttpMethod.PATCH,
url: `https://api.airtable.com/v0/${baseId}/${tableId}/${recordId}`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
body: {
fields,
},
};
const response = await httpClient.sendRequest<AirtableRecord>(request);
if (response.status === 200) {
return response.body;
}
return response;
}
async function deleteRecord({
personalToken: token,
recordId,
tableId,
baseId,
}: Params) {
const request: HttpRequest = {
method: HttpMethod.DELETE,
url: `https://api.airtable.com/v0/${baseId}/${tableId}/${recordId}`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
};
const response = await httpClient.sendRequest<AirtableRecord>(request);
if (response.status === 200) {
return response.body;
}
return response;
}
async function getRecordById({
personalToken: token,
baseId,
tableId,
recordId,
}: Params) {
const request: HttpRequest = {
method: HttpMethod.GET,
url: `https://api.airtable.com/v0/${baseId}/${tableId}/${recordId}`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
};
const response = await httpClient.sendRequest<AirtableRecord>(request);
if (response.status === 200) {
return response.body;
}
return response;
}
async function addCommentToRecord({
personalToken: token,
baseId,
tableId,
recordId,
text,
parentCommentId,
}: Params) {
const body: { text: string; parentCommentId?: string } = {
text: text as string,
};
if (parentCommentId) {
body.parentCommentId = parentCommentId;
}
const request: HttpRequest = {
method: HttpMethod.POST,
url: `https://api.airtable.com/v0/${baseId}/${tableId}/${recordId}/comments`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
body: body,
};
const response = await httpClient.sendRequest<AirtableComment>(request);
if (response.status === 200 || response.status === 201) {
return response.body;
}
return response;
}
async function createBase({
personalToken: token,
workspaceId,
name,
tables,
}: {
personalToken: string;
workspaceId: string;
name: string;
tables: AirtableTableConfig[];
}) {
const request: HttpRequest = {
method: HttpMethod.POST,
url: `https://api.airtable.com/v0/meta/bases`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
body: {
name,
workspaceId,
tables,
},
};
const response =
await httpClient.sendRequest<AirtableCreateBaseResponse>(request);
if (response.status === 200 || response.status === 201) {
return response.body;
}
return response;
}
async function createTable({
personalToken: token,
baseId,
name,
description,
fields,
}: {
personalToken: string;
baseId: string;
name: string;
description?: string;
fields: AirtableFieldConfig[];
}) {
const body: {
name: string;
description?: string;
fields: AirtableFieldConfig[];
} = { name, fields };
if (description) {
body.description = description;
}
const request: HttpRequest = {
method: HttpMethod.POST,
url: `https://api.airtable.com/v0/meta/bases/${baseId}/tables`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
body: body,
};
const response = await httpClient.sendRequest<AirtableTable>(request);
if (response.status === 200 || response.status === 201) {
return response.body;
}
return response;
}
export const airtableCommon = {
base: Property.Dropdown<string,true,typeof airtableAuth>({
auth: airtableAuth,
displayName: 'Base',
required: true,
refreshers: [],
options: async ({ auth }): Promise<DropdownState<string>> => {
if (!auth) {
return {
disabled: true,
options: [],
placeholder: 'Please connect your account',
};
}
try {
const bases: AirtableBase[] = await fetchAllBases({
token: auth.secret_text,
});
return {
disabled: false,
options: bases.map((base: AirtableBase) => {
return { value: base.id, label: base.name };
}),
};
} catch (e) {
console.debug(e);
return {
disabled: true,
options: [],
placeholder: 'Please check your permission scope',
};
}
},
}),
workspaceId: Property.Dropdown<string,true,typeof airtableAuth>({
auth: airtableAuth,
displayName: 'Workspace',
required: true,
refreshers: [],
options: async ({ auth }) => {
if (!auth) {
return {
disabled: true,
options: [],
placeholder: 'Please connect your account',
};
}
// Although there is no direct way to get a list of workspaces,
// we can get a list of bases and then fetch each base to get the workspace id.
const bases = await fetchAllBases({
token: auth.secret_text,
});
const workspacePromises = bases.map((base) =>
fetchBase({ token: auth.secret_text, baseId: base.id })
);
const basesWithWorkspaces = await Promise.all(workspacePromises);
const workspaces = basesWithWorkspaces.reduce((acc, base) => {
if (base.workspaceId) {
// Since we don't have the workspace name, we will use the ID as the name.
acc[base.workspaceId] = base.workspaceId;
}
return acc;
}, {} as Record<string, string>);
return {
disabled: false,
options: Object.entries(workspaces).map(([id, name]) => ({
label: name,
value: id,
})),
};
},
}),
tableId: Property.Dropdown<string,true,typeof airtableAuth>({
auth: airtableAuth,
displayName: 'Table',
required: true,
refreshers: ['base'],
options: async ({ auth, base }): Promise<DropdownState<string>> => {
if (!auth) {
return {
disabled: true,
options: [],
placeholder: 'Please connect your account',
};
}
if (!base) {
return {
disabled: true,
options: [],
placeholder: 'Please select a base first',
};
}
try {
const tables: AirtableTable[] = await fetchTableList({
token: auth.secret_text,
baseId: base as string,
});
return {
disabled: false,
options: tables.map((table) => ({
value: table.id,
label: table.name,
})),
};
} catch (e) {
console.debug(e);
return {
disabled: true,
options: [],
placeholder: 'Please check your permission scope',
};
}
},
}),
views: Property.Dropdown<string,false,typeof airtableAuth>({
auth: airtableAuth,
displayName: 'View',
required: false,
refreshers: ['base', 'tableId'],
options: async ({ auth, base, tableId }): Promise<DropdownState<string>> => {
if (!auth) {
return {
disabled: true,
options: [],
placeholder: 'Please connect your account',
};
}
if (!base) {
return {
disabled: true,
options: [],
placeholder: 'Please select a base first',
};
}
if (!tableId) {
return {
disabled: true,
options: [],
placeholder: 'Please select a table first',
};
}
const views: AirtableView[] = await fetchViews({
token: auth.secret_text,
baseId: base as string,
tableId: tableId as string,
});
return {
disabled: false,
options: views.map((view) => ({
value: view.id,
label: view.name,
})),
};
},
}),
recordId: Property.ShortText({
displayName: 'Record ID',
required: true,
description: 'The ID of the record.',
}),
fields: Property.DynamicProperties({
auth: airtableAuth,
displayName: 'Table',
required: true,
refreshers: ['base', 'tableId'],
props: async ({ auth, base, tableId }) => {
if (!auth) return {};
if (!base) return {};
if (!tableId) return {};
const airtable: AirtableTable = await fetchTable({
token: auth as unknown as string,
baseId: base as unknown as string,
tableId: tableId as unknown as string,
});
const fields = airtable.fields.reduce((acc, field) => {
if (!AirtableEnterpriseFields.includes(field.type)) {
const params = {
displayName: field.name,
description: ['date', 'dateTime'].includes(field.type)
? `${
field.description ? field.description : ''
}Expected format: mmmm d,yyyy`
: field.description,
required: false,
};
if (isNil(AirtableFieldMapping[field.type])) {
acc[field.id] = Property.ShortText({
...params,
});
} else if (
field.type === 'singleSelect' ||
field.type === 'multipleSelects'
) {
const options = field.options?.choices.map(
(option: { id: string; name: string }) => ({
value: option.id,
label: option.name,
})
);
acc[field.id] = AirtableFieldMapping[field.type]({
...params,
options: {
options: options ?? [],
},
});
} else {
acc[field.id] = AirtableFieldMapping[field.type](params);
}
}
return acc;
}, {} as DynamicPropsValue);
return fields;
},
}),
recordIdDropdown: Property.Dropdown<string,true,typeof airtableAuth>({
auth: airtableAuth,
displayName: 'Record',
required: true,
refreshers: ['base', 'tableId'],
options: async ({ auth, base, tableId }) => {
if (!auth || !base || !tableId) {
return {
disabled: true,
options: [],
placeholder: 'Please select a base and table first',
};
}
const table = await fetchTable({
token: auth.secret_text,
baseId: base as string,
tableId: tableId as string,
});
const primaryField = table.fields.find(
(f) => f.id === table.primaryFieldId
);
const primaryFieldName = primaryField?.name;
const records = await listRecords({
token: auth.secret_text,
baseId: base as string,
tableId: tableId as string,
});
const options = records.map((record) => {
let label = record.id;
if (primaryFieldName && record.fields[primaryFieldName]) {
label = record.fields[primaryFieldName] as string;
}
return {
label: label,
value: record.id,
};
});
return {
disabled: false,
options: options,
};
},
}),
fieldNames: Property.Dropdown({
auth: airtableAuth,
displayName: 'Search Field',
required: true,
refreshers: ['base', 'tableId'],
options: async ({ auth, base, tableId }): Promise<DropdownState<string>> => {
if (!auth) {
return {
disabled: true,
options: [],
placeholder: 'Please connect your account',
};
}
if (!base) {
return {
disabled: true,
options: [],
placeholder: 'Please select a base first',
};
}
if (!tableId) {
return {
disabled: true,
options: [],
placeholder: 'Please select a table first',
};
}
const airtable: AirtableTable = await fetchTable({
token: auth.secret_text,
baseId: base as string,
tableId: tableId as string,
});
return {
disabled: false,
options: airtable.fields.map((field: AirtableField) => ({
label: field.name,
value: field.name,
})),
};
},
}),
createNewFields: async (
auth: string,
base: string,
tableId: string,
fields: Record<string, unknown>
) => {
if (!auth) return fields;
if (!base) return fields;
if (!tableId) return fields;
const newFields: Record<string, unknown> = {};
const airtable: AirtableTable = await fetchTable({
token: auth,
baseId: base,
tableId: tableId,
});
airtable.fields.forEach((field) => {
if (!AirtableEnterpriseFields.includes(field.type)) {
const key = field.id;
if (field.type === 'multipleAttachments' && fields[key]) {
newFields[key] = [
{
url: fields[key] as string,
},
];
} else if (
['multipleRecordLinks', 'multipleSelects'].includes(field.type)
) {
if (Array.isArray(fields[key]) && (fields[key] as any[]).length > 0) {
newFields[key] = fields[key];
}
} else {
newFields[key] = fields[key];
}
}
});
return newFields;
},
getTableSnapshot: async (params: Params) => {
Airtable.configure({
apiKey: params.personalToken,
});
const airtable = new Airtable();
const currentTableSnapshot = (
await airtable
.base(params.baseId)
.table(params.tableId)
.select(params.limitToView ? { view: params.limitToView } : {})
.all()
)
.map((r: any) => r._rawJson)
.sort(
(x: any, y: any) =>
new Date(x.createdTime).getTime() - new Date(y.createdTime).getTime()
);
return currentTableSnapshot;
},
createRecord,
findRecord,
updateRecord,
deleteRecord,
getRecordById,
fetchAllBases,
fetchTableList,
fetchTable,
fetchViews,
addCommentToRecord,
createBase,
createTable,
listRecords,
fetchBase,
};

View File

@@ -0,0 +1,179 @@
import { Property } from '@activepieces/pieces-framework';
export interface AirtableBase {
id: string;
name: string;
permissionLevel: AirtablePermissionLevel;
workspaceId?: string;
}
export interface AirtableRecord {
fields: Record<string, unknown>;
createdTime: Date;
id: string;
}
export interface AirtableField {
id: string;
name: string;
description: string;
type: AirtableFieldType;
options?: {
choices: AirtableChoice[];
};
}
export interface AirtableChoice {
id: string;
name: string;
color: string;
}
export interface AirtableTable {
id: string;
name: string;
fields: AirtableField[];
description: string;
primaryFieldId: string;
views: {
id: string;
name: string;
type: string;
}[];
}
export interface AirtableView {
id: string;
name: string;
}
export interface AirtableCreateRecordBody {
records?: AirtableRecord[];
fields?: Record<string, unknown>;
}
declare type AirtablePermissionLevel =
| 'none'
| 'read'
| 'comment'
| 'edit'
| 'create';
export type AirtableFieldType =
| 'singleLineText'
| 'email'
| 'url'
| 'multilineText'
| 'number'
| 'percent'
| 'currency'
| 'singleSelect'
| 'multipleSelects'
| 'multipleRecordLinks'
| 'date'
| 'dateTime'
| 'phoneNumber'
| 'multipleAttachments'
| 'checkbox'
| 'formula'
| 'createdTime'
| 'rollup'
| 'count'
| 'lookup'
| 'multipleLookupValues'
| 'autoNumber'
| 'barcode'
| 'rating'
| 'richText'
| 'duration'
| 'lastModifiedTime'
| 'button'
| 'createdBy'
| 'lastModifiedBy'
| 'externalSyncSource';
export const AirtableEnterpriseFields = [
'singleCollaborator',
'multipleCollaborators',
'aiText',
];
export interface AirtableComment {
id: string;
createdTime: string;
lastUpdatedTime: string | null;
text: string;
parentCommentId?: string;
author: {
id: string;
email: string;
name?: string;
};
mentioned?: Record<
string,
{
id: string;
type: 'user' | 'userGroup';
displayName: string;
email?: string;
}
>;
reactions?: Array<{
emoji: {
unicodeCharacter: string;
};
reactingUser: {
userId: string;
email: string;
name?: string;
};
}>;
}
export interface AirtableFieldConfig {
name: string;
description?: string;
type: AirtableFieldType;
options?: any;
}
export interface AirtableTableConfig {
name: string;
description?: string;
fields: AirtableFieldConfig[];
}
export interface AirtableCreateBaseResponse {
id: string;
tables: AirtableTable[];
}
export const AirtableFieldMapping = {
singleLineText: Property.ShortText,
email: Property.ShortText,
url: Property.ShortText,
multilineText: Property.LongText,
number: Property.Number,
percent: Property.ShortText,
currency: Property.ShortText,
singleSelect: Property.StaticDropdown,
multipleSelects: Property.StaticMultiSelectDropdown,
multipleRecordLinks: Property.Array,
date: Property.ShortText,
dateTime: Property.ShortText,
phoneNumber: Property.ShortText,
multipleAttachments: Property.ShortText,
checkbox: Property.Checkbox,
formula: Property.ShortText,
createdTime: Property.ShortText,
rollup: Property.ShortText,
count: Property.ShortText,
lookup: Property.ShortText,
multipleLookupValues: Property.ShortText,
autoNumber: Property.Number,
barcode: Property.ShortText,
rating: Property.ShortText,
richText: Property.ShortText,
duration: Property.ShortText,
lastModifiedTime: Property.ShortText,
button: Property.ShortText,
createdBy: Property.ShortText,
lastModifiedBy: Property.ShortText,
externalSyncSource: Property.ShortText,
};

View File

@@ -0,0 +1,59 @@
import {
DedupeStrategy,
Polling,
pollingHelper,
} from '@activepieces/pieces-common';
import {
AppConnectionValueForAuthProperty,
StaticPropsValue,
TriggerStrategy,
createTrigger,
} from '@activepieces/pieces-framework';
import { airtableAuth } from '../../';
import { airtableCommon } from '../common';
const props = {
base: airtableCommon.base,
tableId: airtableCommon.tableId,
viewId: airtableCommon.views,
};
const polling: Polling<AppConnectionValueForAuthProperty<typeof airtableAuth>, StaticPropsValue<typeof props>> = {
strategy: DedupeStrategy.TIMEBASED,
items: async ({ auth, propsValue }) => {
const records = await airtableCommon.getTableSnapshot({
personalToken: auth.secret_text,
baseId: propsValue.base,
tableId: propsValue.tableId!,
limitToView: propsValue.viewId,
});
return records.map((record) => ({
epochMilliSeconds: Date.parse(record.createdTime),
data: record,
}));
},
};
export const airtableNewRecordTrigger = createTrigger({
auth: airtableAuth,
name: 'new_record',
displayName: 'New Record',
description: 'Triggers when a new record is added to the selected table.',
props,
sampleData: {},
type: TriggerStrategy.POLLING,
async test(context) {
return await pollingHelper.test(polling, context);
},
async onEnable(context) {
await pollingHelper.onEnable(polling, context);
},
async onDisable(context) {
await pollingHelper.onDisable(polling, context);
},
async run(context) {
return await pollingHelper.poll(polling, context);
},
});

View File

@@ -0,0 +1,127 @@
import {
DedupeStrategy,
Polling,
pollingHelper,
} from '@activepieces/pieces-common';
import {
AppConnectionValueForAuthProperty,
Property,
StaticPropsValue,
TriggerStrategy,
createTrigger,
} from '@activepieces/pieces-framework';
import Airtable from 'airtable';
import dayjs from 'dayjs';
import { airtableAuth } from '../../';
import { airtableCommon } from '../common';
import { AirtableField, AirtableTable } from '../common/models';
const props = {
base: airtableCommon.base,
tableId: airtableCommon.tableId,
sortFields: Property.Dropdown({
auth: airtableAuth,
displayName: 'Trigger field',
description: `**Last Modified Time** field will be used to watch new or updated records.Please create **Last Modified Time** field in your schema,if you don't have any timestamp field.`,
required: true,
refreshers: ['base', 'tableId'],
options: async ({ auth, base, tableId }) => {
if (!auth) {
return {
disabled: true,
options: [],
placeholder: 'Please connect your account',
};
}
if (!base) {
return {
disabled: true,
options: [],
placeholder: 'Please select a base first',
};
}
if (!tableId) {
return {
disabled: true,
options: [],
placeholder: 'Please select a table first',
};
}
const airtable: AirtableTable = await airtableCommon.fetchTable({
token: auth as unknown as string,
baseId: base as unknown as string,
tableId: tableId as unknown as string,
});
return {
disabled: false,
options: airtable.fields
.filter((field: AirtableField) => field.type == 'lastModifiedTime')
.map((field: AirtableField) => ({
label: field.name,
value: field.name,
})),
};
},
}),
viewId: airtableCommon.views,
};
const polling: Polling<AppConnectionValueForAuthProperty<typeof airtableAuth>, StaticPropsValue<typeof props>> = {
strategy: DedupeStrategy.TIMEBASED,
items: async ({ auth, propsValue, lastFetchEpochMS }) => {
Airtable.configure({
apiKey: auth.secret_text,
});
const airtable = new Airtable();
const lastUpdateDate =
lastFetchEpochMS === 0
? dayjs().subtract(1, 'day').toISOString()
: dayjs(lastFetchEpochMS).toISOString();
const records = await airtable
.base(propsValue.base)
.table(propsValue.tableId!)
.select({
filterByFormula: `IS_AFTER({${
propsValue.sortFields as string
}},DATETIME_PARSE("${lastUpdateDate}","YYYY-MM-DD HH:mm:ss.SSS"))`,
view: propsValue.viewId ?? '',
})
.all();
return records.map((item) => {
return {
epochMilliSeconds: dayjs(
item.fields[propsValue.sortFields] as string
).valueOf(),
data: item._rawJson,
};
});
},
};
export const airtableUpdatedRecordTrigger = createTrigger({
auth: airtableAuth,
name: 'updated_record',
displayName: 'New or Updated Record',
description:
'Triggers when a record is created or updated in selected table.',
props,
sampleData: {},
type: TriggerStrategy.POLLING,
async test(context) {
return await pollingHelper.test(polling, context);
},
async onEnable(context) {
await pollingHelper.onEnable(polling, context);
},
async onDisable(context) {
await pollingHelper.onDisable(polling, context);
},
async run(context) {
return await pollingHelper.poll(polling, context);
},
});