Add Activepieces integration for workflow automation

- Add Activepieces fork with SmoothSchedule custom piece
- Create integrations app with Activepieces service layer
- Add embed token endpoint for iframe integration
- Create Automations page with embedded workflow builder
- Add sidebar visibility fix for embed mode
- Add list inactive customers endpoint to Public API
- Include SmoothSchedule triggers: event created/updated/cancelled
- Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
poduck
2025-12-18 22:59:37 -05:00
parent 9848268d34
commit 3aa7199503
16292 changed files with 1284892 additions and 4708 deletions

View File

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

View File

@@ -0,0 +1,7 @@
# pieces-insighto-ai
This library was generated with [Nx](https://nx.dev).
## Building
Run `nx build pieces-insighto-ai` to build the library.

View File

@@ -0,0 +1,10 @@
{
"name": "@activepieces/piece-insighto-ai",
"version": "0.0.2",
"type": "commonjs",
"main": "./src/index.js",
"types": "./src/index.d.ts",
"dependencies": {
"tslib": "^2.3.0"
}
}

View File

@@ -0,0 +1,65 @@
{
"name": "pieces-insighto-ai",
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/pieces/community/insighto-ai/src",
"projectType": "library",
"release": {
"version": {
"manifestRootsToUpdate": [
"dist/{projectRoot}"
],
"currentVersionResolver": "git-tag",
"fallbackCurrentVersionResolver": "disk"
}
},
"tags": [],
"targets": {
"build": {
"executor": "@nx/js:tsc",
"outputs": [
"{options.outputPath}"
],
"options": {
"outputPath": "dist/packages/pieces/community/insighto-ai",
"tsConfig": "packages/pieces/community/insighto-ai/tsconfig.lib.json",
"packageJson": "packages/pieces/community/insighto-ai/package.json",
"main": "packages/pieces/community/insighto-ai/src/index.ts",
"assets": [
"packages/pieces/community/insighto-ai/*.md",
{
"input": "packages/pieces/community/insighto-ai/src/i18n",
"output": "./src/i18n",
"glob": "**/!(i18n.json)"
}
],
"buildableProjectDepsInPackageJsonType": "dependencies",
"updateBuildableProjectDepsInPackageJson": true
},
"dependsOn": [
"^build",
"prebuild"
]
},
"nx-release-publish": {
"options": {
"packageRoot": "dist/{projectRoot}"
}
},
"lint": {
"executor": "@nx/eslint:lint",
"outputs": [
"{options.outputFile}"
]
},
"prebuild": {
"executor": "nx:run-commands",
"options": {
"cwd": "packages/pieces/community/insighto-ai",
"command": "bun install --no-save --silent"
},
"dependsOn": [
"^build"
]
}
}
}

View File

@@ -0,0 +1,65 @@
{
"AI-powered platform for capturing forms, conversations, and data sources with automated processing and outbound communications": "KI-gestützte Plattform für die Erfassung von Formularen, Konversationen und Datenquellen mit automatisierter Verarbeitung und ausgehende Kommunikation",
"Your Insighto.ai API key": "Ihr Insighto.ai API-Schlüssel",
"Add Text Blob Into Data Source": "Text Blob in Datenquelle hinzufügen",
"Upsert Contact": "Upsert-Kontakt",
"Make Outbound Call": "Ausgehenden Anruf tätigen",
"Create Campaign": "Kampagne erstellen",
"Inserts a large text blob into an existing data source": "Fügt einen großen Text-Blob in eine vorhandene Datenquelle ein",
"Create or update a contact using email or phone number": "Erstellen oder aktualisieren eines Kontakts mit E-Mail oder Telefonnummer",
"Initiate an outbound call to a phone number using a configured widget": "Initiieren eines ausgehenden Anrufs an eine Telefonnummer mit einem konfigurierten Widget",
"Create a new outbound call campaign": "Neue Anruf-Kampagne erstellen",
"Data Source": "Datenquelle",
"Name": "Name",
"Description": "Beschreibung",
"Organization ID": "Organisations-ID",
"Text Content": "Textinhalt",
"First Name": "Vorname",
"Last Name": "Nachname",
"Email": "E-Mail",
"Phone Number": "Telefonnummer",
"Widget": "Widget",
"Dynamic Variables": "Dynamische Variablen",
"Campaign Name": "Kampagnenname",
"Campaign Type": "Kampagnentyp",
"Start Time": "Startzeit",
"Interval (minutes)": "Intervall (Minuten)",
"Attributes": "Attribute",
"Status": "Status",
"Execution Weekdays": "Ausführung Wochentage",
"Time Window Start": "Start des Zeitfensters",
"Time Window End": "Zeitfenster Ende",
"Time Zone": "Zeitzone",
"Enabled": "Aktiviert",
"Select the data source to add the text blob to": "Wählen Sie die Datenquelle, um den Text-Blob hinzuzufügen",
"Optional name for this text blob entry": "Optionaler Name für diesen Text-Blob-Eintrag",
"Optional description of what this text blob contains": "Optionale Beschreibung dessen, was dieser Text-Blob enthält",
"The UUID of the organization": "Die UUID der Organisation",
"The text content to add to the data source": "Der Textinhalt, der zur Datenquelle hinzugefügt wird",
"Email address of the contact": "E-Mail-Adresse des Kontakts",
"Phone number including country code (e.g., 16501111234)": "Telefonnummer inkl. Landesvorwahl (z. B. 16501111234)",
"Widget connected to Twilio, Plivo, or Telnyx for making calls": "Widget verbunden mit Twilio, Plivo, oder Telnyx für Anrufe",
"Phone number in E.164 format (e.g., 16501234567)": "Telefonnummer im E.164-Format (z. B. 16501234567)",
"Variables for call prompts (e.g., {\"name\": \"Bob\", \"appointment\": \"tomorrow\"})": "Variablen für Anruflisten (z.B. {\"name\": \"Bob\", \"Ernennung\": \"morgen \"})",
"When the campaign should start": "Wann die Kampagne gestartet werden soll",
"Time between executions (e.g., 60 for hourly, 1440 for daily)": "Zeit zwischen Hinrichtungen (z. B. 60 pro Stunde, 1440 pro Tag)",
"Widget to associate with this campaign": "Widget, das dieser Kampagne zugeordnet werden soll",
"Additional campaign attributes as key-value pairs": "Zusätzliche Kampagnen-Attribute als Schlüssel-Wert-Paare",
"Weekdays as numbers (e.g., [1, 2, 3] for Mon, Tue, Wed)": "Wochentage als Zahlen (z. B. [1, 2, 3] für Mon, Di, Wed)",
"Start time in HH:MM format": "Startzeit im HH:MM-Format",
"End time in HH:MM format": "Endzeit im HH:MM-Format",
"Time zone (defaults to UTC)": "Zeitzone (Standardwert UTC)",
"Outbound Call": "Ausgehender Anruf",
"Not Started": "Nicht gestartet",
"To Be Run": "Zu starten",
"In Progress": "In Bearbeitung",
"Paused": "Pausiert",
"Cancelled": "Abgebrochen",
"Completed": "Abgeschlossen",
"New Captured Form": "Neues erfasstes Formular",
"New Conversation": "Neue Unterhaltung",
"New Contact": "Neuer Kontakt",
"Fires when a new form submission is captured in Insighto.ai": "Feuert ab, wenn eine neue Formularabgabe in Insighto.ai erfasst wird",
"Fires when an existing conversation is updated with a new message": "Feuert ab, wenn eine bestehende Unterhaltung mit einer neuen Nachricht aktualisiert wird",
"Triggers when a new contact is created": "Wird ausgelöst, wenn ein neuer Kontakt erstellt wird"
}

View File

@@ -0,0 +1,65 @@
{
"AI-powered platform for capturing forms, conversations, and data sources with automated processing and outbound communications": "Plataforma impulsada por AIs para capturar formularios, conversaciones y fuentes de datos con procesamiento automatizado y comunicaciones salientes",
"Your Insighto.ai API key": "Tu clave API de Insighto.ai",
"Add Text Blob Into Data Source": "Añadir texto Blob a la fuente de datos",
"Upsert Contact": "Actualizar contacto",
"Make Outbound Call": "Hacer llamada saliente",
"Create Campaign": "Crear Campaña",
"Inserts a large text blob into an existing data source": "Inserta un blob de texto grande en una fuente de datos existente",
"Create or update a contact using email or phone number": "Crear o actualizar un contacto mediante correo electrónico o número de teléfono",
"Initiate an outbound call to a phone number using a configured widget": "Iniciar una llamada saliente a un número de teléfono usando un widget configurado",
"Create a new outbound call campaign": "Crear una nueva campaña de llamadas salientes",
"Data Source": "Fuente de datos",
"Name": "Nombre",
"Description": "Descripción",
"Organization ID": "ID de la organización",
"Text Content": "Contenido de texto",
"First Name": "Nombre",
"Last Name": "Apellido",
"Email": "E-mail",
"Phone Number": "Número de teléfono",
"Widget": "Widget",
"Dynamic Variables": "Variables dinámicas",
"Campaign Name": "Nombre de Campaña",
"Campaign Type": "Tipo de Campaña",
"Start Time": "Hora de inicio",
"Interval (minutes)": "Intervalo (minutos)",
"Attributes": "Atributos",
"Status": "Estado",
"Execution Weekdays": "Ejecutar días semanales",
"Time Window Start": "Inicio de ventana de tiempo",
"Time Window End": "Fin de Ventana",
"Time Zone": "Zona horaria",
"Enabled": "Activado",
"Select the data source to add the text blob to": "Seleccione la fuente de datos a la que agregar el blob de texto",
"Optional name for this text blob entry": "Nombre opcional para este blob de texto",
"Optional description of what this text blob contains": "Descripción opcional de lo que contiene este bloque de texto",
"The UUID of the organization": "El UUID de la organización",
"The text content to add to the data source": "El contenido del texto a añadir a la fuente de datos",
"Email address of the contact": "Dirección de correo del contacto",
"Phone number including country code (e.g., 16501111234)": "Número de teléfono incluyendo el código del país (por ejemplo, 16501111234)",
"Widget connected to Twilio, Plivo, or Telnyx for making calls": "Widget conectado a Twilio, Plivo, o Telnyx para hacer llamadas",
"Phone number in E.164 format (e.g., 16501234567)": "Número de teléfono en formato E.164 (por ejemplo, 16501234567)",
"Variables for call prompts (e.g., {\"name\": \"Bob\", \"appointment\": \"tomorrow\"})": "Variables para peticiones de llamada (por ejemplo, {\"nombre\": \"Bob\", \"cita\": \"Mañana\"})",
"When the campaign should start": "Cuando la campaña debe comenzar",
"Time between executions (e.g., 60 for hourly, 1440 for daily)": "Tiempo entre ejecuciones (por ejemplo, 60 por hora, 1440 por día)",
"Widget to associate with this campaign": "Widget para asociar con esta campaña",
"Additional campaign attributes as key-value pairs": "Atributos adicionales de campaña como pares clave-valor",
"Weekdays as numbers (e.g., [1, 2, 3] for Mon, Tue, Wed)": "Días de semana como números (por ej., [1, 2, 3] para Lun, Mar, Mié)",
"Start time in HH:MM format": "Hora de inicio en formato HH:MM",
"End time in HH:MM format": "Hora de fin en formato HH:MM",
"Time zone (defaults to UTC)": "Zona horaria (por defecto en UTC)",
"Outbound Call": "Llamada saliente",
"Not Started": "No iniciado",
"To Be Run": "A ser ejecutado",
"In Progress": "En curso",
"Paused": "Pausado",
"Cancelled": "Cancelado",
"Completed": "Completado",
"New Captured Form": "Nueva forma capturada",
"New Conversation": "Nueva conversación",
"New Contact": "Nuevo contacto",
"Fires when a new form submission is captured in Insighto.ai": "Dispara cuando un nuevo formulario es capturado en Insighto.ai",
"Fires when an existing conversation is updated with a new message": "Dispara cuando una conversación existente se actualiza con un nuevo mensaje",
"Triggers when a new contact is created": "Dispara cuando se crea un nuevo contacto"
}

View File

@@ -0,0 +1,65 @@
{
"AI-powered platform for capturing forms, conversations, and data sources with automated processing and outbound communications": "Plateforme alimentée par un IA pour capturer des formulaires, des conversations et des sources de données avec un traitement automatisé et des communications sortantes",
"Your Insighto.ai API key": "Votre clé API Insighto.ai",
"Add Text Blob Into Data Source": "Ajouter un bloc de texte dans la source de données",
"Upsert Contact": "Contact Upsert",
"Make Outbound Call": "Passer un appel sortant",
"Create Campaign": "Créer une campagne",
"Inserts a large text blob into an existing data source": "Insère un bloc de texte volumineux dans une source de données existante",
"Create or update a contact using email or phone number": "Créer ou mettre à jour un contact en utilisant un e-mail ou un numéro de téléphone",
"Initiate an outbound call to a phone number using a configured widget": "Lancer un appel sortant vers un numéro de téléphone en utilisant un widget configuré",
"Create a new outbound call campaign": "Créer une nouvelle campagne d'appel sortant",
"Data Source": "Source de données",
"Name": "Nom",
"Description": "Libellé",
"Organization ID": "ID de l'organisation",
"Text Content": "Contenu du texte",
"First Name": "First Name",
"Last Name": "Last Name",
"Email": "Courriel",
"Phone Number": "Numéro de téléphone",
"Widget": "Widget",
"Dynamic Variables": "Variables dynamiques",
"Campaign Name": "Nom de la campagne",
"Campaign Type": "Type de campagne",
"Start Time": "Start Time",
"Interval (minutes)": "Intervalle (minutes)",
"Attributes": "Attributs",
"Status": "Statut",
"Execution Weekdays": "Exécution des jours de la semaine",
"Time Window Start": "Début de la fenêtre de temps",
"Time Window End": "Fin de la fenêtre de temps",
"Time Zone": "Fuseau horaire",
"Enabled": "Activé",
"Select the data source to add the text blob to": "Sélectionnez la source de données à laquelle ajouter le bloc de texte",
"Optional name for this text blob entry": "Nom facultatif pour cette entrée de texte",
"Optional description of what this text blob contains": "Description facultative de ce que contient ce texte",
"The UUID of the organization": "L'UUID de l'organisation",
"The text content to add to the data source": "Le contenu du texte à ajouter à la source de données",
"Email address of the contact": "Adresse e-mail du contact",
"Phone number including country code (e.g., 16501111234)": "Numéro de téléphone incluant l'indicatif du pays (par exemple, 16501111234)",
"Widget connected to Twilio, Plivo, or Telnyx for making calls": "Widget connecté à Twilio, Plivo ou Telnyx pour passer des appels",
"Phone number in E.164 format (e.g., 16501234567)": "Numéro de téléphone au format E.164 (par exemple, 16501234567)",
"Variables for call prompts (e.g., {\"name\": \"Bob\", \"appointment\": \"tomorrow\"})": "Variables pour les invite d'appel (par exemple, {\"name\": \"Bob\", \"appointment\": \"demain\"})",
"When the campaign should start": "Quand la campagne doit démarrer",
"Time between executions (e.g., 60 for hourly, 1440 for daily)": "Temps entre les exécutions (par exemple, 60 pour l'heure, 1440 pour la journée)",
"Widget to associate with this campaign": "Widget à associer à cette campagne",
"Additional campaign attributes as key-value pairs": "Attributs de campagne supplémentaires comme paires clé-valeur",
"Weekdays as numbers (e.g., [1, 2, 3] for Mon, Tue, Wed)": "Les jours de la semaine sous forme de nombres (par exemple, [1, 2, 3] pour lun, mar, mari)",
"Start time in HH:MM format": "Heure de début au format HH:MM",
"End time in HH:MM format": "Heure de fin au format HH:MM",
"Time zone (defaults to UTC)": "Fuseau horaire (par défaut UTC)",
"Outbound Call": "Appel sortant",
"Not Started": "Non démarré",
"To Be Run": "À exécuter",
"In Progress": "En cours",
"Paused": "En pause",
"Cancelled": "Annulé",
"Completed": "Terminé",
"New Captured Form": "Nouvelle forme capturée",
"New Conversation": "Nouvelle conversation",
"New Contact": "Nouveau contact",
"Fires when a new form submission is captured in Insighto.ai": "Tire quand une nouvelle soumission de formulaire est capturée dans Insighto.ai",
"Fires when an existing conversation is updated with a new message": "Se déclenche lorsqu'une conversation existante est mise à jour avec un nouveau message",
"Triggers when a new contact is created": "Déclenche lorsqu'un nouveau contact est créé"
}

View File

@@ -0,0 +1,65 @@
{
"AI-powered platform for capturing forms, conversations, and data sources with automated processing and outbound communications": "フォーム、会話、およびデータソースを自動化された処理とアウトバウンド通信でキャプチャするためのAIを搭載したプラットフォーム",
"Your Insighto.ai API key": "Insighto.ai API キー",
"Add Text Blob Into Data Source": "テキスト Blob をデータ ソースに追加",
"Upsert Contact": "アップサート連絡先",
"Make Outbound Call": "発信を行う",
"Create Campaign": "キャンペーンを作成",
"Inserts a large text blob into an existing data source": "既存のデータソースに大きなテキストブロブを挿入します",
"Create or update a contact using email or phone number": "電子メールまたは電話番号を使用して連絡先を作成または更新",
"Initiate an outbound call to a phone number using a configured widget": "設定されたウィジェットを使用して電話番号に発信を開始する",
"Create a new outbound call campaign": "新しい発信コールキャンペーンを作成します",
"Data Source": "データソース",
"Name": "名前",
"Description": "説明",
"Organization ID": "組織 ID",
"Text Content": "テキストコンテンツ",
"First Name": "名",
"Last Name": "姓",
"Email": "Eメールアドレス",
"Phone Number": "電話番号",
"Widget": "ウィジェット",
"Dynamic Variables": "動的変数",
"Campaign Name": "キャンペーン名",
"Campaign Type": "キャンペーンタイプ",
"Start Time": "開始時刻",
"Interval (minutes)": "間隔 (分)",
"Attributes": "属性",
"Status": "ステータス",
"Execution Weekdays": "Execution Weekdays",
"Time Window Start": "タイムウィンドウの開始",
"Time Window End": "タイムウィンドウの終了",
"Time Zone": "タイムゾーン",
"Enabled": "有効",
"Select the data source to add the text blob to": "テキストブロブを追加するデータソースを選択します。",
"Optional name for this text blob entry": "このテキストの Blob エントリのオプション名",
"Optional description of what this text blob contains": "このテキスト Blob に含まれるオプションの説明",
"The UUID of the organization": "組織の UUID",
"The text content to add to the data source": "データソースに追加するテキストコンテンツ",
"Email address of the contact": "連絡先のメールアドレス",
"Phone number including country code (e.g., 16501111234)": "国コードを含む電話番号16501111234",
"Widget connected to Twilio, Plivo, or Telnyx for making calls": "Twilio、Plivo、またはTelnyxに通話用に接続されたウィジェット",
"Phone number in E.164 format (e.g., 16501234567)": "E.164形式の電話番号16501234567",
"Variables for call prompts (e.g., {\"name\": \"Bob\", \"appointment\": \"tomorrow\"})": "呼び出しプロンプトの変数 (例: {\"name\": \"ボブ\", \"予定\": \"明日\"})",
"When the campaign should start": "キャンペーンを開始する時",
"Time between executions (e.g., 60 for hourly, 1440 for daily)": "実行間隔毎日60時間1440秒",
"Widget to associate with this campaign": "このキャンペーンに関連付けるウィジェット",
"Additional campaign attributes as key-value pairs": "キーと値のペアとして追加のキャンペーン属性",
"Weekdays as numbers (e.g., [1, 2, 3] for Mon, Tue, Wed)": "平日数字(例:月・火・水・水)",
"Start time in HH:MM format": "HH:MM形式の開始時刻",
"End time in HH:MM format": "終了時刻は HH:MM 形式です",
"Time zone (defaults to UTC)": "タイムゾーン (デフォルトは UTC)",
"Outbound Call": "発信通話",
"Not Started": "未開始",
"To Be Run": "実行する",
"In Progress": "進行中",
"Paused": "一時停止中",
"Cancelled": "キャンセルしました",
"Completed": "完了",
"New Captured Form": "新しいキャプチャされたフォーム",
"New Conversation": "新しい会話",
"New Contact": "新しい連絡先",
"Fires when a new form submission is captured in Insighto.ai": "Insighto.ai で新しいフォームの送信がキャプチャされたときに発生します。",
"Fires when an existing conversation is updated with a new message": "既存の会話が新しいメッセージで更新されたときに発行されます",
"Triggers when a new contact is created": "新しい連絡先が作成されたときにトリガーします"
}

View File

@@ -0,0 +1,65 @@
{
"AI-powered platform for capturing forms, conversations, and data sources with automated processing and outbound communications": "AI-aangedreven platform voor het vastleggen van formulieren, gesprekken en gegevensbronnen met geautomatiseerde verwerking en uitgaande communicatie",
"Your Insighto.ai API key": "Je Insighto.ai API-sleutel",
"Add Text Blob Into Data Source": "Tekstblok toevoegen aan gegevensbron",
"Upsert Contact": "Contacten naar beneden",
"Make Outbound Call": "Uitgaande oproep maken",
"Create Campaign": "Nieuwe campagne",
"Inserts a large text blob into an existing data source": "Voegt een grote tekstblob in een bestaande gegevensbron in",
"Create or update a contact using email or phone number": "Een contactpersoon aanmaken of bijwerken via e-mail of telefoonnummer",
"Initiate an outbound call to a phone number using a configured widget": "Start een uitgaande oproep naar een telefoonnummer met een geconfigureerde widget",
"Create a new outbound call campaign": "Maak een nieuwe uitgaande oproep campagne",
"Data Source": "Bron van gegevens",
"Name": "Naam",
"Description": "Beschrijving",
"Organization ID": "Organisatie ID",
"Text Content": "Tekst inhoud",
"First Name": "Voornaam",
"Last Name": "Achternaam",
"Email": "E-mail",
"Phone Number": "Telefoon nummer",
"Widget": "Widget",
"Dynamic Variables": "Dynamische variabelen",
"Campaign Name": "Campagne Naam",
"Campaign Type": "Campagne Type",
"Start Time": "Starttijd",
"Interval (minutes)": "Interval (minuten)",
"Attributes": "Kenmerken",
"Status": "status",
"Execution Weekdays": "Executie Weekdagen",
"Time Window Start": "Start tijdsvenster",
"Time Window End": "Einde van tijdvenster",
"Time Zone": "Tijd Zone",
"Enabled": "Ingeschakeld",
"Select the data source to add the text blob to": "Selecteer de gegevensbron om de tekst blob aan toe te voegen",
"Optional name for this text blob entry": "Optionele naam voor deze tekstblob-invoer",
"Optional description of what this text blob contains": "Optionele beschrijving van wat deze tekst blob bevat",
"The UUID of the organization": "De UUID van de organisatie",
"The text content to add to the data source": "De tekstinhoud om toe te voegen aan de gegevensbron",
"Email address of the contact": "E-mailadres van de contactpersoon",
"Phone number including country code (e.g., 16501111234)": "Telefoonnummer inclusief landcode (bijv. 16501111234)",
"Widget connected to Twilio, Plivo, or Telnyx for making calls": "Widget verbonden met Twilio, Plivo, of Telnyx om te bellen",
"Phone number in E.164 format (e.g., 16501234567)": "Telefoonnummer in E.164-formaat (bijv. 16501234567)",
"Variables for call prompts (e.g., {\"name\": \"Bob\", \"appointment\": \"tomorrow\"})": "Variabelen voor aanroep prompts (bijv. {\"naam\": \"Bob\", \"afspraak \"morgen\"})",
"When the campaign should start": "Wanneer de campagne moet beginnen",
"Time between executions (e.g., 60 for hourly, 1440 for daily)": "Tijd tussen executies (bijv. 60 voor uur, 1440 voor dag)",
"Widget to associate with this campaign": "Widget om te koppelen aan deze campagne",
"Additional campaign attributes as key-value pairs": "Extra campagne attributen als sleutelwaarde paren",
"Weekdays as numbers (e.g., [1, 2, 3] for Mon, Tue, Wed)": "Weekdagen als getallen (b.v. [1, 2, 3] voor Mon, Te, Ween",
"Start time in HH:MM format": "Start tijd in UU:MM formaat",
"End time in HH:MM format": "Eindtijd in HH:MM formaat",
"Time zone (defaults to UTC)": "Tijdzone (standaard UTC)",
"Outbound Call": "Uitgaande oproep",
"Not Started": "Niet begonnen",
"To Be Run": "Nog uit te voeren",
"In Progress": "In uitvoering",
"Paused": "Gepauzeerd",
"Cancelled": "Geannuleerd",
"Completed": "Voltooid",
"New Captured Form": "Nieuw vastgelegd formulier",
"New Conversation": "Nieuwe conversatie",
"New Contact": "Nieuw contactpersoon",
"Fires when a new form submission is captured in Insighto.ai": "Vuurt wanneer een nieuwe formulier wordt ingediend in Insighto.ai",
"Fires when an existing conversation is updated with a new message": "Vuurt wanneer een bestaand gesprek wordt bijgewerkt met een nieuw bericht",
"Triggers when a new contact is created": "Triggert wanneer een nieuw contact wordt aangemaakt"
}

View File

@@ -0,0 +1,65 @@
{
"AI-powered platform for capturing forms, conversations, and data sources with automated processing and outbound communications": "Plataforma com IAR para a captura de formulários, conversas e fontes de dados com processamento automatizado e comunicações de saída",
"Your Insighto.ai API key": "Sua chave de API Insighto.ai",
"Add Text Blob Into Data Source": "Adicionar Bloco de Texto na Fonte de Dados",
"Upsert Contact": "Contato atualizado",
"Make Outbound Call": "Fazer chamada de saída",
"Create Campaign": "Criar Campanha",
"Inserts a large text blob into an existing data source": "Insere um blob de texto grande em uma fonte de dados existente",
"Create or update a contact using email or phone number": "Criar ou atualizar um contato usando e-mail ou número de telefone",
"Initiate an outbound call to a phone number using a configured widget": "Iniciar uma chamada para um número de telefone usando um widget configurado",
"Create a new outbound call campaign": "Criar uma nova campanha de chamada de saída",
"Data Source": "Fonte de Dados",
"Name": "Nome",
"Description": "Descrição",
"Organization ID": "ID da organização",
"Text Content": "Conteúdo do Texto",
"First Name": "Nome",
"Last Name": "Sobrenome",
"Email": "e-mail",
"Phone Number": "Número de telefone",
"Widget": "Widget",
"Dynamic Variables": "Variáveis Dinâmicas",
"Campaign Name": "Nome Da Campanha",
"Campaign Type": "Tipo De Campanha",
"Start Time": "Hora de início",
"Interval (minutes)": "Intervalo (minutos)",
"Attributes": "Atributos",
"Status": "Estado",
"Execution Weekdays": "Dias úteis da Execução",
"Time Window Start": "Janela de Tempo Inicial",
"Time Window End": "Fim da Janela de Tempo",
"Time Zone": "Fuso Horário",
"Enabled": "Ativado",
"Select the data source to add the text blob to": "Selecione a fonte de dados para adicionar o blob de texto",
"Optional name for this text blob entry": "Nome opcional para esta entrada blob texto",
"Optional description of what this text blob contains": "Descrição opcional do que este blob de texto contém",
"The UUID of the organization": "A UUID da organização",
"The text content to add to the data source": "O conteúdo do texto para adicionar à fonte de dados",
"Email address of the contact": "Endereço de email do contato",
"Phone number including country code (e.g., 16501111234)": "Número de telefone incluindo código do país (por exemplo, 16501111234)",
"Widget connected to Twilio, Plivo, or Telnyx for making calls": "Widget conectado a Twilio, Plivo, ou Telnyx para fazer chamadas",
"Phone number in E.164 format (e.g., 16501234567)": "Número de telefone no formato E.164 (por exemplo, 16501234567)",
"Variables for call prompts (e.g., {\"name\": \"Bob\", \"appointment\": \"tomorrow\"})": "Variáveis para solicitações de chamada (por exemplo, {\"name\": \"Bob\", \"compromisso\": \"amanhã\"})",
"When the campaign should start": "Quando a campanha deve começar",
"Time between executions (e.g., 60 for hourly, 1440 for daily)": "Tempo entre execuções (por exemplo, 60 por hora, 1440 por dia)",
"Widget to associate with this campaign": "Widget para associar com esta campanha",
"Additional campaign attributes as key-value pairs": "Atributos de campanha adicionais como pares de chave-valor",
"Weekdays as numbers (e.g., [1, 2, 3] for Mon, Tue, Wed)": "Dias úteis como números (ex.: [1, 2, 3] para Homem, Ter, Quim)",
"Start time in HH:MM format": "Hora de início em formato HH:MM",
"End time in HH:MM format": "Hora de término em formato HH:MM",
"Time zone (defaults to UTC)": "Fuso horário (o padrão é UTC)",
"Outbound Call": "Chamada de saída",
"Not Started": "Não Iniciado",
"To Be Run": "Para Ser Executar",
"In Progress": "Em Execução",
"Paused": "Pausado",
"Cancelled": "Cancelado",
"Completed": "Concluído",
"New Captured Form": "Novo formulário capturado",
"New Conversation": "Nova conversa",
"New Contact": "Novo Contato",
"Fires when a new form submission is captured in Insighto.ai": "Atira quando uma nova submissão de formulário é capturada no Insighto.ai",
"Fires when an existing conversation is updated with a new message": "Atira quando uma conversa existente é atualizada com uma nova mensagem",
"Triggers when a new contact is created": "Dispara quando um novo contato é criado"
}

View File

@@ -0,0 +1,65 @@
{
"AI-powered platform for capturing forms, conversations, and data sources with automated processing and outbound communications": "AI-powered platform for capturing forms, conversations, and data sources with automated processing and outbound communications",
"Your Insighto.ai API key": "Your Insighto.ai API key",
"Add Text Blob Into Data Source": "Add Text Blob Into Data Source",
"Upsert Contact": "Upsert Contact",
"Make Outbound Call": "Make Outbound Call",
"Create Campaign": "Create Campaign",
"Inserts a large text blob into an existing data source": "Inserts a large text blob into an existing data source",
"Create or update a contact using email or phone number": "Create or update a contact using email or phone number",
"Initiate an outbound call to a phone number using a configured widget": "Initiate an outbound call to a phone number using a configured widget",
"Create a new outbound call campaign": "Create a new outbound call campaign",
"Data Source": "Data Source",
"Name": "Name",
"Description": "Description",
"Organization ID": "Organization ID",
"Text Content": "Text Content",
"First Name": "First Name",
"Last Name": "Last Name",
"Email": "Email",
"Phone Number": "Phone Number",
"Widget": "Widget",
"Dynamic Variables": "Dynamic Variables",
"Campaign Name": "Campaign Name",
"Campaign Type": "Campaign Type",
"Start Time": "Start Time",
"Interval (minutes)": "Interval (minutes)",
"Attributes": "Attributes",
"Status": "Status",
"Execution Weekdays": "Execution Weekdays",
"Time Window Start": "Time Window Start",
"Time Window End": "Time Window End",
"Time Zone": "Time Zone",
"Enabled": "Enabled",
"Select the data source to add the text blob to": "Select the data source to add the text blob to",
"Optional name for this text blob entry": "Optional name for this text blob entry",
"Optional description of what this text blob contains": "Optional description of what this text blob contains",
"The UUID of the organization": "The UUID of the organization",
"The text content to add to the data source": "The text content to add to the data source",
"Email address of the contact": "Email address of the contact",
"Phone number including country code (e.g., 16501111234)": "Phone number including country code (e.g., 16501111234)",
"Widget connected to Twilio, Plivo, or Telnyx for making calls": "Widget connected to Twilio, Plivo, or Telnyx for making calls",
"Phone number in E.164 format (e.g., 16501234567)": "Phone number in E.164 format (e.g., 16501234567)",
"Variables for call prompts (e.g., {\"name\": \"Bob\", \"appointment\": \"tomorrow\"})": "Variables for call prompts (e.g., {\"name\": \"Bob\", \"appointment\": \"tomorrow\"})",
"When the campaign should start": "When the campaign should start",
"Time between executions (e.g., 60 for hourly, 1440 for daily)": "Time between executions (e.g., 60 for hourly, 1440 for daily)",
"Widget to associate with this campaign": "Widget to associate with this campaign",
"Additional campaign attributes as key-value pairs": "Additional campaign attributes as key-value pairs",
"Weekdays as numbers (e.g., [1, 2, 3] for Mon, Tue, Wed)": "Weekdays as numbers (e.g., [1, 2, 3] for Mon, Tue, Wed)",
"Start time in HH:MM format": "Start time in HH:MM format",
"End time in HH:MM format": "End time in HH:MM format",
"Time zone (defaults to UTC)": "Time zone (defaults to UTC)",
"Outbound Call": "Outbound Call",
"Not Started": "Not Started",
"To Be Run": "To Be Run",
"In Progress": "In Progress",
"Paused": "Paused",
"Cancelled": "Cancelled",
"Completed": "Completed",
"New Captured Form": "New Captured Form",
"New Conversation": "New Conversation",
"New Contact": "New Contact",
"Fires when a new form submission is captured in Insighto.ai": "Fires when a new form submission is captured in Insighto.ai",
"Fires when an existing conversation is updated with a new message": "Fires when an existing conversation is updated with a new message",
"Triggers when a new contact is created": "Triggers when a new contact is created"
}

View File

@@ -0,0 +1,65 @@
{
"AI-powered platform for capturing forms, conversations, and data sources with automated processing and outbound communications": "AI-powered platform for capturing forms, conversations, and data sources with automated processing and outbound communications",
"Your Insighto.ai API key": "Your Insighto.ai API key",
"Add Text Blob Into Data Source": "Add Text Blob Into Data Source",
"Upsert Contact": "Upsert Contact",
"Make Outbound Call": "Make Outbound Call",
"Create Campaign": "Create Campaign",
"Inserts a large text blob into an existing data source": "Inserts a large text blob into an existing data source",
"Create or update a contact using email or phone number": "Create or update a contact using email or phone number",
"Initiate an outbound call to a phone number using a configured widget": "Initiate an outbound call to a phone number using a configured widget",
"Create a new outbound call campaign": "Create a new outbound call campaign",
"Data Source": "Data Source",
"Name": "名称",
"Description": "描述",
"Organization ID": "Organization ID",
"Text Content": "Text Content",
"First Name": "名字",
"Last Name": "名字",
"Email": "电子邮件地址",
"Phone Number": "Phone Number",
"Widget": "Widget",
"Dynamic Variables": "Dynamic Variables",
"Campaign Name": "Campaign Name",
"Campaign Type": "Campaign Type",
"Start Time": "开始时间",
"Interval (minutes)": "Interval (minutes)",
"Attributes": "Attributes",
"Status": "状态",
"Execution Weekdays": "Execution Weekdays",
"Time Window Start": "Time Window Start",
"Time Window End": "Time Window End",
"Time Zone": "Time Zone",
"Enabled": "已启用",
"Select the data source to add the text blob to": "Select the data source to add the text blob to",
"Optional name for this text blob entry": "Optional name for this text blob entry",
"Optional description of what this text blob contains": "Optional description of what this text blob contains",
"The UUID of the organization": "The UUID of the organization",
"The text content to add to the data source": "The text content to add to the data source",
"Email address of the contact": "Email address of the contact",
"Phone number including country code (e.g., 16501111234)": "Phone number including country code (e.g., 16501111234)",
"Widget connected to Twilio, Plivo, or Telnyx for making calls": "Widget connected to Twilio, Plivo, or Telnyx for making calls",
"Phone number in E.164 format (e.g., 16501234567)": "Phone number in E.164 format (e.g., 16501234567)",
"Variables for call prompts (e.g., {\"name\": \"Bob\", \"appointment\": \"tomorrow\"})": "Variables for call prompts (e.g., {\"name\": \"Bob\", \"appointment\": \"tomorrow\"})",
"When the campaign should start": "When the campaign should start",
"Time between executions (e.g., 60 for hourly, 1440 for daily)": "Time between executions (e.g., 60 for hourly, 1440 for daily)",
"Widget to associate with this campaign": "Widget to associate with this campaign",
"Additional campaign attributes as key-value pairs": "Additional campaign attributes as key-value pairs",
"Weekdays as numbers (e.g., [1, 2, 3] for Mon, Tue, Wed)": "Weekdays as numbers (e.g., [1, 2, 3] for Mon, Tue, Wed)",
"Start time in HH:MM format": "Start time in HH:MM format",
"End time in HH:MM format": "End time in HH:MM format",
"Time zone (defaults to UTC)": "Time zone (defaults to UTC)",
"Outbound Call": "Outbound Call",
"Not Started": "Not Started",
"To Be Run": "To Be Run",
"In Progress": "In Progress",
"Paused": "已暂停",
"Cancelled": "Cancelled",
"Completed": "Completed",
"New Captured Form": "New Captured Form",
"New Conversation": "New Conversation",
"New Contact": "New Contact",
"Fires when a new form submission is captured in Insighto.ai": "Fires when a new form submission is captured in Insighto.ai",
"Fires when an existing conversation is updated with a new message": "Fires when an existing conversation is updated with a new message",
"Triggers when a new contact is created": "Triggers when a new contact is created"
}

View File

@@ -0,0 +1,28 @@
import { createPiece, PieceAuth } from "@activepieces/pieces-framework";
import { addTextBlobAction } from "./lib/actions/add-text-blob-action";
import { upsertContactAction } from "./lib/actions/upsert-contact-action";
import { makeOutboundCallAction } from "./lib/actions/make-outbound-call-action";
import { createCampaignAction } from "./lib/actions/create-campaign-action";
import { newCapturedForm } from "./lib/triggers/new-captured-form";
import { newConversation } from "./lib/triggers/new-conversation";
import { newContact } from "./lib/triggers/new-contact";
import { PieceCategory } from "@activepieces/shared";
export const insightoAuth = PieceAuth.SecretText({
displayName: "API Key",
description: "Your Insighto.ai API key",
required: true,
});
export const insightoAi = createPiece({
displayName: "Insighto.ai",
description: "AI-powered platform for capturing forms, conversations, and data sources with automated processing and outbound communications",
auth: insightoAuth,
minimumSupportedRelease: '0.36.1',
logoUrl: "https://cdn.activepieces.com/pieces/insighto-ai.png",
authors: ['fortunamide', 'onyedikachi-david'],
categories: [PieceCategory.ARTIFICIAL_INTELLIGENCE, PieceCategory.COMMUNICATION],
actions: [addTextBlobAction, upsertContactAction, makeOutboundCallAction, createCampaignAction],
triggers: [newCapturedForm, newConversation, newContact],
});

View File

@@ -0,0 +1,161 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
import { DataSourceItemSchema, DataSourceItem } from '../schemas';
import { insightoAuth } from '../..';
export const addTextBlobAction = createAction({
name: 'add_text_blob',
displayName: 'Add Text Blob Into Data Source',
description: 'Inserts a large text blob into an existing data source',
auth: insightoAuth,
props: {
datasource_id: Property.Dropdown({
auth: insightoAuth,
displayName: 'Data Source',
description: 'Select the data source to add the text blob to',
required: true,
refreshers: [],
options: async ({ auth }) => {
if (!auth) {
return {
disabled: true,
options: [],
placeholder: 'Please authenticate first'
};
}
try {
const apiKey = auth.secret_text;
const url = `https://api.insighto.ai/api/v1/datasource`;
const queryParams: Record<string, string> = {
api_key: apiKey,
page: '1',
size: '100', // Get more data sources for better UX
};
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url,
queryParams,
headers: {
'Content-Type': 'application/json',
},
});
const data = response.body.data;
if (!data || !data.items) {
return {
disabled: true,
options: [],
placeholder: 'No data sources found'
};
}
// Validate the response data
const validatedItems: DataSourceItem[] = [];
for (const item of data.items) {
try {
const parsedItem = DataSourceItemSchema.parse(item);
validatedItems.push(parsedItem);
} catch {
continue;
}
}
const options = validatedItems.map((item) => ({
label: `${item.name || 'Unnamed'} (${item.ds_type})`,
value: JSON.stringify({ id: item.id, ds_type: item.ds_type }),
}));
return {
disabled: false,
options,
};
} catch (error) {
return {
disabled: true,
options: [],
placeholder: 'Failed to load data sources'
};
}
},
}),
name: Property.ShortText({
displayName: 'Name',
description: 'Optional name for this text blob entry',
required: false,
}),
description: Property.LongText({
displayName: 'Description',
description: 'Optional description of what this text blob contains',
required: false,
}),
org_id: Property.ShortText({
displayName: 'Organization ID',
description: 'The UUID of the organization',
required: false,
}),
text_content: Property.LongText({
displayName: 'Text Content',
description: 'The text content to add to the data source',
required: true,
}),
},
async run(context) {
try {
const datasourceSelection = context.propsValue['datasource_id'];
const name = context.propsValue['name'];
const description = context.propsValue['description'];
const org_id = context.propsValue['org_id'];
const text_content = context.propsValue['text_content'];
const apiKey = context.auth.secret_text;
let datasource_id: string;
let ds_type: string;
try {
const parsed = JSON.parse(datasourceSelection);
datasource_id = parsed.id;
ds_type = parsed.ds_type;
} catch {
throw new Error('Invalid data source selection. Please select a valid data source from the dropdown.');
}
const url = `https://api.insighto.ai/api/v1/datasource/${datasource_id}/text_blob`;
const queryParams: Record<string, string> = {
api_key: apiKey,
ds_type,
};
if (name) queryParams['name'] = name;
if (description) queryParams['description'] = description;
if (org_id) queryParams['org_id'] = org_id;
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
url,
queryParams,
body: {
content: text_content,
},
headers: {
'Content-Type': 'application/json',
},
});
if (!response.body) {
throw new Error('No response received from Insighto.ai API');
}
return response.body;
} catch (error) {
if (error instanceof Error) {
throw new Error(`Failed to add text blob: ${error.message}`);
}
throw new Error('Failed to add text blob to data source');
}
},
});

