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,64 @@
import {
AuthenticationType,
HttpMethod,
HttpRequest,
httpClient,
} from '@activepieces/pieces-common';
import { OAuth2PropertyValue } from '@activepieces/pieces-framework';
export interface WebhookInformation {
id: string;
target: string;
type: string;
address: string;
created_at: string;
created_by: string;
triggers: string[];
}
export const common = {
baseUrl: 'https://api.box.com/2.0',
async subscribeWebhook(
auth: OAuth2PropertyValue,
data: {
event: string;
target: {
id: number | string;
type: string;
};
webhookUrl: string;
}
) {
const request: HttpRequest = {
method: HttpMethod.POST,
url: `${common.baseUrl}/webhooks`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: auth.access_token,
},
body: {
address: data.webhookUrl,
triggers: [data.event],
target: data.target,
},
};
const response = await httpClient.sendRequest<WebhookInformation>(request);
return response.body;
},
async unsubscribeWebhook(auth: OAuth2PropertyValue, webhookId: string) {
const request: HttpRequest = {
method: HttpMethod.DELETE,
url: `${common.baseUrl}/webhooks/${webhookId}`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: auth.access_token,
},
};
const response = await httpClient.sendRequest(request);
return response;
},
};

View File

@@ -0,0 +1,92 @@
import {
createTrigger,
TriggerStrategy,
Property,
} from '@activepieces/pieces-framework';
import { boxAuth } from '../..';
import { WebhookInformation, common } from '../common';
export const newComment = createTrigger({
auth: boxAuth,
name: 'new_comment',
displayName: 'New Comment',
description: 'Triggers when a comment is created',
type: TriggerStrategy.WEBHOOK,
props: {
id: Property.ShortText({
displayName: 'File/Folder ID',
description: 'The ID of the item to trigger a webhook',
required: true,
}),
type: Property.StaticDropdown({
displayName: 'Item Type',
description: 'The type of the item to trigger a webhook',
required: true,
options: {
options: [
{ label: 'File', value: 'file' },
{ label: 'Folder', value: 'folder' },
],
},
}),
},
async onEnable(context) {
const target: any = {
id: context.propsValue.id,
type: context.propsValue.type,
};
const webhook = await common.subscribeWebhook(context.auth, {
event: 'COMMENT.CREATED',
target: target,
webhookUrl: context.webhookUrl,
});
await context.store.put(`_new_comment_trigger`, webhook);
},
async onDisable(context) {
const webhook = await context.store.get<WebhookInformation>(
`_new_comment_trigger`
);
if (webhook) {
await common.unsubscribeWebhook(context.auth, webhook.id);
}
},
async run(context) {
return [context.payload.body];
},
sampleData: {
type: 'webhook_event',
id: '9a30442d-f681-4d25-8815-aa46f0515387',
created_at: '2023-04-19T13:25:07-07:00',
trigger: 'COMMENT.CREATED',
webhook: { id: '1396363668', type: 'webhook' },
created_by: {
type: 'user',
id: '24316851337',
name: 'Bonobo',
login: 'email@gmail.com',
},
source: {
id: '538146815',
type: 'comment',
is_reply_comment: false,
message: 'Simple times...',
created_by: {
type: 'user',
id: '24316851337',
name: 'Bonobo',
login: 'email@gmail.com',
},
created_at: '2023-04-19T13:25:07-07:00',
item: { id: '1194590019402', type: 'file' },
modified_at: '2023-04-19T13:25:07-07:00',
},
additional_info: [],
},
});

View File

