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,21 @@
{
"Send Request": "Anfrage senden",
"Makes a GraphQL request.": "Macht eine GraphQL-Anfrage.",
"Method": "Methode",
"URL": "URL",
"Query params": "Abfrageparameter",
"Headers": "Kopfzeilen",
"Query": "Abfrage",
"Variables": "Variablen",
"Use Proxy": "Proxy verwenden",
"Proxy Settings": "Proxy-Einstellungen",
"Timeout(in seconds)": "Zeitüberschreitung (in Sekunden)",
"No Error on Failure": "Kein Fehler bei Fehler",
"Use a proxy for this request": "Proxy für diese Anfrage verwenden",
"GET": "ERHALTEN",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "LÖSCHEN",
"HEAD": "HEAD"
}

View File

@@ -0,0 +1,21 @@
{
"Send Request": "Enviar Solicitud",
"Makes a GraphQL request.": "Realiza una solicitud GraphQL.",
"Method": "Método",
"URL": "URL",
"Query params": "Parámetros de consulta",
"Headers": "Encabezados",
"Query": "Consulta",
"Variables": "Variables",
"Use Proxy": "Usar proxy",
"Proxy Settings": "Ajustes del proxy",
"Timeout(in seconds)": "Tiempo de espera (en segundos)",
"No Error on Failure": "No hay ningún error en fallo",
"Use a proxy for this request": "Usar un proxy para esta solicitud",
"GET": "RECOGER",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "BORRAR",
"HEAD": "LIMPIO"
}

View File

@@ -0,0 +1,21 @@
{
"Send Request": "Envoyer la demande",
"Makes a GraphQL request.": "Fait une requête GraphQL.",
"Method": "Méthode",
"URL": "URL",
"Query params": "Paramètres de requête",
"Headers": "En-têtes",
"Query": "Requête",
"Variables": "Variables",
"Use Proxy": "Utiliser le proxy",
"Proxy Settings": "Paramètres du proxy",
"Timeout(in seconds)": "Délai d'attente (en secondes)",
"No Error on Failure": "Aucune erreur en cas d'échec",
"Use a proxy for this request": "Utiliser un proxy pour cette requête",
"GET": "OBTENIR",
"POST": "POSTER",
"PATCH": "PATCH",
"PUT": "EFFACER",
"DELETE": "SUPPRIMER",
"HEAD": "HEAD"
}

View File

@@ -0,0 +1,21 @@
{
"Send Request": "リクエストを送信",
"Makes a GraphQL request.": "GraphQLリクエストを作成します。",
"Method": "方法",
"URL": "URL",
"Query params": "クエリパラメータ",
"Headers": "ヘッダー",
"Query": "クエリ",
"Variables": "変数",
"Use Proxy": "プロキシを使用",
"Proxy Settings": "プロキシ設定",
"Timeout(in seconds)": "タイムアウト(秒単位)",
"No Error on Failure": "失敗時にエラーはありません",
"Use a proxy for this request": "このリクエストにプロキシを使用する",
"GET": "取得",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "削除",
"HEAD": "頭"
}

View File

@@ -0,0 +1,21 @@
{
"Send Request": "Verzoek verzenden",
"Makes a GraphQL request.": "Maakt een GraphQL aanvraag.",
"Method": "Methode",
"URL": "URL",
"Query params": "Query parameters",
"Headers": "Kopteksten",
"Query": "Zoekopdracht",
"Variables": "Variabelen",
"Use Proxy": "Gebruik Proxy",
"Proxy Settings": "Proxy Instellingen",
"Timeout(in seconds)": "Timeout(in seconden)",
"No Error on Failure": "Geen fout bij fout",
"Use a proxy for this request": "Gebruik een proxy voor dit verzoek",
"GET": "KRIJG",
"POST": "POSTE",
"PATCH": "BEKIJK",
"PUT": "PUT",
"DELETE": "VERWIJDEREN",
"HEAD": "HOOFD"
}

View File