View File

@@ -0,0 +1,229 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
import { WidgetItemSchema, WidgetItem } from '../schemas';
import { insightoAuth } from '../..';
export const createCampaignAction = createAction({
name: 'create_campaign',
displayName: 'Create Campaign',
description: 'Create a new outbound call campaign',
auth: insightoAuth,
props: {
name: Property.ShortText({
displayName: 'Campaign Name',
required: true,
}),
type: Property.StaticDropdown({
displayName: 'Campaign Type',
required: true,
options: {
options: [
{ label: 'Outbound Call', value: 'outbound_call' },
],
},
}),
start_time: Property.DateTime({
displayName: 'Start Time',
description: 'When the campaign should start',
required: true,
}),
interval: Property.Number({
displayName: 'Interval (minutes)',
description: 'Time between executions (e.g., 60 for hourly, 1440 for daily)',
required: true,
}),
widget_id: Property.Dropdown({
auth: insightoAuth,
displayName: 'Widget',
description: 'Widget to associate with this campaign',
required: false,
refreshers: [],
options: async ({ auth }) => {
if (!auth) {
return {
disabled: true,
options: [],
placeholder: 'Please authenticate first'
};
}
try {
const apiKey = auth.secret_text;
const url = `https://api.insighto.ai/api/v1/widget`;
const queryParams: Record<string, string> = {
api_key: apiKey,
page: '1',
size: '100', // Get more widgets for better UX
};
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url,
queryParams,
headers: {
'Content-Type': 'application/json',
},
});
const data = response.body.data;
if (!data || !data.items) {
return {
disabled: true,
options: [],
placeholder: 'No widgets found'
};
}
// Validate the response data
const validatedItems: WidgetItem[] = [];
for (const item of data.items) {
try {
const parsedItem = WidgetItemSchema.parse(item);
validatedItems.push(parsedItem);
} catch {
continue;
}
}
const options = validatedItems.map((item) => ({
label: `${item.name || item.display_name || 'Unnamed'} (${item.widget_type} - ${item.widget_provider || 'No Provider'})`,
value: item.id,
}));
return {
disabled: false,
options,
};
} catch {
return {
disabled: true,
options: [],
placeholder: 'Failed to load widgets'
};
}
},
}),
attributes: Property.Object({
displayName: 'Attributes',
description: 'Additional campaign attributes as key-value pairs',
required: false,
}),
status: Property.StaticDropdown({
displayName: 'Status',
required: false,
options: {
options: [
{ label: 'Not Started', value: 'not_started' },
{ label: 'To Be Run', value: 'to_be_run' },
{ label: 'In Progress', value: 'in_progress' },
{ label: 'Paused', value: 'paused' },
{ label: 'Cancelled', value: 'cancelled' },
{ label: 'Completed', value: 'completed' },
],
},
}),
execution_weekdays: Property.Array({
displayName: 'Execution Weekdays',
description: 'Weekdays as numbers (e.g., [1, 2, 3] for Mon, Tue, Wed)',
required: false,
}),
time_window_start: Property.ShortText({
displayName: 'Time Window Start',
description: 'Start time in HH:MM format',
required: false,
}),
time_window_end: Property.ShortText({
displayName: 'Time Window End',
description: 'End time in HH:MM format',
required: false,
}),
time_zone: Property.ShortText({
displayName: 'Time Zone',
description: 'Time zone (defaults to UTC)',
required: false,
defaultValue: 'UTC',
}),
enabled: Property.Checkbox({
displayName: 'Enabled',
required: false,
defaultValue: false,
}),
},
async run(context) {
try {
const name = context.propsValue['name'];
const type = context.propsValue['type'];
const start_time = context.propsValue['start_time'];
const interval = context.propsValue['interval'];
const widget_id = context.propsValue['widget_id'];
const attributes = context.propsValue['attributes'];
const status = context.propsValue['status'];
const execution_weekdays = context.propsValue['execution_weekdays'];
const time_window_start = context.propsValue['time_window_start'];
const time_window_end = context.propsValue['time_window_end'];
const time_zone = context.propsValue['time_zone'];
const enabled = context.propsValue['enabled'];
if (!name) {
throw new Error('Campaign name is required');
}
if (!type) {
throw new Error('Campaign type is required');
}
if (!start_time) {
throw new Error('Start time is required');
}
if (!interval || interval <= 0) {
throw new Error('Interval must be a positive number');
}
const apiKey = context.auth.secret_text;
const url = `https://api.insighto.ai/api/v1/campaign/create`;
const queryParams: Record<string, string> = {
api_key: apiKey,
};
const body: any = {
name,
type,
start_time,
interval,
};
if (widget_id) body.widget_id = widget_id;
if (attributes) body.attributes = attributes;
if (status) body.status = status;
if (execution_weekdays) body.execution_weekdays = execution_weekdays;
if (time_window_start) body.time_window_start = time_window_start;
if (time_window_end) body.time_window_end = time_window_end;
if (time_zone) body.time_zone = time_zone;
if (enabled !== undefined) body.enabled = enabled;
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
url,
queryParams,
body,
headers: {
'Content-Type': 'application/json',
},
});
if (!response.body) {
throw new Error('No response received from Insighto.ai API');
}
return response.body;
} catch (error) {
if (error instanceof Error) {
throw new Error(`Failed to create campaign: ${error.message}`);
}
throw new Error('Failed to create campaign');
}
},
});

