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,29 @@
import { createAction } from '@activepieces/pieces-framework';
import { apifyAuth } from '../..';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
export const getActors = createAction({
name: 'getActors',
auth: apifyAuth,
displayName: "Get user's Actors",
description: 'Gets the list of Actors available to the user.',
props: {},
async run(context) {
const apifyToken = context.auth.props.apikey;
const headers = {
Authorization: 'Bearer ' + apifyToken,
'Content-Type': 'application/json',
};
const url = 'https://api.apify.com/v2/acts/';
const httprequestdata = {
method: HttpMethod.GET,
url,
headers,
};
const response = await httpClient.sendRequest(httprequestdata);
return response.body;
},
});

View File

@@ -0,0 +1,39 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { apifyAuth } from '../..';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
export const getDatasetItems = createAction({
name: 'getDatasetItems',
auth: apifyAuth,
displayName: 'Get Dataset Items',
description: 'Gets the data from an Actors run.',
props: {
runid: Property.ShortText({
displayName: 'The runid of the Actor (alphanumeric)',
description:
'The runid of the completed Actors run [defaultDatasetId] (compulsory)',
required: true,
}),
},
async run(context) {
const apifyToken = context.auth.props.apikey;
const headers = {
Authorization: 'Bearer ' + apifyToken,
'Content-Type': 'application/json',
};
const url =
'https://api.apify.com/v2/datasets/' +
context.propsValue.runid +
'/items/';
const httprequestdata = {
method: HttpMethod.GET,
url,
headers,
};
const response = await httpClient.sendRequest(httprequestdata);
return response.body;
},
});

View File

@@ -0,0 +1,42 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { apifyAuth } from '../..';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
export const getLastRun = createAction({
name: 'getLastRun',
auth: apifyAuth,
displayName: 'Get last run details',
description: 'Gets last run details for a given Actor.',
props: {
actorid: Property.ShortText({
displayName: 'The id of the Actor (alphanumeric)',
// updated the description as can also use the actors user or ownername a tilde and the actor name in place of the id
description:
'The id [defaultDatasetId] of the Actor to get run information [you can also use the username then ~ then the name] (compulsory)',
required: true,
}),
},
async run(context) {
const apifyToken = context.auth.props.apikey;
const headers = {
Authorization: 'Bearer ' + apifyToken,
'Content-Type': 'application/json',
};
// removed ?status=SUCCEEDED as we might need to know if a particular actor failed
const url =
'https://api.apify.com/v2/acts/' +
context.propsValue.actorid +
'/runs/last';
//?status=SUCCEEDED'
const httprequestdata = {
method: HttpMethod.GET,
url,
headers,
};
const response = await httpClient.sendRequest(httprequestdata);
return response.body.data;
},
});

View File

@@ -0,0 +1,46 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { apifyAuth } from '../..';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
export const startActor = createAction({
// https://api.apify.com/v2/acts/{actorId}/run-sync
// https://api.apify.com/v2/acts/{actorId}/runs
name: 'startActor',
auth: apifyAuth,
displayName: 'Start an Apify Actor',
description: 'Starts an Apify Actor web scraper',
props: {
actorid: Property.ShortText({
displayName: 'The id or name of the Actor (alphanumeric)',
description:
'The id of the Actor to run [Use either id, or the username then ~ then the name] (compulsory)',
required: true,
}),
jsonbody: Property.Json({
displayName: 'JSON input',
description:
'The JSON input to pass to the Actor [you can get the JSON from a run in your Apify account]. If left blank will use defaults. (optional)',
required: true,
}),
},
async run(context) {
const apifyToken = context.auth.props.apikey;
const headers = {
Authorization: 'Bearer ' + apifyToken,
'Content-Type': 'application/json',
};
const url =
'https://api.apify.com/v2/acts/' + context.propsValue.actorid + '/runs/';
const httprequestdata = {
method: HttpMethod.POST,
url,
headers,
body: JSON.stringify(context.propsValue.jsonbody),
};
const response = await httpClient.sendRequest(httprequestdata);
return response.body.data;
},
});