@@ -0,0 +1,21 @@
{
"Send Request": "Enviar solicitação",
"Makes a GraphQL request.": "Faz uma solicitação GraphQL.",
"Method": "Método",
"URL": "URL:",
"Query params": "Consultar parâmetros",
"Headers": "Cabeçalhos",
"Query": "Requisição",
"Variables": "Variáveis",
"Use Proxy": "Usar Proxy",
"Proxy Settings": "Configurações do Proxy",
"Timeout(in seconds)": "Tempo limite (em segundos)",
"No Error on Failure": "Nenhum erro no Failure",
"Use a proxy for this request": "Usar um proxy para esta requisição",
"GET": "OBTER",
"POST": "POSTAR",
"PATCH": "COMPRAR",
"PUT": "COLOCAR",
"DELETE": "EXCLUIR",
"HEAD": "CABEÇA"
}

View File

@@ -0,0 +1,22 @@
{
"GraphQL": "GraphQL",
"Send Request": "Отправить запрос",
"Makes a GraphQL request.": "Делает запрос GraphQL.",
"Method": "Метод",
"URL": "URL",
"Query params": "Параметры запроса",
"Headers": "Заголовки",
"Query": "Запрос",
"Variables": "Переменные",
"Use Proxy": "Использовать прокси",
"Proxy Settings": "Настройки прокси",
"Timeout(in seconds)": "Тайм-аут (в секундах)",
"No Error on Failure": "Нет ошибок при ошибке",
"Use a proxy for this request": "Использовать прокси для этого запроса",
"GET": "ПОЛУЧИТЬ",
"POST": "ПОСТ",
"PATCH": "ПАТЧ",
"PUT": "ПОКУПИТЬ",
"DELETE": "УДАЛИТЬ",
"HEAD": "HEAD"
}

View File

@@ -0,0 +1,21 @@
{
"Send Request": "Send Request",
"Makes a GraphQL request.": "Makes a GraphQL request.",
"Method": "Method",
"URL": "URL",
"Query params": "Query params",
"Headers": "Headers",
"Query": "Query",
"Variables": "Variables",
"Use Proxy": "Use Proxy",
"Proxy Settings": "Proxy Settings",
"Timeout(in seconds)": "Timeout(in seconds)",
"No Error on Failure": "No Error on Failure",
"Use a proxy for this request": "Use a proxy for this request",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD"
}

View File

@@ -0,0 +1,22 @@
{
"GraphQL": "GraphQL",
"Send Request": "Send Request",
"Makes a GraphQL request.": "Makes a GraphQL request.",
"Method": "Method",
"URL": "URL",
"Query params": "Query params",
"Headers": "Headers",
"Query": "Query",
"Variables": "Variables",
"Use Proxy": "Use Proxy",
"Proxy Settings": "Proxy Settings",
"Timeout(in seconds)": "Timeout(in seconds)",
"No Error on Failure": "No Error on Failure",
"Use a proxy for this request": "Use a proxy for this request",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD"
}

View File

@@ -0,0 +1,21 @@
{
"Send Request": "Send Request",
"Makes a GraphQL request.": "Makes a GraphQL request.",
"Method": "方法",
"URL": "URL",
"Query params": "Query params",
"Headers": "信头",
"Query": "Query",
"Variables": "Variables",
"Use Proxy": "Use Proxy",
"Proxy Settings": "Proxy Settings",
"Timeout(in seconds)": "Timeout(in seconds)",
"No Error on Failure": "失败时没有错误",
"Use a proxy for this request": "Use a proxy for this request",
"GET": "获取",
"POST": "帖子",
"PATCH": "PATCH",
"PUT": "弹出",
"DELETE": "删除",
"HEAD": "黑色"
}

View File

@@ -0,0 +1,16 @@
import { createPiece, PieceAuth } from "@activepieces/pieces-framework";
import { query } from "./lib/actions/query";
import { PieceCategory } from "@activepieces/shared";
export const graphql = createPiece({
displayName: "GraphQL",
auth: PieceAuth.None(),
minimumSupportedRelease: '0.30.0',
logoUrl: "https://cdn.activepieces.com/pieces/graphql.svg",
categories:[PieceCategory.CORE],
authors: ['mahmuthamet'],
actions: [query],
triggers: [],
});

View File