View File

@@ -0,0 +1,146 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
import { WidgetItemSchema, WidgetItem } from '../schemas';
import { insightoAuth } from '../..';
export const makeOutboundCallAction = createAction({
name: 'make_outbound_call',
displayName: 'Make Outbound Call',
description: 'Initiate an outbound call to a phone number using a configured widget',
auth: insightoAuth,
props: {
widget_id: Property.Dropdown({
auth: insightoAuth,
displayName: 'Widget',
description: 'Widget connected to Twilio, Plivo, or Telnyx for making calls',
required: true,
refreshers: [],
options: async ({ auth }) => {
if (!auth) {
return {
disabled: true,
options: [],
placeholder: 'Please authenticate first'
};
}
try {
const apiKey = auth.secret_text;
const url = `https://api.insighto.ai/api/v1/widget`;
const queryParams: Record<string, string> = {
api_key: apiKey,
page: '1',
size: '100', // Get more widgets for better UX
};
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url,
queryParams,
headers: {
'Content-Type': 'application/json',
},
});
const data = response.body.data;
if (!data || !data.items) {
return {
disabled: true,
options: [],
placeholder: 'No widgets found'
};
}
// Validate the response data
const validatedItems: WidgetItem[] = [];
for (const item of data.items) {
try {
const parsedItem = WidgetItemSchema.parse(item);
validatedItems.push(parsedItem);
} catch {
continue;
}
}
const options = validatedItems.map((item) => ({
label: `${item.name || item.display_name || 'Unnamed'} (${item.widget_type} - ${item.widget_provider || 'No Provider'})`,
value: item.id,
}));
return {
disabled: false,
options,
};
} catch {
return {
disabled: true,
options: [],
placeholder: 'Failed to load widgets'
};
}
},
}),
to: Property.ShortText({
displayName: 'Phone Number',
description: 'Phone number in E.164 format (e.g., 16501234567)',
required: true,
}),
prompt_dynamic_variables: Property.Object({
displayName: 'Dynamic Variables',
description: 'Variables for call prompts (e.g., {"name": "Bob", "appointment": "tomorrow"})',
required: false,
}),
},
async run(context) {
try {
const widget_id = context.propsValue['widget_id'];
const to = context.propsValue['to'];
const prompt_dynamic_variables = context.propsValue['prompt_dynamic_variables'];
if (!widget_id) {
throw new Error('Widget is required. Please select a widget from the dropdown.');
}
if (!to) {
throw new Error('Phone number is required.');
}
const apiKey = context.auth.secret_text;
const url = `https://api.insighto.ai/api/v1/call/${widget_id}`;
const queryParams: Record<string, string> = {
api_key: apiKey,
};
const body: any = {
to,
};
if (prompt_dynamic_variables) {
body.prompt_dynamic_variables = prompt_dynamic_variables;
}
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
url,
queryParams,
body,
headers: {
'Content-Type': 'application/json',
},
});
if (!response.body) {
throw new Error('No response received from Insighto.ai API');
}
return response.body;
} catch (error) {
if (error instanceof Error) {
throw new Error(`Failed to make outbound call: ${error.message}`);
}
throw new Error('Failed to make outbound call');
}
},
});

