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,33 @@
{
"extends": [
"../../../../.eslintrc.base.json"
],
"ignorePatterns": [
"!**/*"
],
"overrides": [
{
"files": [
"*.ts",
"*.tsx",
"*.js",
"*.jsx"
],
"rules": {}
},
{
"files": [
"*.ts",
"*.tsx"
],
"rules": {}
},
{
"files": [
"*.js",
"*.jsx"
],
"rules": {}
}
]
}

View File

@@ -0,0 +1,7 @@
# pieces-motiontools
This library was generated with [Nx](https://nx.dev).
## Building
Run `nx build pieces-motiontools` to build the library.

View File

@@ -0,0 +1,10 @@
{
"name": "@activepieces/piece-motiontools",
"version": "0.0.1",
"type": "commonjs",
"main": "./src/index.js",
"types": "./src/index.d.ts",
"dependencies": {
"tslib": "^2.3.0"
}
}

View File

@@ -0,0 +1,65 @@
{
"name": "pieces-motiontools",
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/pieces/community/motiontools/src",
"projectType": "library",
"release": {
"version": {
"manifestRootsToUpdate": [
"dist/{projectRoot}"
],
"currentVersionResolver": "git-tag",
"fallbackCurrentVersionResolver": "disk"
}
},
"tags": [],
"targets": {
"build": {
"executor": "@nx/js:tsc",
"outputs": [
"{options.outputPath}"
],
"options": {
"outputPath": "dist/packages/pieces/community/motiontools",
"tsConfig": "packages/pieces/community/motiontools/tsconfig.lib.json",
"packageJson": "packages/pieces/community/motiontools/package.json",
"main": "packages/pieces/community/motiontools/src/index.ts",
"assets": [
"packages/pieces/community/motiontools/*.md",
{
"input": "packages/pieces/community/motiontools/src/i18n",
"output": "./src/i18n",
"glob": "**/!(i18n.json)"
}
],
"buildableProjectDepsInPackageJsonType": "dependencies",
"updateBuildableProjectDepsInPackageJson": true
},
"dependsOn": [
"prebuild",
"^build"
]
},
"nx-release-publish": {
"options": {
"packageRoot": "dist/{projectRoot}"
}
},
"prebuild": {
"dependsOn": [
"^build"
],
"executor": "nx:run-commands",
"options": {
"cwd": "packages/pieces/community/motiontools",
"command": "bun install --no-save --silent"
}
},
"lint": {
"executor": "@nx/eslint:lint",
"outputs": [
"{options.outputFile}"
]
}
}
}

View File

@@ -0,0 +1,27 @@
import { createPiece } from '@activepieces/pieces-framework';
import { create1stopBooking } from './lib/actions/create-1-stop-booking';
import { create2stopBooking } from './lib/actions/create-2-stop-booking';
import { motiontoolsAuth } from './lib/common/auth';
import { bookingCreated } from './lib/triggers/booking-created';
import { bookingStatusUpdate } from './lib/triggers/booking-status-update';
import { bookingStopStatusUpdate } from './lib/triggers/booking-stop-status-update';
import { packageCreated } from './lib/triggers/package-created';
import { packageStatusUpdate } from './lib/triggers/package-status-update';
export const motiontools = createPiece({
displayName: 'MotionTools',
auth: motiontoolsAuth,
description:
'Digitize processes, boost efficiency and excite users with MotionTools, the operating system for fleet-based service providers.',
minimumSupportedRelease: '0.36.1',
logoUrl: 'https://cdn.activepieces.com/pieces/motiontools.png',
authors: ['sanket-a11y'],
actions: [create1stopBooking, create2stopBooking],
triggers: [
bookingCreated,
bookingStatusUpdate,
bookingStopStatusUpdate,
packageCreated,
packageStatusUpdate,
],
});

View File

@@ -0,0 +1,157 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { motiontoolsAuth } from '../common/auth';
import { makeRequest } from '../common/client';
import { HttpMethod } from '@activepieces/pieces-common';
export const create1stopBooking = createAction({
auth: motiontoolsAuth,
name: 'create1stopBooking',
displayName: 'Create 1-stop Booking',
description: 'Create a hailing booking (1-stop).',
props: {
scheduled_at: Property.ShortText({
displayName: 'Scheduled At',
description: 'Scheduled datetime (ISO 8601) for the booking (optional)',
required: false,
}),
payment_method: Property.ShortText({
displayName: 'Payment Method',
description: 'Payment method (e.g. cash, card)',
required: true,
}),
stop_type: Property.ShortText({
displayName: 'Stop Type',
description: 'Type of stop (e.g. pickup, dropoff)',
required: false,
}),
stop_lat: Property.Number({
displayName: 'Latitude',
description: 'Latitude for the stop (optional)',
required: false,
}),
stop_lng: Property.Number({
displayName: 'Longitude',
description: 'Longitude for the stop (optional)',
required: false,
}),
stop_street: Property.ShortText({
displayName: 'Street',
description: 'Street name for the stop (optional)',
required: false,
}),
stop_number: Property.ShortText({
displayName: 'Street Number',
description: 'Street number for the stop (optional)',
required: false,
}),
stop_city: Property.ShortText({
displayName: 'City',
description: 'City for the stop (optional)',
required: false,
}),
stop_country: Property.ShortText({
displayName: 'Country',
description: 'Country for the stop (optional)',
required: false,
}),
stop_zip_code: Property.ShortText({
displayName: 'Postal Code',
description: 'Postal code for the stop (optional)',
required: false,
}),
stop_additional_line: Property.ShortText({
displayName: 'Address Additional Line',
description: 'Additional address line for the stop (optional)',
required: false,
}),
stop_location_name: Property.ShortText({
displayName: 'Location Name',
description: 'Location name for the stop (optional)',
required: false,
}),
stop_first_name: Property.ShortText({
displayName: 'Contact First Name',
description: "Contact's first name at the stop (optional)",
required: false,
}),
stop_last_name: Property.ShortText({
displayName: 'Contact Last Name',
description: "Contact's last name at the stop (optional)",
required: false,
}),
stop_phone_number: Property.ShortText({
displayName: 'Contact Phone Number',
description: "Contact's phone number (optional)",
required: false,
}),
stop_email: Property.ShortText({
displayName: 'Contact Email',
description: "Contact's email (optional)",
required: false,
}),
},
async run({ auth, propsValue }) {
const {
scheduled_at,
payment_method,
stop_type,
stop_lat,
stop_lng,
stop_street,
stop_number,
stop_city,
stop_country,
stop_zip_code,
stop_additional_line,
stop_location_name,
stop_first_name,
stop_last_name,
stop_phone_number,
stop_email,
} = propsValue;
const booking: any = {};
if (scheduled_at) booking.scheduled_at = scheduled_at;
booking.payment_method = payment_method;
const stop: any = {
type: stop_type || 'pickup',
flow: 'full',
};
if (typeof stop_lat === 'number') stop.lat = stop_lat;
if (typeof stop_lng === 'number') stop.lng = stop_lng;
if (stop_street) stop.street = stop_street;
if (stop_number) stop.number = stop_number;
if (stop_city) stop.city = stop_city;
if (stop_country) stop.country = stop_country;
if (stop_zip_code) stop.zip_code = stop_zip_code;
if (stop_additional_line) stop.additional_line = stop_additional_line;
if (stop_location_name) stop.location_name = stop_location_name;
if (stop_first_name) stop.first_name = stop_first_name;
if (stop_last_name) stop.last_name = stop_last_name;
if (stop_phone_number) stop.phone_number = stop_phone_number;
if (stop_email) stop.email = stop_email;
booking.stops = [stop];
try {
const response = await makeRequest(
auth.secret_text,
HttpMethod.POST,
'/hailing/bookings',
{ booking }
);
return response;
} catch (error) {
throw new Error(
`Failed to create booking: ${
error instanceof Error ? error.message : String(error)
}`
);
}
},
});

View File

@@ -0,0 +1,250 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { motiontoolsAuth } from '../common/auth';
import { makeRequest } from '../common/client';
import { HttpMethod } from '@activepieces/pieces-common';
export const create2stopBooking = createAction({
auth: motiontoolsAuth,
name: 'create2stopBooking',
displayName: 'Create 2-stop Booking',
description: 'Create a hailing booking with two stops (pickup + dropoff).',
props: {
scheduled_at: Property.ShortText({
displayName: 'Scheduled At',
description: 'Scheduled datetime (ISO 8601) for the booking (optional)',
required: false,
}),
payment_method: Property.ShortText({
displayName: 'Payment Method',
description: 'Payment method (e.g. cash, card)',
required: true,
}),
additional_information: Property.LongText({
displayName: 'Additional Information',
description: 'Any extra notes for the booking (optional)',
required: false,
}),
metadata: Property.Json({
displayName: 'Metadata',
description: 'Additional metadata for the booking (optional)',
required: false,
}),
// Stop 1 (pickup)
stop1_type: Property.ShortText({
displayName: 'Stop 1 Type',
required: false,
}),
stop1_metadata: Property.Json({
displayName: 'Stop 1 Metadata',
required: false,
}),
stop1_lat: Property.Number({
displayName: 'Stop 1 Latitude',
required: false,
}),
stop1_lng: Property.Number({
displayName: 'Stop 1 Longitude',
required: false,
}),
stop1_street: Property.ShortText({
displayName: 'Stop 1 Street',
required: false,
}),
stop1_number: Property.ShortText({
displayName: 'Stop 1 Street Number',
required: false,
}),
stop1_city: Property.ShortText({
displayName: 'Stop 1 City',
required: false,
}),
stop1_country: Property.ShortText({
displayName: 'Stop 1 Country',
required: false,
}),
stop1_zip_code: Property.ShortText({
displayName: 'Stop 1 Postal Code',
required: false,
}),
stop1_additional_line: Property.ShortText({
displayName: 'Stop 1 Address Additional Line',
required: false,
}),
stop1_location_name: Property.ShortText({
displayName: 'Stop 1 Location Name',
required: false,
}),
stop1_first_name: Property.ShortText({
displayName: 'Stop 1 Contact First Name',
required: false,
}),
stop1_last_name: Property.ShortText({
displayName: 'Stop 1 Contact Last Name',
required: false,
}),
stop1_phone_number: Property.ShortText({
displayName: 'Stop 1 Contact Phone',
required: false,
}),
stop1_email: Property.ShortText({
displayName: 'Stop 1 Contact Email',
required: false,
}),
// Stop 2 (dropoff)
stop2_type: Property.ShortText({
displayName: 'Stop 2 Type',
required: false,
}),
stop2_metadata: Property.Json({
displayName: 'Stop 2 Metadata',
required: false,
}),
stop2_lat: Property.Number({
displayName: 'Stop 2 Latitude',
required: false,
}),
stop2_lng: Property.Number({
displayName: 'Stop 2 Longitude',
required: false,
}),
stop2_street: Property.ShortText({
displayName: 'Stop 2 Street',
required: false,
}),
stop2_number: Property.ShortText({
displayName: 'Stop 2 Street Number',
required: false,
}),
stop2_city: Property.ShortText({
displayName: 'Stop 2 City',
required: false,
}),
stop2_country: Property.ShortText({
displayName: 'Stop 2 Country',
required: false,
}),
stop2_zip_code: Property.ShortText({
displayName: 'Stop 2 Postal Code',
required: false,
}),
stop2_additional_line: Property.ShortText({
displayName: 'Stop 2 Address Additional Line',
required: false,
}),
stop2_location_name: Property.ShortText({
displayName: 'Stop 2 Location Name',
required: false,
}),
stop2_first_name: Property.ShortText({
displayName: 'Stop 2 Contact First Name',
required: false,
}),
stop2_last_name: Property.ShortText({
displayName: 'Stop 2 Contact Last Name',
required: false,
}),
stop2_phone_number: Property.ShortText({
displayName: 'Stop 2 Contact Phone',
required: false,
}),
stop2_email: Property.ShortText({
displayName: 'Stop 2 Contact Email',
required: false,
}),
},
async run({ auth, propsValue }) {
const {
scheduled_at,
payment_method,
additional_information,
metadata,
stop1_type,
stop1_metadata,
stop1_lat,
stop1_lng,
stop1_street,
stop1_number,
stop1_city,
stop1_country,
stop1_zip_code,
stop1_additional_line,
stop1_location_name,
stop1_first_name,
stop1_last_name,
stop1_phone_number,
stop1_email,
stop2_type,
stop2_metadata,
stop2_lat,
stop2_lng,
stop2_street,
stop2_number,
stop2_city,
stop2_country,
stop2_zip_code,
stop2_additional_line,
stop2_location_name,
stop2_first_name,
stop2_last_name,
stop2_phone_number,
stop2_email,
} = propsValue;
const booking: any = {};
if (scheduled_at) booking.scheduled_at = scheduled_at;
booking.payment_method = payment_method;
if (additional_information)
booking.additional_information = additional_information;
if (metadata) booking.metadata = metadata;
const stop1: any = {
type: stop1_type || 'pickup',
flow: 'full',
};
if (stop1_metadata) stop1.metadata = stop1_metadata;
if (typeof stop1_lat === 'number') stop1.lat = stop1_lat;
if (typeof stop1_lng === 'number') stop1.lng = stop1_lng;
if (stop1_street) stop1.street = stop1_street;
if (stop1_number) stop1.number = stop1_number;
if (stop1_city) stop1.city = stop1_city;
if (stop1_country) stop1.country = stop1_country;
if (stop1_zip_code) stop1.zip_code = stop1_zip_code;
if (stop1_additional_line) stop1.additional_line = stop1_additional_line;
if (stop1_location_name) stop1.location_name = stop1_location_name;
if (stop1_first_name) stop1.first_name = stop1_first_name;
if (stop1_last_name) stop1.last_name = stop1_last_name;
if (stop1_phone_number) stop1.phone_number = stop1_phone_number;
if (stop1_email) stop1.email = stop1_email;
const stop2: any = {
type: stop2_type || 'dropoff',
flow: 'full',
};
if (stop2_metadata) stop2.metadata = stop2_metadata;
if (typeof stop2_lat === 'number') stop2.lat = stop2_lat;
if (typeof stop2_lng === 'number') stop2.lng = stop2_lng;
if (stop2_street) stop2.street = stop2_street;
if (stop2_number) stop2.number = stop2_number;
if (stop2_city) stop2.city = stop2_city;
if (stop2_country) stop2.country = stop2_country;
if (stop2_zip_code) stop2.zip_code = stop2_zip_code;
if (stop2_additional_line) stop2.additional_line = stop2_additional_line;
if (stop2_location_name) stop2.location_name = stop2_location_name;
if (stop2_first_name) stop2.first_name = stop2_first_name;
if (stop2_last_name) stop2.last_name = stop2_last_name;
if (stop2_phone_number) stop2.phone_number = stop2_phone_number;
if (stop2_email) stop2.email = stop2_email;
booking.stops = [stop1, stop2];
const response = await makeRequest(
auth.secret_text,
HttpMethod.POST,
'/hailing/bookings',
{ booking }
);
return response;
},
});

View File

@@ -0,0 +1,8 @@
import { PieceAuth } from '@activepieces/pieces-framework';
export const motiontoolsAuth = PieceAuth.SecretText({
displayName: 'Motiontools API Key',
description:
'API Key for authenticating with Motiontools. Refer https://help.motiontools.io/en/articles/10476909-create-an-api-key',
required: true,
});

View File

@@ -0,0 +1,29 @@
import { HttpMethod, httpClient } from '@activepieces/pieces-common';
export const BASE_URL = 'https://api.motiontools.io/api';
export async function makeRequest(
apiKey: string,
method: HttpMethod,
path: string,
body?: any
) {
try {
const response = await httpClient.sendRequest({
method,
url: `${BASE_URL}${path}`,
headers: {
'api-key': apiKey,
},
body: body,
});
return response.body;
} catch (error: any) {
throw new Error(
`Unexpected error: ${JSON.stringify(
error.response || error.message || error
)}`
);
}
}

View File

@@ -0,0 +1,72 @@
import {
createTrigger,
Property,
TriggerStrategy,
} from '@activepieces/pieces-framework';
import { motiontoolsAuth } from '../common/auth';
export const bookingCreated = createTrigger({
auth: motiontoolsAuth,
name: 'bookingCreated',
displayName: 'Booking Created',
description: 'Triggers when a new booking is created. Only available if you have a MotionToolsadmin account',
props: {
instructions: Property.MarkDown({
value: `# Motiontools Webhook Setup
1. Open Motiontools → Settings → Advanced → Webhooks
2. Click **Create webhook**
3. Name: e.g., Activepieces Booking Created
4. Endpoint URL: paste the Activepieces webhook URL below:
\`\`\`text
{{webhookUrl}}
\`\`\`
5. Enable event: **booking.created**
6. Toggle **Active** and click **Save**
`,
}),
},
sampleData: {
id: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
timestamp: '2020-11-09T10:19:07Z',
resource_type: 'booking',
event: 'created',
data: {
booking_id: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
service_id: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
customer_id: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
service_area_id: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
place_ids: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
scheduled_at: '2020-11-09T10:19:07Z',
status: 'cancelled',
requested_capabilities: {
property1: 'string',
property2: 'string',
},
managing_organization_ids: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
external_id: 'string',
},
},
type: TriggerStrategy.WEBHOOK,
async onEnable(context) {
// implement webhook creation logic
},
async onDisable(context) {
// implement webhook deletion logic
},
async run(context) {
const body = context.payload.body as any;
if (
body.event === 'created' &&
body.resource_type === 'booking' &&
body.data
) {
return body;
}
return [];
},
});

View File

@@ -0,0 +1,61 @@
import {
createTrigger,
Property,
TriggerStrategy,
} from '@activepieces/pieces-framework';
import { motiontoolsAuth } from '../common/auth';
export const bookingStatusUpdate = createTrigger({
auth: motiontoolsAuth,
name: 'bookingStatusUpdate',
displayName: 'Booking Status Update',
description:
'Triggers when a booking status is updated. Only available if you have a MotionToolsadmin account',
props: {
instructions: Property.MarkDown({
value: `# Motiontools Webhook Setup
1. Open Motiontools → Settings → Advanced → Webhooks
2. Click **Create webhook**
3. Name: e.g., Activepieces Booking Status Update
4. Endpoint URL: paste the Activepieces webhook URL below:
\`\`\`text
{{webhookUrl}}
\`\`\`
5. Enable event: **booking.modified**
6. Toggle **Active** and click **Save**
`,
}),
},
sampleData: {
id: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
timestamp: '2020-11-09T10:19:07Z',
resource_type: 'booking',
event: 'modified',
data: {
booking_id: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
customer_id: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
external_id: 'string',
service_area_id: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
},
},
type: TriggerStrategy.WEBHOOK,
async onEnable(context) {
// implement webhook creation logic
},
async onDisable(context) {
// implement webhook deletion logic
},
async run(context) {
const body = context.payload.body as any;
if (
body.event === 'modified' &&
body.resource_type === 'booking' &&
body.data
) {
return [body];
}
return [];
},
});

View File

@@ -0,0 +1,60 @@
import {
createTrigger,
Property,
TriggerStrategy,
} from '@activepieces/pieces-framework';
import { motiontoolsAuth } from '../common/auth';
export const bookingStopStatusUpdate = createTrigger({
auth: motiontoolsAuth,
name: 'bookingStopStatusUpdate',
displayName: 'Booking Stop Status Update',
description: '',
props: {
instructions: Property.MarkDown({
value: `# Motiontools Webhook Setup
1. Open Motiontools → Settings → Advanced → Webhooks
2. Click **Create webhook**
3. Name: e.g., Activepieces Booking Stop Status Update
4. Endpoint URL: paste the Activepieces webhook URL below:
\`\`\`text
{{webhookUrl}}
\`\`\`
5. Enable event: **booking.route_changed**
6. Toggle **Active** and click **Save**
`,
}),
},
sampleData: {
id: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
timestamp: '2020-11-09T10:19:07Z',
resource_type: 'booking',
event: 'route_changed',
data: {
booking_id: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
customer_id: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
external_id: 'string',
service_area_id: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
},
},
type: TriggerStrategy.WEBHOOK,
async onEnable(context) {
// implement webhook creation logic
},
async onDisable(context) {
// implement webhook deletion logic
},
async run(context) {
const body = context.payload.body as any;
if (
body.event === 'route_changed' &&
body.resource_type === 'booking' &&
body.data
) {
return [body];
}
return [];
},
});

View File

@@ -0,0 +1,60 @@
import {
createTrigger,
Property,
TriggerStrategy,
} from '@activepieces/pieces-framework';
import { motiontoolsAuth } from '../common/auth';
export const packageCreated = createTrigger({
auth: motiontoolsAuth,
name: 'packageCreated',
displayName: 'Package Created',
description: 'Triggers when a package is created',
props: {
instructions: Property.MarkDown({
value: `# Motiontools Webhook Setup
1. Open Motiontools → Settings → Advanced → Webhooks
2. Click **Create webhook**
3. Name: e.g., Activepieces Booking Stop Status Update
4. Endpoint URL: paste the Activepieces webhook URL below:
\`\`\`text
{{webhookUrl}}
\`\`\`
5. Enable event: **hailing_package.created**
6. Toggle **Active** and click **Save**
`,
}),
},
sampleData: {
id: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
timestamp: '2020-11-09T10:19:07Z',
resource_type: 'hailing_package',
event: 'created',
data: {
package_id: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
customer_id: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
status: 'at_customs',
customs_status: 'documents_needed',
},
},
type: TriggerStrategy.WEBHOOK,
async onEnable(context) {
// implement webhook creation logic
},
async onDisable(context) {
// implement webhook deletion logic
},
async run(context) {
const body = context.payload.body as any;
if (
body.event === 'created' &&
body.resource_type === 'hailing_package' &&
body.data
) {
return [body];
}
return [];
},
});

View File

@@ -0,0 +1,61 @@
import {
createTrigger,
Property,
TriggerStrategy,
} from '@activepieces/pieces-framework';
import { motiontoolsAuth } from '../common/auth';
export const packageStatusUpdate = createTrigger({
auth: motiontoolsAuth,
name: 'packageStatusUpdate',
displayName: 'Package Status Update',
description: '',
props: {
instructions: Property.MarkDown({
value: `# Motiontools Webhook Setup
1. Open Motiontools → Settings → Advanced → Webhooks
2. Click **Create webhook**
3. Name: e.g., Activepieces Booking Stop Status Update
4. Endpoint URL: paste the Activepieces webhook URL below:
\`\`\`text
{{webhookUrl}}
\`\`\`
5. Enable event: **hailing_package.customs_transition**
6. Toggle **Active** and click **Save**
`,
}),
},
sampleData: {
id: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
timestamp: '2020-11-09T10:19:07Z',
resource_type: 'hailing_package',
event: 'customs_transition',
data: {
package_id: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
customer_id: 'db76ba31-96f8-4c95-b71d-85ade5c7a640',
from: 'documents_needed',
to: 'documents_needed',
event: 'announce',
},
},
type: TriggerStrategy.WEBHOOK,
async onEnable(context) {
// implement webhook creation logic
},
async onDisable(context) {
// implement webhook deletion logic
},
async run(context) {
const body = context.payload.body as any;
if (
body.event === 'customs_transition' &&
body.resource_type === 'hailing_package' &&
body.data
) {
return [body];
}
return [];
},
});

View File

@@ -0,0 +1,20 @@
{
"extends": "../../../../tsconfig.base.json",
"compilerOptions": {
"module": "commonjs",
"forceConsistentCasingInFileNames": true,
"strict": true,
"importHelpers": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noPropertyAccessFromIndexSignature": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
}
]
}

View File

@@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../../dist/out-tsc",
"declaration": true,
"types": ["node"]
},
"include": ["src/**/*.ts"]
}