@@ -0,0 +1,153 @@
import {
httpClient,
HttpError,
HttpHeaders,
HttpRequest,
QueryParams,
} from '@activepieces/pieces-common';
import {
createAction,
DynamicPropsValue,
PieceAuth,
Property,
} from '@activepieces/pieces-framework';
import { assertNotNullOrUndefined } from '@activepieces/shared';
import { httpMethodDropdown } from '../common/props';
import { HttpsProxyAgent } from 'https-proxy-agent';
import axios from 'axios';
export const query = createAction({
name: 'send_request',
displayName: 'Send Request',
description: 'Makes a GraphQL request.',
props: {
method: httpMethodDropdown,
url: Property.ShortText({
displayName: 'URL',
required: true,
}),
queryParams: Property.Object({
displayName: 'Query params',
required: true,
}),
headers: Property.Object({
displayName: 'Headers',
required: true,
}),
query: Property.LongText({
displayName: 'Query',
required: true,
}),
variables: Property.Json({
displayName: 'Variables',
required: false,
}),
use_proxy: Property.Checkbox({
displayName: 'Use Proxy',
defaultValue: false,
description: 'Use a proxy for this request',
required: false,
}),
proxy_settings: Property.DynamicProperties({
displayName: 'Proxy Settings',
auth: PieceAuth.None(),
refreshers: ['use_proxy'],
required: false,
props: async ({ use_proxy }) => {
if (!use_proxy) return {};
const fields: DynamicPropsValue = {};
fields['proxy_host'] = Property.ShortText({
displayName: 'Proxy Host',
required: true,
});
fields['proxy_port'] = Property.Number({
displayName: 'Proxy Port',
required: true,
});
fields['proxy_username'] = Property.ShortText({
displayName: 'Proxy Username',
required: false,
});
fields['proxy_password'] = Property.ShortText({
displayName: 'Proxy Password',
required: false,
});
return fields;
},
}),
timeout: Property.Number({
displayName: 'Timeout(in seconds)',
required: false,
}),
failsafe: Property.Checkbox({
displayName: 'No Error on Failure',
required: false,
}),
},
errorHandlingOptions: {
continueOnFailure: { hide: true },
retryOnFailure: { defaultValue: true },
},
async run(context) {
const {
method,
url,
headers,
queryParams,
query,
variables,
timeout,
failsafe,
use_proxy,
} = context.propsValue;
assertNotNullOrUndefined(method, 'Method');
assertNotNullOrUndefined(url, 'URL');
const request: HttpRequest = {
method,
url,
queryParams: queryParams as QueryParams,
headers: headers as HttpHeaders,
timeout: timeout ? timeout * 1000 : 0,
body: JSON.stringify({ query, variables }),
};
try {
if (use_proxy) {
const proxySettings = context.propsValue.proxy_settings;
assertNotNullOrUndefined(proxySettings, 'Proxy Settings');
assertNotNullOrUndefined(proxySettings['proxy_host'], 'Proxy Host');
assertNotNullOrUndefined(proxySettings['proxy_port'], 'Proxy Port');
let proxyUrl;
if (proxySettings['proxy_username'] && proxySettings['proxy_password']) {
proxyUrl = `http://${proxySettings['proxy_username']}:${proxySettings['proxy_password']}@${proxySettings['proxy_host']}:${proxySettings['proxy_port']}`;
} else {
proxyUrl = `http://${proxySettings['proxy_host']}:${proxySettings['proxy_port']}`;
}
const httpsAgent = new HttpsProxyAgent(proxyUrl)
const axiosClient = axios.create({
httpsAgent,
});
const proxied_response = await axiosClient.request(request);
return proxied_response.data;
}
return await httpClient.sendRequest(request);
} catch (error) {
if (failsafe) {
return (error as HttpError).errorMessage();
}
throw error;
}
},
});

View File

@@ -0,0 +1,14 @@
import { Property } from '@activepieces/pieces-framework';
import { HttpMethod } from '@activepieces/pieces-common';
const httpMethodDropdownOptions = Object.values(HttpMethod).map((m) => ({
label: m,
value: m,
}));
export const httpMethodDropdown = Property.StaticDropdown<HttpMethod>({
displayName: 'Method',
required: true,
options: { options: httpMethodDropdownOptions },
defaultValue: HttpMethod.POST,
});