View File

@@ -0,0 +1,74 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
import { insightoAuth } from '../..';
export const upsertContactAction = createAction({
name: 'upsert_contact',
displayName: 'Upsert Contact',
description: 'Create or update a contact using email or phone number',
auth: insightoAuth,
props: {
first_name: Property.ShortText({
displayName: 'First Name',
required: false,
}),
last_name: Property.ShortText({
displayName: 'Last Name',
required: false,
}),
email: Property.ShortText({
displayName: 'Email',
description: 'Email address of the contact',
required: false,
}),
phone_number: Property.ShortText({
displayName: 'Phone Number',
description: 'Phone number including country code (e.g., 16501111234)',
required: false,
}),
},
async run(context) {
try {
const first_name = context.propsValue['first_name'];
const last_name = context.propsValue['last_name'];
const email = context.propsValue['email'];
const phone_number = context.propsValue['phone_number'];
if (!email && !phone_number) {
throw new Error('Either email or phone number must be provided');
}
const apiKey = context.auth.secret_text;
const url = `https://api.insighto.ai/api/v1/contact/upsert`;
const queryParams: Record<string, string> = {
api_key: apiKey,
};
if (first_name) queryParams['first_name'] = first_name;
if (last_name) queryParams['last_name'] = last_name;
if (email) queryParams['email'] = email;
if (phone_number) queryParams['phone_number'] = phone_number;
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
url,
queryParams,
headers: {
'Content-Type': 'application/json',
},
});
if (!response.body) {
throw new Error('No response received from Insighto.ai API');
}
return response.body;
} catch (error) {
if (error instanceof Error) {
throw new Error(`Failed to upsert contact: ${error.message}`);
}
throw new Error('Failed to upsert contact');
}
},
});

