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,30 @@
{
"Project ID": "Projekt-ID",
"Datasource ID": "Datenquellen-ID",
"API Key": "API-Schlüssel",
"Your Instasent Project ID": "Ihre Instasent Project ID",
"Your Instasent Datasource ID": "Ihre Instasent Datasource-ID",
"Your Instasent API Bearer Token": "Dein Instasent API Bären-Token",
"\n## Obtain your auth data\n1. Go to https://dashboard.instasent.com\n2. Access to your project\n3. Create an Activepieces data source\n4. Copy the auth parameters and paste them in the fields below\n": "\n## Erhalte deine Authentifizierungsdaten\n1. Gehe zu https://dashboard.instasent.com\n2. Zugriff auf dein Projekt\n3. Erstellen Sie eine Activepieces Datenquelle\n4. Kopieren Sie die Auth Parameter und fügen Sie sie in die Felder unten\n ein",
"Add/Update contact": "Kontakt hinzufügen/aktualisieren",
"Delete Contact": "Kontakt löschen",
"Add Event": "Neuer Termin",
"Add or update a single contact": "Einen einzigen Kontakt hinzufügen oder aktualisieren",
"Delete a single contact by User ID": "Lösche einen einzigen Kontakt durch Benutzer-ID",
"Add a contact event": "Kontaktereignis hinzufügen",
"Contact Properties": "Kontakteigenschaften",
"Instant": "Sofort",
"User ID": "Benutzer-ID",
"Event ID": "Event-ID",
"Event Date": "Event-Datum",
"Event Type": "Ereignistyp",
"Event Parameters": "Ereignisparameter",
"Enter the contact properties, the User ID is mandatory": "Geben Sie die Kontakteigenschaften ein, die Benutzer-ID ist obligatorisch",
"Process contact immediately instead of queuing. Only enable this when you need to add an event for this contact in the next step. Not recommended for high-volume operations.": "Kontakt sofort statt Warteschlange verarbeiten. Aktivieren Sie dies nur, wenn Sie im nächsten Schritt ein Ereignis für diesen Kontakt hinzufügen müssen. Nicht empfohlen für großvolumige Operationen.",
"Unique identifier of the contact to delete": "Eindeutige Kennung des zu löschenden Kontakts",
"Unique identifier of the user": "Eindeutige Kennung des Benutzers",
"Unique identifier for this event. Used for deduplication.": "Eindeutiger Bezeichner für dieses Ereignis. Wird zur Dekopilierung verwendet.",
"Date and time when the event occurred, will default to now (ISO 8601 format YYYY-MM-DDTHH:MM:SS.SSSZ)": "Datum und Uhrzeit, wenn das Ereignis aufgetreten ist, wird nun standardmäßig (ISO 8601 Format JJJJ-MM-TTTHH:MM:SS.SSSZ)",
"Select the type of event to create": "Wählen Sie die Art des zu erstellenden Ereignisses",
"Parameters for the selected event type": "Parameter für den ausgewählten Ereignistyp"
}

View File

@@ -0,0 +1,30 @@
{
"Project ID": "ID del proyecto",
"Datasource ID": "ID de datos",
"API Key": "Clave API",
"Your Instasent Project ID": "Tu ID de proyecto Instasent",
"Your Instasent Datasource ID": "Tu ID de datos Instasent",
"Your Instasent API Bearer Token": "Tu token de portador de API Instasent",
"\n## Obtain your auth data\n1. Go to https://dashboard.instasent.com\n2. Access to your project\n3. Create an Activepieces data source\n4. Copy the auth parameters and paste them in the fields below\n": "\n## Obtén tus datos de autenticación\n1. Ve a https://dashboard.instasent.com\n2. Accede a tu proyecto\n3. Crear una fuente de datos de piezas activas\n4. Copie los parámetros de autenticación y péguelos en los campos debajo de\n",
"Add/Update contact": "Añadir/Actualizar contacto",
"Delete Contact": "Eliminar contacto",
"Add Event": "Añadir evento",
"Add or update a single contact": "Añadir o actualizar un solo contacto",
"Delete a single contact by User ID": "Eliminar un solo contacto por ID de usuario",
"Add a contact event": "Añadir un evento de contacto",
"Contact Properties": "Propiedades del contacto",
"Instant": "Instantáneo",
"User ID": "ID Usuario",
"Event ID": "Evento ID",
"Event Date": "Fecha del evento",
"Event Type": "Tipo de evento",
"Event Parameters": "Parámetros del evento",
"Enter the contact properties, the User ID is mandatory": "Introduzca las propiedades de contacto, el ID de usuario es obligatorio",
"Process contact immediately instead of queuing. Only enable this when you need to add an event for this contact in the next step. Not recommended for high-volume operations.": "Procesar contacto inmediatamente en lugar de poner en cola. Actívalo solo cuando necesite agregar un evento para este contacto en el siguiente paso. No recomendado para operaciones de alto volumen.",
"Unique identifier of the contact to delete": "Identificador único del contacto a eliminar",
"Unique identifier of the user": "Identificador único del usuario",
"Unique identifier for this event. Used for deduplication.": "Identificador único para este evento. Utilizado para deduplicación.",
"Date and time when the event occurred, will default to now (ISO 8601 format YYYY-MM-DDTHH:MM:SS.SSSZ)": "Fecha y hora en que ocurrió el evento, por defecto ahora (formato ISO 8601 AAAA-MM-DDTHH:MM:SS.SSZ)",
"Select the type of event to create": "Seleccione el tipo de evento a crear",
"Parameters for the selected event type": "Parámetros para el tipo de evento seleccionado"
}