@@ -0,0 +1,116 @@
import {
createTrigger,
TriggerStrategy,
Property,
} from '@activepieces/pieces-framework';
import { boxAuth } from '../..';
import { WebhookInformation, common } from '../common';
export const newFile = createTrigger({
auth: boxAuth,
name: 'new_file',
displayName: 'New File',
description: 'Triggers when a file is uploaded',
type: TriggerStrategy.WEBHOOK,
props: {
folder: Property.ShortText({
displayName: 'Folder ID',
description:
'The ID of the folder in which file uploads will trigger this webhook',
required: true,
}),
},
async onEnable(context) {
const target: any = {
id: context.propsValue.folder,
type: 'folder',
};
const webhook = await common.subscribeWebhook(context.auth, {
event: 'FILE.UPLOADED',
target: target,
webhookUrl: context.webhookUrl,
});
await context.store.put(`_new_file_trigger`, webhook);
},
async onDisable(context) {
const webhook = await context.store.get<WebhookInformation>(
`_new_file_trigger`
);
if (webhook) {
await common.unsubscribeWebhook(context.auth, webhook.id);
}
},
async run(context) {
return [context.payload.body];
},
sampleData: {
type: 'webhook_event',
id: 'fb0bd323-33b9-4f71-9dbc-fbcc3fe109ad',
created_at: '2023-04-19T12:06:52-07:00',
trigger: 'FILE.UPLOADED',
webhook: { id: '1396340122', type: 'webhook' },
created_by: {
type: 'user',
id: '24316851337',
name: 'Bonobo',
login: 'email@gmail.com',
},
source: {
id: '1194585432265',
type: 'file',
file_version: {
type: 'file_version',
id: '1302595111465',
sha1: '63da452d845b91ccb638510d046b902e96275359',
},
sequence_id: '0',
etag: '0',
sha1: '63da452d845b91ccb638510d046b902e96275359',
name: 'ap-logo.svg',
description: '',
size: 877,
path_collection: { total_count: 2, entries: [Array] },
created_at: '2023-04-19T12:06:52-07:00',
modified_at: '2023-04-19T12:06:52-07:00',
trashed_at: null,
purged_at: null,
content_created_at: '2023-02-02T06:54:17-08:00',
content_modified_at: '2023-02-02T06:54:17-08:00',
created_by: {
type: 'user',
id: '24316851337',
name: 'Bonobo',
login: 'email@gmail.com',
},
modified_by: {
type: 'user',
id: '24316851332',
name: 'Bonobo',
login: 'email@gmail.com',
},
owned_by: {
type: 'user',
id: '24316851332',
name: 'Bonobo',
login: 'email@gmail.com',
},
shared_link: null,
parent: {
type: 'folder',
id: '198605434359',
sequence_id: '0',
etag: '0',
name: 'Kinembe',
},
item_status: 'active',
},
additional_info: [],
},
});

View File

@@ -0,0 +1,108 @@
import {
createTrigger,
TriggerStrategy,
Property,
} from '@activepieces/pieces-framework';
import { boxAuth } from '../..';
import { WebhookInformation, common } from '../common';
export const newFolder = createTrigger({
auth: boxAuth,
name: 'new_folder',
displayName: 'New Folder',
description: 'Triggers when a folder is created',
type: TriggerStrategy.WEBHOOK,
props: {
folder: Property.ShortText({
displayName: 'Folder ID',
description:
'The ID of the folder in which file uploads will trigger this webhook',
required: true,
}),
},
async onEnable(context) {
const target: any = {
id: context.propsValue.folder,
type: 'folder',
};
const webhook = await common.subscribeWebhook(context.auth, {
event: 'FOLDER.CREATED',
target: target,
webhookUrl: context.webhookUrl,
});
await context.store.put(`_new_folder_trigger`, webhook);
},
async onDisable(context) {
const webhook = await context.store.get<WebhookInformation>(
`_new_folder_trigger`
);
if (webhook) {
await common.unsubscribeWebhook(context.auth, webhook.id);
}
},
async run(context) {
return [context.payload.body];
},
sampleData: {
id: '3f08aca1-aa0b-49a5-8e5a-5d8980bfbdef',
type: 'webhook_event',
source: {
id: '218634717358',
etag: '0',
name: 'test folder',
size: 0,
type: 'folder',
parent: {
id: '218635125044',
etag: '0',
name: 'Desktop',
type: 'folder',
sequence_id: '0',
},
purged_at: null,
created_at: '2023-07-25T05:55:08-07:00',
trashed_at: null,
description: '',
item_status: 'active',
modified_at: '2023-07-25T05:55:08-07:00',
sequence_id: '0',
shared_link: null,
path_collection: {
entries: [
{
id: '0',
etag: null,
name: 'All Files',
type: 'folder',
sequence_id: null,
},
{
id: '218635125044',
etag: '0',
name: 'Desktop',
type: 'folder',
sequence_id: '0',
},
],
total_count: 2,
},
content_created_at: '2023-07-25T05:55:08-07:00',
content_modified_at: '2023-07-25T05:55:08-07:00',
folder_upload_email: null,
},
trigger: 'FOLDER.CREATED',
webhook: {
id: '1738566186',
type: 'webhook',
},
created_at: '2023-07-25T05:55:09-07:00',
additional_info: [],
},
});