View File

@@ -0,0 +1,148 @@
import { z } from 'zod';
// Conversation schema for new-conversation trigger
export const ConversationItemSchema = z.object({
id: z.string(),
widget_id: z.string(),
assistant_id: z.string(),
assistant_name: z.string().optional(),
attributes: z.string().optional(),
first_message: z.string().optional(),
device_type: z.string().optional(),
created_at: z.string(),
updated_at: z.string(),
chat_count: z.number(),
includes_voice: z.boolean(),
intent_name: z.string().optional(),
contact_id: z.string(),
contact_first_name: z.string().optional(),
contact_last_name: z.string().optional(),
summary: z.string().optional(),
widget_type: z.string().optional(),
widget_provider: z.string().optional(),
});
export type ConversationItem = z.infer<typeof ConversationItemSchema>;
// Contact schema for new-contact trigger
export const ContactItemSchema = z.object({
id: z.string(),
first_name: z.string().optional(),
last_name: z.string().optional(),
email: z.string().optional(),
channels: z.record(z.string(), z.unknown()).optional(),
user_attributes: z.record(z.string(), z.unknown()).optional(),
last_seen: z.string().optional(),
last_sent: z.string().optional(),
org_id: z.string().optional(),
first_assistant_id: z.string().optional(),
last_assistant_id: z.string().optional(),
first_widget_id: z.string().optional(),
last_widget_id: z.string().optional(),
custom_fields: z.record(z.string(), z.unknown()).optional(),
created_at: z.string(),
});
export type ContactItem = z.infer<typeof ContactItemSchema>;
// Form schema for new-captured-form trigger
export const FormItemSchema = z.object({
id: z.string(),
name: z.string().optional(),
email: z.string().optional(),
phone_number: z.string().optional(),
created_at: z.string(),
updated_at: z.string(),
}).catchall(z.any()); // Allow additional properties
export type FormItem = z.infer<typeof FormItemSchema>;
// Webhook payload schema for captured_form.created event
export const CapturedFormWebhookSchema = z.object({
id: z.string().uuid(),
object: z.literal("event"),
event: z.literal("captured_form.created"),
created_at: z.string(),
data: z.object({
captured_form_id: z.string().uuid(),
form_id: z.string().uuid(),
conversation_id: z.string().uuid(),
widget_id: z.string().uuid(),
assistant_id: z.string().uuid(),
form_name: z.string(),
field_values: z.record(z.string(), z.unknown()),
attributes: z.record(z.string(), z.unknown()),
}),
});
export type CapturedFormWebhook = z.infer<typeof CapturedFormWebhookSchema>;
// Webhook payload schema for conversation.updated event
export const ConversationWebhookSchema = z.object({
id: z.string().uuid(),
object: z.literal("event"),
event: z.literal("conversation.updated"),
created_at: z.string(),
data: z.object({
conversation_id: z.string().uuid(),
widget_id: z.string().uuid(),
assistant_id: z.string().uuid(),
device_type: z.enum(["mobile", "native", "desktop", "tablet", "phone"]),
contact_id: z.string().uuid(),
chat_count: z.number(),
transcript: z.array(z.object({
conversation_id: z.string().uuid().nullable(),
sender_type: z.enum(["bot", "agent", "user", "tool"]).nullable(),
message_type: z.enum(["voice", "text"]).nullable(),
text: z.string(),
voice_base64: z.string().nullable(),
data_sources: z.array(z.any()).nullable(),
id: z.string().uuid(),
updated_at: z.string().nullable(),
created_at: z.string().nullable(),
char_count: z.number().nullable(),
})),
attributes: z.record(z.string(), z.unknown()),
}),
});
export type ConversationWebhook = z.infer<typeof ConversationWebhookSchema>;
// Assistant schema for dropdown options
export const AssistantItemSchema = z.object({
id: z.string(),
name: z.string().optional(),
assistant_type: z.string(),
llm_model: z.string(),
});
export type AssistantItem = z.infer<typeof AssistantItemSchema>;
// Widget schema for dropdown options
export const WidgetItemSchema = z.object({
id: z.string(),
name: z.string().optional(),
display_name: z.string().optional(),
widget_type: z.string(),
widget_provider: z.string().optional(),
});
export type WidgetItem = z.infer<typeof WidgetItemSchema>;
// Data source schema for dropdown options
export const DataSourceItemSchema = z.object({
id: z.string(),
name: z.string().optional(),
ds_type: z.string(),
});
export type DataSourceItem = z.infer<typeof DataSourceItemSchema>;
// API Response wrapper schema
export const ApiResponseSchema = z.object({
data: z.object({
items: z.array(z.any()),
}).optional(),
});
export type ApiResponse = z.infer<typeof ApiResponseSchema>;