View File

@@ -0,0 +1,30 @@
{
"Project ID": "ID du projet",
"Datasource ID": "ID de la source de données",
"API Key": "Clé API",
"Your Instasent Project ID": "Votre ID de projet Instasent",
"Your Instasent Datasource ID": "Votre identifiant de source de données Instasent",
"Your Instasent API Bearer Token": "Votre jeton Instasent API Bearer",
"\n## Obtain your auth data\n1. Go to https://dashboard.instasent.com\n2. Access to your project\n3. Create an Activepieces data source\n4. Copy the auth parameters and paste them in the fields below\n": "\n## Obtain your auth data\n1. Go to https://dashboard.instasent.com\n2. Access to your project\n3. Create an Activepieces data source\n4. Copy the auth parameters and paste them in the fields below\n",
"Add/Update contact": "Ajouter/Mettre à jour le contact",
"Delete Contact": "Supprimer le contact",
"Add Event": "Ajouter un événement",
"Add or update a single contact": "Ajouter ou mettre à jour un contact unique",
"Delete a single contact by User ID": "Supprimer un contact unique par ID d'utilisateur",
"Add a contact event": "Ajouter un événement de contact",
"Contact Properties": "Propriétés du contact",
"Instant": "Instantané",
"User ID": "Identifiant de l'utilisateur",
"Event ID": "ID de l'événement",
"Event Date": "Date de l'événement",
"Event Type": "Type d'événement",
"Event Parameters": "Paramètres de l'événement",
"Enter the contact properties, the User ID is mandatory": "Entrez les propriétés du contact, l'ID de l'utilisateur est obligatoire",
"Process contact immediately instead of queuing. Only enable this when you need to add an event for this contact in the next step. Not recommended for high-volume operations.": "Traiter immédiatement le contact au lieu de la file d'attente. Activer cette option uniquement lorsque vous devez ajouter un événement pour ce contact à l'étape suivante. Non recommandé pour les opérations en volume élevé.",
"Unique identifier of the contact to delete": "Identifiant unique du contact à supprimer",
"Unique identifier of the user": "Identifiant unique de l'utilisateur",
"Unique identifier for this event. Used for deduplication.": "Identifiant unique pour cet événement. Utilisé pour la déduplication",
"Date and time when the event occurred, will default to now (ISO 8601 format YYYY-MM-DDTHH:MM:SS.SSSZ)": "Date et heure où l'événement s'est produit, sera par défaut à maintenant (format ISO 8601 AAAA-MM-JJJ: MM:SSSZ)",
"Select the type of event to create": "Sélectionnez le type d'événement à créer",
"Parameters for the selected event type": "Paramètres pour le type d'événement sélectionné"
}

View File

@@ -0,0 +1,30 @@
{
"Project ID": "プロジェクトID",
"Datasource ID": "データソースID",
"API Key": "API キー",
"Your Instasent Project ID": "Instasent Project ID",
"Your Instasent Datasource ID": "Instasent Datasource ID",
"Your Instasent API Bearer Token": "あなたのInstasent APIベアラートトークン",
"\n## Obtain your auth data\n1. Go to https://dashboard.instasent.com\n2. Access to your project\n3. Create an Activepieces data source\n4. Copy the auth parameters and paste them in the fields below\n": "\n## Obtain your auth data\n1. Go to https://dashboard.instasent.com\n2. Access to your project\n3. Create an Activepieces data source\n4. Copy the auth parameters and paste them in the fields below\n",
"Add/Update contact": "連絡先の追加/更新",
"Delete Contact": "連絡先を削除",
"Add Event": "イベントを追加",
"Add or update a single contact": "単一の連絡先を追加または更新",
"Delete a single contact by User ID": "ユーザー ID による単一の連絡先を削除",
"Add a contact event": "連絡先イベントを追加",
"Contact Properties": "連絡先のプロパティ",
"Instant": "インスタント",
"User ID": "ユーザー ID",
"Event ID": "イベントID",
"Event Date": "イベント日付",
"Event Type": "イベントタイプ",
"Event Parameters": "イベントパラメータ",
"Enter the contact properties, the User ID is mandatory": "連絡先のプロパティを入力します。ユーザー ID は必須です。",
"Process contact immediately instead of queuing. Only enable this when you need to add an event for this contact in the next step. Not recommended for high-volume operations.": "キューイングの代わりにすぐに連絡先を処理します。 次のステップでこの連絡先にイベントを追加する必要がある場合にのみ有効にしてください。大量の操作にはお勧めしません。",
"Unique identifier of the contact to delete": "削除する連絡先の固有識別子",
"Unique identifier of the user": "ユーザーの一意の識別子",
"Unique identifier for this event. Used for deduplication.": "このイベントの一意の識別子。重複排除に使用されます。",
"Date and time when the event occurred, will default to now (ISO 8601 format YYYY-MM-DDTHH:MM:SS.SSSZ)": "イベントが発生した日時は既定(ISO 8601形式YYYY-MM-DDTHH:MM:SSSSZ)",
"Select the type of event to create": "作成するイベントの種類を選択してください",
"Parameters for the selected event type": "選択したイベントタイプのパラメータ"
}

