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,42 @@
import { createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
httpClient,
HttpMethod,
} from '@activepieces/pieces-common';
import { bubbleAuth } from '../../index';
import { bubbleCommon } from '../common';
export const bubbleCreateThingAction = createAction({
auth: bubbleAuth,
name: 'bubble_create_thing',
displayName: 'Create Thing',
description: 'Create a thing',
props: {
typename: bubbleCommon.typename,
fields: bubbleCommon.fields,
},
async run(context) {
const { appname, token } = context.auth.props;
const { typename, fields } = context.propsValue;
const server_url = `https://${appname}.bubbleapps.io/api/1.1/obj/${typename}`;
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
url: server_url,
headers: {
'user-agent': 'activepieces',
Authorization: `Bearer ${token}`,
},
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
body: fields,
});
return response.body;
},
});

View File

@@ -0,0 +1,41 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import {
AuthenticationType,
httpClient,
HttpMethod,
} from '@activepieces/pieces-common';
import { bubbleAuth } from '../../index';
import { bubbleCommon } from '../common';
export const bubbleDeleteThingAction = createAction({
auth: bubbleAuth,
name: 'bubble_delete_thing',
displayName: 'Delete Thing',
description: 'Delete a thing',
props: {
typename: bubbleCommon.typename,
thing_id: bubbleCommon.thing_id,
},
async run(context) {
const { appname, token } = context.auth.props;
const { typename, thing_id } = context.propsValue;
const server_url = `https://${appname}.bubbleapps.io/api/1.1/obj/${typename}/${thing_id}`;
const response = await httpClient.sendRequest({
method: HttpMethod.DELETE,
url: server_url,
headers: {
'user-agent': 'activepieces',
Authorization: `Bearer ${token}`,
},
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
});
return response.body;
},
});

View File

@@ -0,0 +1,44 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import {
AuthenticationType,
httpClient,
HttpMethod,
} from '@activepieces/pieces-common';
import { bubbleAuth } from '../../index';
import { bubbleCommon } from '../common';
export const bubbleGetThingAction = createAction({
auth: bubbleAuth,
name: 'bubble_get_thing',
displayName: 'Get Thing',
description: 'Get a thing by id',
props: {
typename: bubbleCommon.typename,
thing_id: bubbleCommon.thing_id,
},
async run(context) {
const { appname, token } = context.auth.props;
const { typename, thing_id } = context.propsValue;
const server_url = `https://${appname}.bubbleapps.io/api/1.1/obj/${typename}`;
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url: server_url,
headers: {
'user-agent': 'activepieces',
Authorization: `Bearer ${token}`,
},
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
body: {
constraint: `id = ${thing_id}`,
},
});
return response.body;
},
});

View File

@@ -0,0 +1,101 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import {
AuthenticationType,
httpClient,
HttpMethod,
} from '@activepieces/pieces-common';
import { bubbleAuth } from '../../index';
import { bubbleCommon } from '../common';
export const bubbleListThingsAction = createAction({
auth: bubbleAuth,
name: 'bubble_list_things',
displayName: 'List Thing',
description: 'List things by type',
props: {
typename: bubbleCommon.typename,
constraint: Property.StaticDropdown({
displayName: 'Constraint',
required: true,
options: {
options: [
{
label: 'equals or not equal',
value: 'equals or not equal',
},
{
label: 'text contains or not text contains',
value: 'text contains or not text contains',
},
{
label: 'greater than or less than',
value: 'greater than or less than',
},
{
label: 'in or not in',
value: 'in or not in',
},
{
label: 'contains or not contains',
value: 'contains or not contains',
},
{
label: 'empty or not empty',
value: 'empty or not empty',
},
{
label: 'geographic_search',
value: 'geographic_search',
},
],
},
}),
field: Property.ShortText({
displayName: 'Field',
required: true,
}),
value: Property.ShortText({
displayName: 'Value',
required: true,
}),
cursor: Property.Number({
displayName: 'Start from',
required: true,
}),
limit: Property.Number({
displayName: 'Limit',
required: true,
}),
},
async run(context) {
const { appname, token } = context.auth.props;
const { typename, constraint, field, value, cursor, limit } =
context.propsValue;
const server_url = `https://${appname}.bubbleapps.io/api/1.1/obj/${typename}`;
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
url: server_url,
headers: {
'user-agent': 'activepieces',
Authorization: `Bearer ${token}`,
},
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
body: {
constraint: constraint,
field: field,
value: value,
cursor: cursor,
limit: limit,
},
});
return response.body;
},
});

View File

@@ -0,0 +1,43 @@
import { createAction } from '@activepieces/pieces-framework';
import {
AuthenticationType,
httpClient,
HttpMethod,
} from '@activepieces/pieces-common';
import { bubbleAuth } from '../../index';
import { bubbleCommon } from '../common';
export const bubbleUpdateThingAction = createAction({
auth: bubbleAuth,
name: 'bubble_update_thing',
displayName: 'Update Thing',
description: 'Updates a thing',
props: {
typename: bubbleCommon.typename,
thing_id: bubbleCommon.thing_id,
fields: bubbleCommon.fields,
},
async run(context) {
const { appname, token } = context.auth.props;
const { typename, thing_id } = context.propsValue;
const server_url = `https://${appname}.bubbleapps.io/api/1.1/obj/${typename}/${thing_id}`;
const response = await httpClient.sendRequest({
method: HttpMethod.PATCH,
url: server_url,
headers: {
'user-agent': 'activepieces',
Authorization: `Bearer ${token}`,
},
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
body: context.propsValue.fields,
});
return response.body;
},
});

View File

@@ -0,0 +1,16 @@
import { Property } from '@activepieces/pieces-framework';
export const bubbleCommon = {
typename: Property.ShortText({
displayName: 'Typename',
required: true,
}),
fields: Property.Json({
displayName: 'Body',
required: false,
}),
thing_id: Property.ShortText({
displayName: 'Thing ID',
required: true,
}),
};