View File

@@ -0,0 +1,85 @@
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
import { CapturedFormWebhookSchema } from '../schemas';
import { insightoAuth } from '../..';
export const newCapturedForm = createTrigger({
name: 'new_captured_form',
displayName: 'New Captured Form',
description: 'Fires when a new form submission is captured in Insighto.ai',
props: {},
auth: insightoAuth,
sampleData: {
id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
object: 'event',
event: 'captured_form.created',
created_at: '2023-11-07T05:31:56Z',
data: {
captured_form_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
form_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
conversation_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
widget_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
assistant_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
form_name: 'Contact Form',
field_values: {
first_name: 'Joe',
last_name: 'Doe'
},
attributes: {}
}
},
type: TriggerStrategy.WEBHOOK,
async onEnable(context) {
const webhookUrl = context.webhookUrl;
const apiKey = context.auth.secret_text;
try {
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
url: 'https://api.insighto.ai/api/v1/outbound_webhook',
queryParams: { api_key: apiKey },
body: {
endpoint: webhookUrl,
name: 'Activepieces Captured Form Webhook',
enabled: true,
},
headers: {
'Content-Type': 'application/json',
},
});
await context.store.put('webhook_id', response.body.data?.id);
} catch (error) {
throw new Error(`Failed to register webhook: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
},
async onDisable(context) {
const webhookId = await context.store.get('webhook_id');
if (!webhookId) return;
const apiKey = context.auth.secret_text;
try {
await httpClient.sendRequest({
method: HttpMethod.DELETE,
url: `https://api.insighto.ai/api/v1/outbound_webhook/${webhookId}`,
queryParams: { api_key: apiKey },
});
} catch {
// Webhook deletion failed, ignore error
}
await context.store.delete('webhook_id');
},
async run(context) {
const payload = context.payload.body;
try {
// Validate webhook payload
const validatedPayload = CapturedFormWebhookSchema.parse(payload);
return [validatedPayload];
} catch {
return [];
}
},
});