View File

@@ -0,0 +1,30 @@
{
"Project ID": "Project ID",
"Datasource ID": "Gegevensbron ID",
"API Key": "API Sleutel",
"Your Instasent Project ID": "Uw Instasent Project ID",
"Your Instasent Datasource ID": "Uw Instasent dataource-ID",
"Your Instasent API Bearer Token": "Je Instasent API Bearer Token",
"\n## Obtain your auth data\n1. Go to https://dashboard.instasent.com\n2. Access to your project\n3. Create an Activepieces data source\n4. Copy the auth parameters and paste them in the fields below\n": "\n## Verkrijg je autorisatiegegevens\n1. Ga naar https://dashboard.instasent.com\n2. Toegang tot je project\n3. Maak een Activepieces gegevensbron\n4. Kopieer de authenticatieparameters en plak ze in de onderstaande velden\n",
"Add/Update contact": "Contactpersoon toevoegen/bijwerken",
"Delete Contact": "Contactpersoon verwijderen",
"Add Event": "Afspraak toevoegen",
"Add or update a single contact": "Eén contactpersoon toevoegen of bijwerken",
"Delete a single contact by User ID": "Eén contactpersoon verwijderen via gebruikers-ID",
"Add a contact event": "Een contactgebeurtenis toevoegen",
"Contact Properties": "Contact eigenschappen",
"Instant": "Onmiddellijk",
"User ID": "Gebruiker ID",
"Event ID": "Gebeurtenis ID",
"Event Date": "Gebeurtenis datum",
"Event Type": "Gebeurtenis type",
"Event Parameters": "Event parameters",
"Enter the contact properties, the User ID is mandatory": "Voer de contactpersoon eigenschappen in, de gebruiker is verplicht",
"Process contact immediately instead of queuing. Only enable this when you need to add an event for this contact in the next step. Not recommended for high-volume operations.": "Contact onmiddellijk verwerken in plaats van wachtrij. Schakel dit alleen in als u een gebeurtenis voor deze contactpersoon in de volgende stap wilt toevoegen. Niet aanbevolen voor grote bewerkingen.",
"Unique identifier of the contact to delete": "Unieke identifier van de te verwijderen contactpersoon",
"Unique identifier of the user": "Unieke identifier van de gebruiker",
"Unique identifier for this event. Used for deduplication.": "Unieke identifier voor deze gebeurtenis. Wordt gebruikt voor deduplicatie.",
"Date and time when the event occurred, will default to now (ISO 8601 format YYYY-MM-DDTHH:MM:SS.SSSZ)": "Datum en tijd waarop de gebeurtenis heeft plaatsgevonden zullen als standaard worden ingesteld (ISO 8601 formaat YYYY-MM-DDTHH:MM:SS.SSSZ)",
"Select the type of event to create": "Selecteer het te maken type gebeurtenis",
"Parameters for the selected event type": "Parameters voor het geselecteerde gebeurtenistype"
}

View File

