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:
@@ -0,0 +1,88 @@
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { systemeIoAuth } from '../common/auth';
|
||||
import { systemeIoCommon } from '../common/client';
|
||||
import { randomBytes } from 'crypto';
|
||||
|
||||
export const newContact = createTrigger({
|
||||
auth: systemeIoAuth,
|
||||
name: 'newContact',
|
||||
displayName: 'New Contact',
|
||||
description: 'Fires when a new contact is created',
|
||||
props: {},
|
||||
sampleData: {
|
||||
contact: {
|
||||
id: 12345,
|
||||
email: "email@example.com",
|
||||
registeredAt: "2024-01-01T00:00:00+00:00",
|
||||
locale: "en",
|
||||
sourceURL: null,
|
||||
unsubscribed: false,
|
||||
bounced: false,
|
||||
needsConfirmation: false,
|
||||
fields: [
|
||||
{
|
||||
fieldName: "first_name",
|
||||
slug: "first_name",
|
||||
value: "John"
|
||||
},
|
||||
{
|
||||
fieldName: "last_name",
|
||||
slug: "last_name",
|
||||
value: "Doe"
|
||||
},
|
||||
{
|
||||
fieldName: "phone_number",
|
||||
slug: "phone_number",
|
||||
value: "+1234567890"
|
||||
}
|
||||
],
|
||||
tags: [
|
||||
{
|
||||
id: 1,
|
||||
name: "new_customer"
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "email_subscriber"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
async onEnable(context) {
|
||||
const secret = randomBytes(32).toString('hex');
|
||||
const response = await systemeIoCommon.createWebhook({
|
||||
eventType: 'CONTACT_CREATED',
|
||||
webhookUrl: context.webhookUrl,
|
||||
auth: context.auth.secret_text,
|
||||
secret: secret,
|
||||
});
|
||||
|
||||
await context.store.put('new_contact_webhook_id', response.id);
|
||||
await context.store.put('new_contact_webhook_secret', secret);
|
||||
},
|
||||
async onDisable(context) {
|
||||
const webhookId = await context.store.get<string>('new_contact_webhook_id');
|
||||
if (webhookId) {
|
||||
await systemeIoCommon.deleteWebhook({
|
||||
webhookId,
|
||||
auth: context.auth.secret_text,
|
||||
});
|
||||
await context.store.put('new_contact_webhook_id', null);
|
||||
await context.store.put('new_contact_webhook_secret', null);
|
||||
}
|
||||
},
|
||||
async run(context) {
|
||||
const webhookSecret = await context.store.get<string>('new_contact_webhook_secret');
|
||||
const webhookSignatureHeader = context.payload.headers['x-webhook-signature'];
|
||||
const rawBody = context.payload.rawBody;
|
||||
|
||||
if (!systemeIoCommon.verifyWebhookSignature(webhookSecret || undefined, webhookSignatureHeader, rawBody)) {
|
||||
console.warn('Systeme.io webhook signature verification failed');
|
||||
return [];
|
||||
}
|
||||
|
||||
const payload = context.payload.body as any;
|
||||
return [payload.contact || payload];
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,84 @@
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { systemeIoAuth } from '../common/auth';
|
||||
import { systemeIoCommon } from '../common/client';
|
||||
import { randomBytes } from 'crypto';
|
||||
|
||||
export const newSale = createTrigger({
|
||||
auth: systemeIoAuth,
|
||||
name: 'newSale',
|
||||
displayName: 'New Sale',
|
||||
description: 'Fires when a new purchase is made within a funnel',
|
||||
props: {},
|
||||
sampleData: {
|
||||
sale: {
|
||||
id: 67890,
|
||||
amount: 99.99,
|
||||
currency: "USD",
|
||||
status: "completed",
|
||||
createdAt: "2024-01-01T00:00:00+00:00",
|
||||
updatedAt: "2024-01-01T00:00:00+00:00",
|
||||
product: {
|
||||
id: 123,
|
||||
name: "Premium Course",
|
||||
type: "digital_product"
|
||||
},
|
||||
funnel: {
|
||||
id: 456,
|
||||
name: "Sales Funnel",
|
||||
step: "checkout"
|
||||
},
|
||||
contact: {
|
||||
id: 12345,
|
||||
email: "customer@example.com",
|
||||
firstName: "John",
|
||||
lastName: "Doe"
|
||||
},
|
||||
payment: {
|
||||
method: "stripe",
|
||||
transactionId: "txn_1234567890",
|
||||
gateway: "stripe"
|
||||
},
|
||||
affiliate: {
|
||||
id: null,
|
||||
commission: null
|
||||
}
|
||||
}
|
||||
},
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
async onEnable(context) {
|
||||
const secret = randomBytes(32).toString('hex');
|
||||
const response = await systemeIoCommon.createWebhook({
|
||||
eventType: 'SALE_NEW',
|
||||
webhookUrl: context.webhookUrl,
|
||||
auth: context.auth.secret_text,
|
||||
secret: secret,
|
||||
});
|
||||
|
||||
await context.store.put('new_sale_webhook_id', response.id);
|
||||
await context.store.put('new_sale_webhook_secret', secret);
|
||||
},
|
||||
async onDisable(context) {
|
||||
const webhookId = await context.store.get<string>('new_sale_webhook_id');
|
||||
if (webhookId) {
|
||||
await systemeIoCommon.deleteWebhook({
|
||||
webhookId,
|
||||
auth: context.auth.secret_text,
|
||||
});
|
||||
await context.store.put('new_sale_webhook_id', null);
|
||||
await context.store.put('new_sale_webhook_secret', null);
|
||||
}
|
||||
},
|
||||
async run(context) {
|
||||
const webhookSecret = await context.store.get<string>('new_sale_webhook_secret');
|
||||
const webhookSignatureHeader = context.payload.headers['x-webhook-signature'];
|
||||
const rawBody = context.payload.rawBody;
|
||||
|
||||
if (!systemeIoCommon.verifyWebhookSignature(webhookSecret || undefined, webhookSignatureHeader, rawBody)) {
|
||||
console.warn('Systeme.io webhook signature verification failed');
|
||||
return [];
|
||||
}
|
||||
|
||||
const payload = context.payload.body as any;
|
||||
return [payload.sale || payload];
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,93 @@
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { systemeIoAuth } from '../common/auth';
|
||||
import { systemeIoCommon } from '../common/client';
|
||||
import { randomBytes } from 'crypto';
|
||||
|
||||
export const newTagAddedToContact = createTrigger({
|
||||
auth: systemeIoAuth,
|
||||
name: 'newTagAddedToContact',
|
||||
displayName: 'New Tag Added to Contact',
|
||||
description: 'Fires when a specific tag is assigned to a contact',
|
||||
props: {},
|
||||
sampleData: {
|
||||
contact: {
|
||||
id: 12345,
|
||||
email: "customer@example.com",
|
||||
registeredAt: "2024-01-01T00:00:00+00:00",
|
||||
locale: "en",
|
||||
sourceURL: null,
|
||||
unsubscribed: false,
|
||||
bounced: false,
|
||||
needsConfirmation: false,
|
||||
fields: [
|
||||
{
|
||||
fieldName: "first_name",
|
||||
slug: "first_name",
|
||||
value: "John"
|
||||
},
|
||||
{
|
||||
fieldName: "last_name",
|
||||
slug: "last_name",
|
||||
value: "Doe"
|
||||
},
|
||||
{
|
||||
fieldName: "phone_number",
|
||||
slug: "phone_number",
|
||||
value: "+1234567890"
|
||||
}
|
||||
],
|
||||
tags: [
|
||||
{
|
||||
id: 1,
|
||||
name: "existing_customer"
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "VIP Customer"
|
||||
}
|
||||
]
|
||||
},
|
||||
tag: {
|
||||
id: 2,
|
||||
name: "VIP Customer"
|
||||
},
|
||||
addedAt: "2024-01-01T10:30:00+00:00"
|
||||
},
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
async onEnable(context) {
|
||||
const secret = randomBytes(32).toString('hex');
|
||||
const response = await systemeIoCommon.createWebhook({
|
||||
eventType: 'CONTACT_TAG_ADDED',
|
||||
webhookUrl: context.webhookUrl,
|
||||
auth: context.auth.secret_text ,
|
||||
secret: secret,
|
||||
});
|
||||
|
||||
await context.store.put('new_tag_added_webhook_id', response.id);
|
||||
await context.store.put('new_tag_added_webhook_secret', secret);
|
||||
},
|
||||
async onDisable(context) {
|
||||
const webhookId = await context.store.get<string>('new_tag_added_webhook_id');
|
||||
if (webhookId) {
|
||||
await systemeIoCommon.deleteWebhook({
|
||||
webhookId,
|
||||
auth: context.auth.secret_text,
|
||||
});
|
||||
await context.store.put('new_tag_added_webhook_id', null);
|
||||
await context.store.put('new_tag_added_webhook_secret', null);
|
||||
}
|
||||
},
|
||||
async run(context) {
|
||||
const webhookSecret = await context.store.get<string>('new_tag_added_webhook_secret');
|
||||
const webhookSignatureHeader = context.payload.headers['x-webhook-signature'];
|
||||
const rawBody = context.payload.rawBody;
|
||||
|
||||
if (!systemeIoCommon.verifyWebhookSignature(webhookSecret || undefined, webhookSignatureHeader, rawBody)) {
|
||||
console.warn('Systeme.io webhook signature verification failed');
|
||||
return [];
|
||||
}
|
||||
|
||||
const payload = context.payload.body as any;
|
||||
return [payload];
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user