View File

@@ -0,0 +1,95 @@
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
import { ContactItemSchema, ContactItem } from '../schemas';
import { insightoAuth } from '../..';
export const newContact = createTrigger({
name: 'new_contact',
displayName: 'New Contact',
description: 'Triggers when a new contact is created',
props: {},
auth: insightoAuth,
sampleData: {
id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
first_name: 'John',
last_name: 'Doe',
email: 'john.doe@example.com',
channels: {},
user_attributes: {},
last_seen: '2023-11-07T05:31:56Z',
last_sent: '2023-11-07T05:31:56Z',
org_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
first_assistant_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
last_assistant_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
first_widget_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
last_widget_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
custom_fields: {},
created_at: '2023-11-07T05:31:56Z'
},
type: TriggerStrategy.POLLING,
async onEnable(context) {
// Initialize with empty seen contacts
await context.store.put('seen_contacts', []);
},
async onDisable(context) {
await context.store.delete('seen_contacts');
},
async run(context) {
try {
const apiKey = context.auth.secret_text;
const url = `https://api.insighto.ai/api/v1/contact`;
const queryParams: Record<string, string> = {
api_key: apiKey,
page: '1',
size: '100',
};
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url,
queryParams,
headers: {
'Content-Type': 'application/json',
},
});
const data = response.body.data;
if (!data || !data.items) {
return [];
}
const validatedContacts: ContactItem[] = [];
for (const contact of data.items) {
try {
const validContact = ContactItemSchema.parse(contact);
validatedContacts.push(validContact);
} catch {
continue;
}
}
const seenContacts = (await context.store.get<string[]>('seen_contacts')) || [];
const newContacts: ContactItem[] = [];
const allContactIds = validatedContacts.map(c => c.id);
for (const contact of validatedContacts) {
if (!seenContacts.includes(contact.id)) {
newContacts.push(contact);
}
}
if (newContacts.length > 0) {
const updatedSeenContacts = [...new Set([...seenContacts, ...allContactIds])];
await context.store.put('seen_contacts', updatedSeenContacts.slice(-1000));
}
return newContacts;
} catch (error) {
if (error instanceof Error) {
throw new Error(`Failed to fetch contacts: ${error.message}`);
}
throw new Error('Failed to fetch contacts');
}
},
});