@@ -0,0 +1,30 @@
{
"Project ID": "ID do Projeto",
"Datasource ID": "ID da fonte",
"API Key": "Chave de API",
"Your Instasent Project ID": "Seu ID do Projeto Instasent",
"Your Instasent Datasource ID": "Seu ID de fonte de dados instantânea",
"Your Instasent API Bearer Token": "Seu Token de Portador da API Instasent",
"\n## Obtain your auth data\n1. Go to https://dashboard.instasent.com\n2. Access to your project\n3. Create an Activepieces data source\n4. Copy the auth parameters and paste them in the fields below\n": "\n## Obtenha seus dados de autenticação\n1. Acesse https://dashboard.instasent.com\n2. Acesse o seu projeto\n3. Crie uma fonte de dados do Activepieces\n4. Copie os parâmetros de autenticação e cole-os nos campos abaixo\n",
"Add/Update contact": "Adicionar/Atualizar contato",
"Delete Contact": "Excluir contato",
"Add Event": "Adicionar evento",
"Add or update a single contact": "Adicionar ou atualizar um único contato",
"Delete a single contact by User ID": "Excluir um único contato por ID de usuário",
"Add a contact event": "Adicionar evento de contato",
"Contact Properties": "Propriedades do contato",
"Instant": "Instantâneo",
"User ID": "ID de usuário",
"Event ID": "Código do evento",
"Event Date": "Data do Evento",
"Event Type": "Tipo de Evento",
"Event Parameters": "Parâmetros de Evento",
"Enter the contact properties, the User ID is mandatory": "Insira as propriedades de contato, a ID de Usuário é obrigatória",
"Process contact immediately instead of queuing. Only enable this when you need to add an event for this contact in the next step. Not recommended for high-volume operations.": "Processar contato imediatamente em vez de enfileirar. Ative isso somente quando precisar adicionar um evento para este contato na próxima etapa. Não recomendado para operações de alto volume.",
"Unique identifier of the contact to delete": "Identificador único do contato a excluir",
"Unique identifier of the user": "Identificador exclusivo do usuário",
"Unique identifier for this event. Used for deduplication.": "Identificador exclusivo para esse evento. Usado para desduplicar.",
"Date and time when the event occurred, will default to now (ISO 8601 format YYYY-MM-DDTHH:MM:SS.SSSZ)": "Data e hora quando o evento ocorreu, será o padrão para agora (formato ISO 8601 YYYY-MM-DDTHH:MM:SS.SSSZ)",
"Select the type of event to create": "Selecione o tipo de evento para criar",
"Parameters for the selected event type": "Parâmetros para o tipo de evento selecionado"
}

View File

@@ -0,0 +1,31 @@
{
"Instasent": "Мгновенно",
"Project ID": "ID проекта",
"Datasource ID": "ID источника данных",
"API Key": "Ключ API",
"Your Instasent Project ID": "Ваш экспресс-ID проекта",
"Your Instasent Datasource ID": "Ваш мгновенный идентификатор",
"Your Instasent API Bearer Token": "Токен Instasent API Bearer",
"\n## Obtain your auth data\n1. Go to https://dashboard.instasent.com\n2. Access to your project\n3. Create an Activepieces data source\n4. Copy the auth parameters and paste them in the fields below\n": "\n## Получите ваши данные авторизации\n1. Перейдите на https://dashboard.instasent.com\n2. Получите доступ к вашему проекту\n3. Создайте источник данных Activepieces\n4. Скопируйте параметры авторизации и вставьте их в поля ниже\n",
"Add/Update contact": "Добавить/Обновить контакт",
"Delete Contact": "Удалить контакт",
"Add Event": "Добавить событие",
"Add or update a single contact": "Добавить или обновить один контакт",
"Delete a single contact by User ID": "Удалить один контакт по ID пользователя",
"Add a contact event": "Добавить событие контакта",
"Contact Properties": "Параметры контакта",
"Instant": "Мгновенно",
"User ID": "ID пользователя",
"Event ID": "ID события",
"Event Date": "Дата события",
"Event Type": "Тип события",
"Event Parameters": "Параметры события",
"Enter the contact properties, the User ID is mandatory": "Введите свойства контакта, обязательный ID пользователя",
"Process contact immediately instead of queuing. Only enable this when you need to add an event for this contact in the next step. Not recommended for high-volume operations.": "Обработать контакт сразу, а не в очереди. Включите это только тогда, когда вам нужно добавить событие для этого контакта на следующем шаге. Не рекомендуется для высокообъемных операций.",
"Unique identifier of the contact to delete": "Уникальный идентификатор контакта для удаления",
"Unique identifier of the user": "Уникальный идентификатор пользователя",
"Unique identifier for this event. Used for deduplication.": "Уникальный идентификатор для этого события. Используется для deduplication.",
"Date and time when the event occurred, will default to now (ISO 8601 format YYYY-MM-DDTHH:MM:SS.SSSZ)": "Дата и время, когда произошло событие, будут установлены по умолчанию (формат ISO 8601 YYY-MM-DDTHH:MM:SSSZ)",
"Select the type of event to create": "Выберите тип события для создания",
"Parameters for the selected event type": "Параметры выбранного типа события"
}

View File

