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:
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Please use ***your-twin-labs-api-key*** as value for API Key": "Bitte verwenden Sie ***dein-twin-labs-api-key*** als Wert für den API-Schlüssel",
|
||||
"Browse": "Durchsuchen",
|
||||
"Browse the internet with an AI web navigation agent that can find information for you": "Durchsuchen Sie das Internet mit einem KI-Webnavigationsmakler, der Informationen für Sie finden kann",
|
||||
"startUrl": "startUrl",
|
||||
"Goal": "Ziel",
|
||||
"The URL where the browsing task should begin": "Die URL, in der die Browsing-Aufgabe beginnen soll",
|
||||
"The goal or objective of the browsing task": "Das Ziel oder Ziel der Browsing-Aufgabe"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Please use ***your-twin-labs-api-key*** as value for API Key": "Por favor usa ***tu-doble-labs-api-key*** como valor para la Clave API",
|
||||
"Browse": "Navegar",
|
||||
"Browse the internet with an AI web navigation agent that can find information for you": "Navegue por Internet con un agente de navegación web de IA que puede encontrar información para usted",
|
||||
"startUrl": "startUrl",
|
||||
"Goal": "Objetivo",
|
||||
"The URL where the browsing task should begin": "La URL donde debe comenzar la tarea de navegación",
|
||||
"The goal or objective of the browsing task": "El objetivo o objetivo de la tarea de navegación"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Please use ***your-twin-labs-api-key*** as value for API Key": "Veuillez utiliser ***your-twin-labs-api-key*** comme valeur pour la clé API",
|
||||
"Browse": "Parcourir",
|
||||
"Browse the internet with an AI web navigation agent that can find information for you": "Naviguez sur Internet avec un agent de navigation web IA qui peut trouver des informations pour vous",
|
||||
"startUrl": "startUrl",
|
||||
"Goal": "Objectif",
|
||||
"The URL where the browsing task should begin": "L'URL où la tâche de navigation doit commencer",
|
||||
"The goal or objective of the browsing task": "L'objectif ou l'objectif de la tâche de navigation"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Please use ***your-twin-labs-api-key*** as value for API Key": "API キーの値として ***your-twin-labs-api-key*** を使用してください",
|
||||
"Browse": "検索",
|
||||
"Browse the internet with an AI web navigation agent that can find information for you": "情報を見つけることができるAIウェブナビゲーションエージェントでインターネットを閲覧する",
|
||||
"startUrl": "startUrl",
|
||||
"Goal": "目標",
|
||||
"The URL where the browsing task should begin": "ブラウジングタスクが開始されるURL",
|
||||
"The goal or objective of the browsing task": "ブラウジングタスクの目標または目的"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Please use ***your-twin-labs-api-key*** as value for API Key": "Gebruik ***uw-twin-labs-api-sleutel*** als waarde voor API-sleutel",
|
||||
"Browse": "Bladeren",
|
||||
"Browse the internet with an AI web navigation agent that can find information for you": "Blader door het internet met een AI webnavigatieagent die informatie voor u kan vinden",
|
||||
"startUrl": "startUrl",
|
||||
"Goal": "Doel",
|
||||
"The URL where the browsing task should begin": "De URL waar de surftaak moet beginnen",
|
||||
"The goal or objective of the browsing task": "Het doel of doel van de surftaak"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Please use ***your-twin-labs-api-key*** as value for API Key": "Por favor, use ***sua-chave-duin-labs-api-*** como valor para a chave API",
|
||||
"Browse": "Localizar...",
|
||||
"Browse the internet with an AI web navigation agent that can find information for you": "Navegue pela internet com um agente de navegação por web AI que pode encontrar informações para você",
|
||||
"startUrl": "startUrl",
|
||||
"Goal": "Meta",
|
||||
"The URL where the browsing task should begin": "O URL onde a tarefa de navegação deve começar",
|
||||
"The goal or objective of the browsing task": "O objetivo ou objetivo da tarefa de navegação"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"Twin Web Agent": "Веб Агент Twin",
|
||||
"Please use ***your-twin-labs-api-key*** as value for API Key": "Пожалуйста, используйте ***your-twin-labs-api-key*** в качестве значения ключа API",
|
||||
"Browse": "Обзор",
|
||||
"Browse the internet with an AI web navigation agent that can find information for you": "Просмотреть интернет с агентом ИИ веб-навигации, который может найти информацию для вас",
|
||||
"startUrl": "startUrl",
|
||||
"Goal": "Цель",
|
||||
"The URL where the browsing task should begin": "URL-адрес, в котором должна начинаться задача просмотра",
|
||||
"The goal or objective of the browsing task": "Цель или цель браузерной задачи"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Please use ***your-twin-labs-api-key*** as value for API Key": "Please use ***your-twin-labs-api-key*** as value for API Key",
|
||||
"Browse": "Browse",
|
||||
"Browse the internet with an AI web navigation agent that can find information for you": "Browse the internet with an AI web navigation agent that can find information for you",
|
||||
"startUrl": "startUrl",
|
||||
"Goal": "Goal",
|
||||
"The URL where the browsing task should begin": "The URL where the browsing task should begin",
|
||||
"The goal or objective of the browsing task": "The goal or objective of the browsing task"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"Twin Web Agent": "Twin Web Agent",
|
||||
"Please use ***your-twin-labs-api-key*** as value for API Key": "Please use ***your-twin-labs-api-key*** as value for API Key",
|
||||
"Browse": "Browse",
|
||||
"Browse the internet with an AI web navigation agent that can find information for you": "Browse the internet with an AI web navigation agent that can find information for you",
|
||||
"startUrl": "startUrl",
|
||||
"Goal": "Mục tiêu",
|
||||
"The URL where the browsing task should begin": "The URL where the browsing task should begin",
|
||||
"The goal or objective of the browsing task": "The goal or objective of the browsing task"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Please use ***your-twin-labs-api-key*** as value for API Key": "Please use ***your-twin-labs-api-key*** as value for API Key",
|
||||
"Browse": "Browse",
|
||||
"Browse the internet with an AI web navigation agent that can find information for you": "Browse the internet with an AI web navigation agent that can find information for you",
|
||||
"startUrl": "startUrl",
|
||||
"Goal": "Goal",
|
||||
"The URL where the browsing task should begin": "The URL where the browsing task should begin",
|
||||
"The goal or objective of the browsing task": "The goal or objective of the browsing task"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
import { createPiece, PieceAuth } from "@activepieces/pieces-framework";
|
||||
import { startBrowsingTask } from "./lib/actions/start-browsing-task";
|
||||
|
||||
export const twinLabsAuth = PieceAuth.SecretText({
|
||||
displayName:'API Key',
|
||||
required:true,
|
||||
description:"Please use ***your-twin-labs-api-key*** as value for API Key"
|
||||
});
|
||||
|
||||
export const twinLabs = createPiece({
|
||||
displayName: "Twin Web Agent",
|
||||
auth: twinLabsAuth,
|
||||
minimumSupportedRelease: '0.20.0',
|
||||
logoUrl: "https://cdn.activepieces.com/pieces/twin-labs.png",
|
||||
authors: [],
|
||||
actions: [startBrowsingTask],
|
||||
triggers: [],
|
||||
});
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { twinLabsAuth } from '../..';
|
||||
|
||||
// API BASE URL
|
||||
const API_BASE_URL = 'https://paris.prod.api.twin.so';
|
||||
|
||||
export const startBrowsingTask = createAction({
|
||||
name: 'startBrowsingTask',
|
||||
auth: twinLabsAuth,
|
||||
displayName: 'Browse',
|
||||
description:
|
||||
'Browse the internet with an AI web navigation agent that can find information for you',
|
||||
props: {
|
||||
|
||||
|
||||
startUrl: Property.ShortText({
|
||||
displayName: 'startUrl',
|
||||
required: true,
|
||||
description: 'The URL where the browsing task should begin',
|
||||
defaultValue: '',
|
||||
}),
|
||||
|
||||
goal: Property.ShortText({
|
||||
displayName: 'Goal',
|
||||
required: true,
|
||||
description: 'The goal or objective of the browsing task',
|
||||
}),
|
||||
},
|
||||
|
||||
async run(context) {
|
||||
// Interface for the initial /browse
|
||||
interface BrowseStartResponse {
|
||||
url: string;
|
||||
universeId: string;
|
||||
worldId: number;
|
||||
unitId: number;
|
||||
}
|
||||
|
||||
// Interface for the GET polling
|
||||
interface BrowseStatusResponse {
|
||||
completed : boolean;
|
||||
pending?: boolean;
|
||||
output?: string;
|
||||
|
||||
}
|
||||
|
||||
// Start the browsing task
|
||||
const startRes = await httpClient.sendRequest<BrowseStartResponse>({
|
||||
method: HttpMethod.POST,
|
||||
url: `${API_BASE_URL}/browse`,
|
||||
headers: {
|
||||
'x-api-key': context.auth.secret_text,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: {
|
||||
goal: context.propsValue['goal'],
|
||||
startUrl: context.propsValue['startUrl'],
|
||||
outputType: 'string',
|
||||
completionCallbackUrl: 'https://',
|
||||
},
|
||||
});
|
||||
|
||||
const pollingUrl = startRes.body.url;
|
||||
let statusResponse: BrowseStatusResponse = {
|
||||
completed: false,
|
||||
pending: true,
|
||||
};
|
||||
const timeoutAt = Date.now() + 15 * 60 * 1000; // 15 minutes
|
||||
|
||||
|
||||
// Poll for task completion every 5 seconds until timeout
|
||||
while (!statusResponse.completed && Date.now() < timeoutAt) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 5_000)); // wait 5 seconds
|
||||
|
||||
const pollRes = await httpClient.sendRequest<BrowseStatusResponse>({
|
||||
method: HttpMethod.GET,
|
||||
url: pollingUrl,
|
||||
headers: {
|
||||
'x-api-key': context.auth.secret_text,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
statusResponse = pollRes.body; // update statusResponse with the latest response
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Return the final statusResponse in all cases
|
||||
return statusResponse;
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user