View File

@@ -0,0 +1,107 @@
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
import { ConversationWebhookSchema } from '../schemas';
import { insightoAuth } from '../..';
export const newConversation = createTrigger({
name: 'new_conversation',
displayName: 'New Conversation',
description: 'Fires when an existing conversation is updated with a new message',
props: {},
auth: insightoAuth,
sampleData: {
id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
object: 'event',
event: 'conversation.updated',
created_at: '2023-11-07T05:31:56Z',
data: {
conversation_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
widget_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
assistant_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
device_type: 'mobile',
contact_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
chat_count: 5,
transcript: [
{
conversation_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
sender_type: 'user',
message_type: 'text',
text: 'Hello, I need help with my order',
voice_base64: null,
data_sources: [],
id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
updated_at: '2023-11-07T05:31:56Z',
created_at: '2023-11-07T05:31:56Z',
char_count: 30
},
{
conversation_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
sender_type: 'bot',
message_type: 'text',
text: 'I\'d be happy to help you with your order. Could you please provide your order number?',
voice_base64: null,
data_sources: null,
id: '3c90c3cc-0d44-4b50-8888-8dd25736052b',
updated_at: '2023-11-07T05:32:10Z',
created_at: '2023-11-07T05:32:10Z',
char_count: 85
}
],
attributes: {}
}
},
type: TriggerStrategy.WEBHOOK,
async onEnable(context) {
const webhookUrl = context.webhookUrl;
const apiKey = context.auth.secret_text;
try {
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
url: 'https://api.insighto.ai/api/v1/outbound_webhook',
queryParams: { api_key: apiKey },
body: {
endpoint: webhookUrl,
name: 'Activepieces Conversation Webhook',
enabled: true,
},
headers: {
'Content-Type': 'application/json',
},
});
await context.store.put('webhook_id', response.body.data?.id);
} catch (error) {
throw new Error(`Failed to register webhook: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
},
async onDisable(context) {
const webhookId = await context.store.get('webhook_id');
if (!webhookId) return;
const apiKey = context.auth.secret_text;
try {
await httpClient.sendRequest({
method: HttpMethod.DELETE,
url: `https://api.insighto.ai/api/v1/outbound_webhook/${webhookId}`,
queryParams: { api_key: apiKey },
});
} catch {
// Webhook deletion failed, ignore error
}
await context.store.delete('webhook_id');
},
async run(context) {
const payload = context.payload.body;
try {
// Validate webhook payload
const validatedPayload = ConversationWebhookSchema.parse(payload);
return [validatedPayload];
} catch {
return [];
}
},
});

View File

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

View File

@@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../../dist/out-tsc",
"declaration": true,
"types": ["node"]
},
"include": ["src/**/*.ts"]
}