@@ -0,0 +1,30 @@
{
"Project ID": "Project ID",
"Datasource ID": "Datasource ID",
"API Key": "API Key",
"Your Instasent Project ID": "Your Instasent Project ID",
"Your Instasent Datasource ID": "Your Instasent Datasource ID",
"Your Instasent API Bearer Token": "Your Instasent API Bearer Token",
"\n## Obtain your auth data\n1. Go to https://dashboard.instasent.com\n2. Access to your project\n3. Create an Activepieces data source\n4. Copy the auth parameters and paste them in the fields below\n": "\n## Obtain your auth data\n1. Go to https://dashboard.instasent.com\n2. Access to your project\n3. Create an Activepieces data source\n4. Copy the auth parameters and paste them in the fields below\n",
"Add/Update contact": "Add/Update contact",
"Delete Contact": "Delete Contact",
"Add Event": "Add Event",
"Add or update a single contact": "Add or update a single contact",
"Delete a single contact by User ID": "Delete a single contact by User ID",
"Add a contact event": "Add a contact event",
"Contact Properties": "Contact Properties",
"Instant": "Instant",
"User ID": "User ID",
"Event ID": "Event ID",
"Event Date": "Event Date",
"Event Type": "Event Type",
"Event Parameters": "Event Parameters",
"Enter the contact properties, the User ID is mandatory": "Enter the contact properties, the User ID is mandatory",
"Process contact immediately instead of queuing. Only enable this when you need to add an event for this contact in the next step. Not recommended for high-volume operations.": "Process contact immediately instead of queuing. Only enable this when you need to add an event for this contact in the next step. Not recommended for high-volume operations.",
"Unique identifier of the contact to delete": "Unique identifier of the contact to delete",
"Unique identifier of the user": "Unique identifier of the user",
"Unique identifier for this event. Used for deduplication.": "Unique identifier for this event. Used for deduplication.",
"Date and time when the event occurred, will default to now (ISO 8601 format YYYY-MM-DDTHH:MM:SS.SSSZ)": "Date and time when the event occurred, will default to now (ISO 8601 format YYYY-MM-DDTHH:MM:SS.SSSZ)",
"Select the type of event to create": "Select the type of event to create",
"Parameters for the selected event type": "Parameters for the selected event type"
}

View File

@@ -0,0 +1,31 @@
{
"Instasent": "Instasent",
"Project ID": "Project ID",
"Datasource ID": "Datasource ID",
"API Key": "API Key",
"Your Instasent Project ID": "Your Instasent Project ID",
"Your Instasent Datasource ID": "Your Instasent Datasource ID",
"Your Instasent API Bearer Token": "Your Instasent API Bearer Token",
"\n## Obtain your auth data\n1. Go to https://dashboard.instasent.com\n2. Access to your project\n3. Create an Activepieces data source\n4. Copy the auth parameters and paste them in the fields below\n": "\n## Obtain your auth data\n1. Go to https://dashboard.instasent.com\n2. Access to your project\n3. Create an Activepieces data source\n4. Copy the auth parameters and paste them in the fields below\n",
"Add/Update contact": "Add/Update contact",
"Delete Contact": "Delete Contact",
"Add Event": "Add Event",
"Add or update a single contact": "Add or update a single contact",
"Delete a single contact by User ID": "Delete a single contact by User ID",
"Add a contact event": "Add a contact event",
"Contact Properties": "Contact Properties",
"Instant": "Instant",
"User ID": "User ID",
"Event ID": "Event ID",
"Event Date": "Event Date",
"Event Type": "Event Type",
"Event Parameters": "Event Parameters",
"Enter the contact properties, the User ID is mandatory": "Enter the contact properties, the User ID is mandatory",
"Process contact immediately instead of queuing. Only enable this when you need to add an event for this contact in the next step. Not recommended for high-volume operations.": "Process contact immediately instead of queuing. Only enable this when you need to add an event for this contact in the next step. Not recommended for high-volume operations.",
"Unique identifier of the contact to delete": "Unique identifier of the contact to delete",
"Unique identifier of the user": "Unique identifier of the user",
"Unique identifier for this event. Used for deduplication.": "Unique identifier for this event. Used for deduplication.",
"Date and time when the event occurred, will default to now (ISO 8601 format YYYY-MM-DDTHH:MM:SS.SSSZ)": "Date and time when the event occurred, will default to now (ISO 8601 format YYYY-MM-DDTHH:MM:SS.SSSZ)",
"Select the type of event to create": "Select the type of event to create",
"Parameters for the selected event type": "Parameters for the selected event type"
}

View File

