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,96 @@
import {
createTrigger,
Property,
TriggerStrategy,
} from '@activepieces/pieces-framework';
import { assertNotNullOrUndefined } from '@activepieces/shared';
import { nanoid } from 'nanoid';
import { figmaCommon } from '../common';
import { figmaWebhookPostRequest, figmaDeleteRequest } from '../common/utils';
import { figmaAuth } from '../../';
type TriggerData = {
webhookId: string;
};
const TRIGGER_DATA_STORE_KEY = 'figma_new_comment_trigger_data';
export const newCommentTrigger = createTrigger({
auth: figmaAuth,
name: 'new_comment',
displayName: 'New Comment (Figma Professional plan only)',
description: 'Triggers when a new comment is posted',
type: TriggerStrategy.WEBHOOK,
sampleData: [
{
id: '12345',
team_id: '1234567890',
event_type: 'FILE_COMMENT',
client_id: null,
endpoint: 'http://localhost:1234/webhook',
passcode: 'figma-passcode',
status: 'ACTIVE',
description: null,
protocol_version: '2',
},
],
props: {
team_id: Property.ShortText({
displayName: 'Team ID',
description:
'Naviate to team page, copy the Id from the URL after the word team/',
required: true,
}),
},
async onEnable(context): Promise<void> {
const token = context.auth.access_token;
const teamId = context.propsValue['team_id'];
assertNotNullOrUndefined(token, 'token');
assertNotNullOrUndefined(teamId, 'teamId');
const url = `${figmaCommon.baseUrl}/${figmaCommon.webhooks}`;
const eventType = 'FILE_COMMENT';
const passcode = `figma_passcode_${nanoid()}`;
const endpoint = context.webhookUrl;
const { response_body } = await figmaWebhookPostRequest({
token,
url,
eventType,
teamId,
endpoint,
passcode,
});
await context.store?.put<TriggerData>(TRIGGER_DATA_STORE_KEY, {
webhookId: response_body['id'],
});
},
async onDisable(context): Promise<void> {
const token = context.auth.access_token;
assertNotNullOrUndefined(token, 'token');
const triggerData = await context.store?.get<TriggerData>(
TRIGGER_DATA_STORE_KEY
);
if (triggerData !== null && triggerData !== undefined) {
const url = `${figmaCommon.baseUrl}/${figmaCommon.webhook}`.replace(
':webhook_id',
triggerData.webhookId
);
await figmaDeleteRequest({ token, url });
}
},
async run(context) {
const payloadBody = context.payload.body as Record<string, unknown>;
if ('event_type' in payloadBody && payloadBody['event_type'] === 'PING') {
return [];
}
return [payloadBody];
},
});