@@ -0,0 +1,30 @@
{
"Project ID": "Project ID",
"Datasource ID": "Datasource ID",
"API Key": "API 密钥",
"Your Instasent Project ID": "Your Instasent Project ID",
"Your Instasent Datasource ID": "Your Instasent Datasource ID",
"Your Instasent API Bearer Token": "Your Instasent API Bearer Token",
"\n## Obtain your auth data\n1. Go to https://dashboard.instasent.com\n2. Access to your project\n3. Create an Activepieces data source\n4. Copy the auth parameters and paste them in the fields below\n": "\n## Obtain your auth data\n1. Go to https://dashboard.instasent.com\n2. Access to your project\n3. Create an Activepieces data source\n4. Copy the auth parameters and paste them in the fields below\n",
"Add/Update contact": "Add/Update contact",
"Delete Contact": "Delete Contact",
"Add Event": "Add Event",
"Add or update a single contact": "Add or update a single contact",
"Delete a single contact by User ID": "Delete a single contact by User ID",
"Add a contact event": "Add a contact event",
"Contact Properties": "Contact Properties",
"Instant": "Instant",
"User ID": "User ID",
"Event ID": "Event ID",
"Event Date": "Event Date",
"Event Type": "Event Type",
"Event Parameters": "Event Parameters",
"Enter the contact properties, the User ID is mandatory": "Enter the contact properties, the User ID is mandatory",
"Process contact immediately instead of queuing. Only enable this when you need to add an event for this contact in the next step. Not recommended for high-volume operations.": "Process contact immediately instead of queuing. Only enable this when you need to add an event for this contact in the next step. Not recommended for high-volume operations.",
"Unique identifier of the contact to delete": "Unique identifier of the contact to delete",
"Unique identifier of the user": "Unique identifier of the user",
"Unique identifier for this event. Used for deduplication.": "Unique identifier for this event. Used for deduplication.",
"Date and time when the event occurred, will default to now (ISO 8601 format YYYY-MM-DDTHH:MM:SS.SSSZ)": "Date and time when the event occurred, will default to now (ISO 8601 format YYYY-MM-DDTHH:MM:SS.SSSZ)",
"Select the type of event to create": "Select the type of event to create",
"Parameters for the selected event type": "Parameters for the selected event type"
}

View File

@@ -0,0 +1,84 @@
import { createPiece, PieceAuth } from "@activepieces/pieces-framework";
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
import { deleteContact } from './lib/actions/delete-contact';
import { addOrUpdateContact } from './lib/actions/add-or-update-contact';
import { createEvent } from "./lib/actions/create-event";
import { BASE_URL } from "./lib/common/constants";
import { InstasentAuthType } from './lib/common/types';
import { PieceCategory } from "@activepieces/shared";
export const getBaseUrl = (auth: { projectId: string, datasourceId: string }) => {
return `${BASE_URL}/project/${auth.projectId}/datasource/${auth.datasourceId}`;
};
const authDescriptionMarkdown = `
## Obtain your auth data
1. Go to https://dashboard.instasent.com
2. Access to your project
3. Create an Activepieces data source
4. Copy the auth parameters and paste them in the fields below
`;
export const instasentAuth = PieceAuth.CustomAuth({
description: authDescriptionMarkdown,
props: {
projectId: PieceAuth.SecretText({
displayName: 'Project ID',
description: 'Your Instasent Project ID',
required: true,
}),
datasourceId: PieceAuth.SecretText({
displayName: 'Datasource ID',
description: 'Your Instasent Datasource ID',
required: true,
}),
apiKey: PieceAuth.SecretText({
displayName: 'API Key',
description: 'Your Instasent API Bearer Token',
required: true,
})
},
validate: async ({ auth }) => {
const authData = auth;
try {
const baseUrl = getBaseUrl(authData);
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url: `${baseUrl}/stream`,
headers: {
'Authorization': `Bearer ${auth.apiKey}`
}
});
const data = response.body;
if (!data.organization || !data.stream || !data.datasource || !data.project) {
return {
valid: false,
error: 'Invalid API response structure'
};
}
return {
valid: true
};
} catch (error: any) {
return {
valid: false,
error: error.response?.data?.message || 'Invalid credentials or connection error'
};
}
},
required: true
});
export const instasent = createPiece({
displayName: "Instasent",
minimumSupportedRelease: '0.30.0',
logoUrl: "https://cdn.activepieces.com/pieces/instasent.jpg",
categories:[PieceCategory.MARKETING],
authors: ["dev-instasent", "https://github.com/dev-instasent"],
auth: instasentAuth,
actions: [addOrUpdateContact, deleteContact, createEvent],
triggers: [],
});

View File

@@ -0,0 +1,127 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
import { getBaseUrl, instasentAuth } from '../../index';
import { BOOLEAN_OPTIONS, IGNORED_ATTRIBUTES, LONG_TEXT_TYPES } from '../common/constants';
const PROPERTY_ITERATIONS = [
{ check: (spec: any) => spec.requiredInWebhook },
{ check: (spec: any) => spec.important },
{ check: (spec: any) => spec.visible !== false },
{ check: (spec: any) => !spec.custom },
{ check: () => true }
];
export const addOrUpdateContact = createAction({
name: 'add_or_update_contact',
displayName: 'Add/Update contact',
description: 'Add or update a single contact',
auth: instasentAuth,
props: {
contact: Property.DynamicProperties({
auth: instasentAuth,
displayName: 'Contact Properties',
description: 'Enter the contact properties, the User ID is mandatory',
required: true,
refreshers: ['authentication'],
props: async ({ auth }) => {
if (!auth) {
return {};
}
const authData = auth;
const baseUrl = getBaseUrl({
projectId: authData.props.projectId,
datasourceId: authData.props.datasourceId
});
try {
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url: `${baseUrl}/stream/specs/attributes`,
headers: {
'Authorization': `Bearer ${authData.props.apiKey}`
}
});
const properties: Record<string, any> = {};
for (const iteration of PROPERTY_ITERATIONS) {
for (const spec of response.body.specs) {
// Ignored properties
if (spec.readOnly || properties[spec.uid] || IGNORED_ATTRIBUTES.includes(spec.uid)) {
continue;
}
// Multiple iterations to sort the properties based on their attributes
if (!iteration.check(spec)) {
continue;
}
const displayLabel = spec.displayLabel;
let description = spec.description;
if (spec.dataType === 'date') {
description += ' (ISO 8601 format YYYY-MM-DD)';
}
if (spec.multivalue > 1) {
properties[spec.uid] = Property.Array({
displayName: displayLabel,
description: `${description} (Max ${spec.multivalue} values)`,
required: spec.requiredInWebhook
});
} else if (spec.dataType === 'bool') {
properties[spec.uid] = Property.StaticDropdown({
displayName: displayLabel,
description: `${description} [0=false|1=true|null=unknown]`,
required: spec.requiredInWebhook,
options: {
options: BOOLEAN_OPTIONS
}
});
} else {
const PropType = LONG_TEXT_TYPES.includes(spec.dataType) ? Property.LongText : Property.ShortText;
properties[spec.uid] = PropType({
displayName: displayLabel,
description: description,
required: spec.requiredInWebhook
});
}
}
}
return properties;
} catch (error) {
throw new Error('Failed to load contact properties');
}
}
}),
instant: Property.Checkbox({
displayName: 'Instant',
description: 'Process contact immediately instead of queuing. Only enable this when you need to add an event for this contact in the next step. Not recommended for high-volume operations.',
required: false,
defaultValue: false
})
},
async run(context) {
const contact = context.propsValue.contact;
const instant = context.propsValue.instant;
const auth = context.auth;
const baseUrl = getBaseUrl({ projectId: auth.props.projectId, datasourceId: auth.props.datasourceId });
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
url: `${baseUrl}/stream/contacts${instant ? '?_sync' : ''}`,
headers: {
'Authorization': `Bearer ${auth.props.apiKey}`,
'Content-Type': 'application/json'
},
body: [contact]
});
if (response.body.entitiesSuccess !== 1) {
throw new Error(`Failed to add or update contact: ${JSON.stringify(response.body.errors)}`);
}
return response.body;
}
});

View File

@@ -0,0 +1,162 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
import { getBaseUrl, instasentAuth } from '../..';
import { ApiResponse, EventParameter, EventSpec, InstasentAuthType } from '../common/types';
import { BOOLEAN_OPTIONS } from '../common/constants';
export const createEvent = createAction({
name: 'add_event',
displayName: 'Add Event',
description: 'Add a contact event',
auth: instasentAuth,
props: {
user_id: Property.ShortText({
displayName: 'User ID',
description: 'Unique identifier of the user',
required: true
}),
event_id: Property.ShortText({
displayName: 'Event ID',
description: 'Unique identifier for this event. Used for deduplication.',
required: true
}),
event_date: Property.ShortText({
displayName: 'Event Date',
description: 'Date and time when the event occurred, will default to now (ISO 8601 format YYYY-MM-DDTHH:MM:SS.SSSZ)',
required: false
}),
event_type: Property.Dropdown({
auth: instasentAuth,
displayName: 'Event Type',
description: 'Select the type of event to create',
required: true,
refreshers: [],
options: async ({ auth }) => {
if (!auth) {
return {
disabled: true,
options: [],
placeholder: 'Please connect your account first',
};
}
const authData = auth;
const baseUrl = getBaseUrl({
projectId: authData.props.projectId,
datasourceId: authData.props.datasourceId
});
const response = await httpClient.sendRequest<{ specs: EventSpec[] }>({
method: HttpMethod.GET,
url: `${baseUrl}/stream/specs/events`,
headers: {
'Authorization': `Bearer ${authData.props.apiKey}`
}
});
return {
options: response.body.specs.map(spec => ({
label: `${spec.emoji} ${spec.name}`,
value: spec.uid
}))
};
}
}),
event_parameters: Property.DynamicProperties({
auth: instasentAuth,
displayName: 'Event Parameters',
description: 'Parameters for the selected event type',
required: true,
refreshers: ['event_type'],
props: async ({ auth, event_type }) => {
if (!auth || !event_type) return {};
const authData = auth;
const baseUrl = getBaseUrl({
projectId: authData.props.projectId,
datasourceId: authData.props.datasourceId
});
const response = await httpClient.sendRequest<{ specs: EventParameter[] }>({
method: HttpMethod.GET,
url: `${baseUrl}/stream/specs/event-parameters/${event_type}`,
headers: {
'Authorization': `Bearer ${authData.props.apiKey}`
}
});
const props: Record<string, any> = {};
response.body.specs.forEach(param => {
if (param.multiValue > 1) {
props[param.parameter] = Property.Array({
displayName: param.title,
description: `${param.description} (Max ${param.multiValue} values)`,
required: param.required
});
} else {
// Convert API parameter specs to ActivePieces properties
switch (param.dataType) {
case 'bool':
props[param.parameter] = Property.StaticDropdown({
displayName: param.title,
description: `${param.description} [0=false|1=true|null=unknown]`,
required: param.required,
options: {
options: BOOLEAN_OPTIONS
}
})
break;
case "string":
case "payload":
props[param.parameter] = Property.LongText({
displayName: param.title,
description: param.description,
required: param.required
});
break;
default:
props[param.parameter] = Property.ShortText({
displayName: param.title,
description: param.description,
required: param.required
});
break;
}
}
});
return props;
}
})
},
async run({ auth, propsValue }) {
const authData = auth as InstasentAuthType;
const baseUrl = getBaseUrl({
projectId: authData.props.projectId,
datasourceId: authData.props.datasourceId
});
const eventData = {
_user_id: propsValue.user_id,
_event_id: propsValue.event_id,
_event_type: propsValue.event_type,
_event_date: propsValue.event_date,
_event_parameters: propsValue.event_parameters
};
const response = await httpClient.sendRequest<ApiResponse<typeof eventData>>({
method: HttpMethod.POST,
url: `${baseUrl}/stream/events`,
headers: {
'Authorization': `Bearer ${authData.props.apiKey}`,
'Content-Type': 'application/json'
},
body: [eventData]
});
if (response.body.entitiesSuccess !== 1) {
throw new Error(`Failed to create event: ${JSON.stringify(response.body.errors)}`);
}
return response.body;
}
});

View File

@@ -0,0 +1,33 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
import { getBaseUrl, instasentAuth } from '../../index';
export const deleteContact = createAction({
name: 'delete_contact',
displayName: 'Delete Contact',
description: 'Delete a single contact by User ID',
auth: instasentAuth,
props: {
userId: Property.ShortText({
displayName: 'User ID',
description: 'Unique identifier of the contact to delete',
required: true
})
},
async run(context) {
const { userId } = context.propsValue;
const auth = context.auth;
const baseUrl = getBaseUrl({ projectId: auth.props.projectId, datasourceId: auth.props.datasourceId });
const response = await httpClient.sendRequest({
method: HttpMethod.DELETE,
url: `${baseUrl}/stream/contacts/${userId}`,
headers: {
'Authorization': `Bearer ${auth.props.apiKey}`
}
});
return response.body;
}
});

View File

@@ -0,0 +1,11 @@
export const IGNORED_ATTRIBUTES = ['_email_verified', '_phone_mobile_verified'];
export const BASE_URL = 'https://api.instasent.com/v1';
export const BOOLEAN_OPTIONS = [
{ label: 'True', value: '1' },
{ label: 'False', value: '0' },
{ label: 'Unknown / Not set', value: null }
];
export const LONG_TEXT_TYPES = ['text', 'payload', 'string'];

View File

@@ -0,0 +1,53 @@
import { AppConnectionValueForAuthProperty } from "@activepieces/pieces-framework";
import { instasentAuth } from "../..";
export type InstasentAuthType = AppConnectionValueForAuthProperty<typeof instasentAuth>;
export interface EventSpec {
uid: string;
name: string;
description: string;
category: string;
attribution: boolean;
automation: boolean;
icon: string;
emoji: string;
important: boolean;
}
export interface EventParameter {
parameter: string;
title: string;
description: string;
icon: string;
dataType: string;
visualType: string;
maxLength: number;
required: boolean;
multiValue: number;
}
export interface ContactAttributeSpec {
uid: string;
displayLabel: string;
description: string;
dataType: string;
multivalue: number;
readOnly: boolean;
requiredInWebhook: boolean;
important: boolean;
visible: boolean;
custom: boolean;
}
export interface ApiResponse<T> {
success: boolean;
entitiesSuccess: number;
streamId: string;
projectId: string;
datasourceId: string;
errors: any[];
accepted: Array<{
position: number;
item: T;
}>;
}