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,33 @@
|
||||
{
|
||||
"extends": [
|
||||
"../../../../.eslintrc.base.json"
|
||||
],
|
||||
"ignorePatterns": [
|
||||
"!**/*"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx",
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# pieces-esignatures
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Building
|
||||
|
||||
Run `nx build pieces-esignatures` to build the library.
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "@activepieces/piece-esignatures",
|
||||
"version": "0.0.1",
|
||||
"type": "commonjs",
|
||||
"main": "./src/index.js",
|
||||
"types": "./src/index.d.ts",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"name": "pieces-esignatures",
|
||||
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "packages/pieces/community/esignatures/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/esignatures",
|
||||
"tsConfig": "packages/pieces/community/esignatures/tsconfig.lib.json",
|
||||
"packageJson": "packages/pieces/community/esignatures/package.json",
|
||||
"main": "packages/pieces/community/esignatures/src/index.ts",
|
||||
"assets": [
|
||||
"packages/pieces/community/esignatures/*.md",
|
||||
{
|
||||
"input": "packages/pieces/community/esignatures/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/esignatures",
|
||||
"command": "bun install --no-save --silent"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": [
|
||||
"{options.outputFile}"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { createPiece } from '@activepieces/pieces-framework';
|
||||
import { esignaturesAuth } from './lib/common/auth';
|
||||
import { PieceCategory } from '@activepieces/shared';
|
||||
import { createContract } from './lib/actions/create-contract';
|
||||
import { createCustomApiCallAction } from '@activepieces/pieces-common';
|
||||
|
||||
export const esignatures = createPiece({
|
||||
displayName: 'eSignatures',
|
||||
auth: esignaturesAuth,
|
||||
minimumSupportedRelease: '0.36.1',
|
||||
logoUrl: 'https://cdn.activepieces.com/pieces/esignatures.png',
|
||||
authors: ['sanket-a11y'],
|
||||
categories: [PieceCategory.SALES_AND_CRM],
|
||||
actions: [
|
||||
createContract,
|
||||
createCustomApiCallAction({
|
||||
baseUrl: () => `https://esignatures.com/api`,
|
||||
authLocation: 'queryParams',
|
||||
auth: esignaturesAuth,
|
||||
authMapping: async (auth) => {
|
||||
return {
|
||||
token: `${auth.secret_text}`,
|
||||
};
|
||||
},
|
||||
}),
|
||||
],
|
||||
triggers: [],
|
||||
});
|
||||
@@ -0,0 +1,131 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { esignaturesAuth } from '../common/auth';
|
||||
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const createContract = createAction({
|
||||
auth: esignaturesAuth,
|
||||
name: 'createContract',
|
||||
displayName: 'Create Contract',
|
||||
description: 'Create a new contract from a template in eSignatures',
|
||||
props: {
|
||||
templateId: Property.ShortText({
|
||||
displayName: 'Template ID',
|
||||
description: 'The ID of the template to use for the contract',
|
||||
required: true,
|
||||
}),
|
||||
title: Property.ShortText({
|
||||
displayName: 'Contract Title',
|
||||
description:
|
||||
'Unique title for the contract (defaults to template title if not specified)',
|
||||
required: false,
|
||||
}),
|
||||
locale: Property.StaticDropdown({
|
||||
displayName: 'Language',
|
||||
description: 'Language setting for the signer page and emails',
|
||||
required: false,
|
||||
options: {
|
||||
disabled: false,
|
||||
options: [
|
||||
{ label: 'Czech', value: 'cz' },
|
||||
{ label: 'Danish', value: 'da' },
|
||||
{ label: 'German', value: 'de' },
|
||||
{ label: 'Greek', value: 'el' },
|
||||
{ label: 'English', value: 'en' },
|
||||
{ label: 'English (UK)', value: 'en-GB' },
|
||||
{ label: 'Spanish', value: 'es' },
|
||||
{ label: 'Finnish', value: 'fi' },
|
||||
{ label: 'French', value: 'fr' },
|
||||
{ label: 'Croatian', value: 'hr' },
|
||||
{ label: 'Hungarian', value: 'hu' },
|
||||
{ label: 'Indonesian', value: 'id' },
|
||||
{ label: 'Italian', value: 'it' },
|
||||
{ label: 'Japanese', value: 'ja' },
|
||||
{ label: 'Dutch', value: 'nl' },
|
||||
{ label: 'Norwegian', value: 'no' },
|
||||
{ label: 'Polish', value: 'pl' },
|
||||
{ label: 'Portuguese', value: 'pt' },
|
||||
{ label: 'Romanian', value: 'ro' },
|
||||
{ label: 'Serbian', value: 'rs' },
|
||||
{ label: 'Slovak', value: 'sk' },
|
||||
{ label: 'Slovenian', value: 'sl' },
|
||||
{ label: 'Swedish', value: 'sv' },
|
||||
{ label: 'Vietnamese', value: 'vi' },
|
||||
{ label: 'Chinese (Simplified)', value: 'zh-CN' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
metadata: Property.ShortText({
|
||||
displayName: 'Metadata',
|
||||
description: 'Custom data to attach to the contract',
|
||||
required: false,
|
||||
}),
|
||||
expiresInHours: Property.Number({
|
||||
displayName: 'Expires In Hours',
|
||||
description: 'Sets the expiry time (in hours) for the contract',
|
||||
required: false,
|
||||
}),
|
||||
customWebhookUrl: Property.ShortText({
|
||||
displayName: 'Custom Webhook URL',
|
||||
description: 'Custom URL for webhook notifications',
|
||||
required: false,
|
||||
}),
|
||||
assignedUserEmail: Property.ShortText({
|
||||
displayName: 'Assigned User Email',
|
||||
description: 'Email to assign management of the contract',
|
||||
required: false,
|
||||
}),
|
||||
labels: Property.Array({
|
||||
displayName: 'Labels',
|
||||
description: 'Labels to assign to the contract (for grouping)',
|
||||
required: false,
|
||||
}),
|
||||
test: Property.Checkbox({
|
||||
displayName: 'Test Contract',
|
||||
description: 'Mark as test/demo contract with no fees charged',
|
||||
required: false,
|
||||
}),
|
||||
saveAsDraft: Property.Checkbox({
|
||||
displayName: 'Save as Draft',
|
||||
description: 'Save as draft instead of sending to signers',
|
||||
required: false,
|
||||
}),
|
||||
signers: Property.Array({
|
||||
displayName: 'Signers',
|
||||
description:
|
||||
'List of individuals required to sign (name, email, and/or mobile)',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
const payload: any = {
|
||||
template_id: propsValue.templateId,
|
||||
};
|
||||
|
||||
if (propsValue.title) payload.title = propsValue.title;
|
||||
if (propsValue.locale) payload.locale = propsValue.locale;
|
||||
if (propsValue.metadata) payload.metadata = propsValue.metadata;
|
||||
if (propsValue.expiresInHours !== undefined)
|
||||
payload.expires_in_hours = propsValue.expiresInHours.toString();
|
||||
if (propsValue.customWebhookUrl)
|
||||
payload.custom_webhook_url = propsValue.customWebhookUrl;
|
||||
if (propsValue.assignedUserEmail)
|
||||
payload.assigned_user_email = propsValue.assignedUserEmail;
|
||||
if (propsValue.labels) payload.labels = propsValue.labels;
|
||||
if (propsValue.test !== undefined)
|
||||
payload.test = propsValue.test ? 'yes' : 'no';
|
||||
if (propsValue.saveAsDraft !== undefined)
|
||||
payload.save_as_draft = propsValue.saveAsDraft ? 'yes' : 'no';
|
||||
if (propsValue.signers) payload.signers = propsValue.signers;
|
||||
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.POST,
|
||||
url: `https://esignatures.com/api/contracts?token=${auth.secret_text}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: payload,
|
||||
});
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
import { PieceAuth } from '@activepieces/pieces-framework';
|
||||
|
||||
export const esignaturesAuth = PieceAuth.SecretText({
|
||||
displayName: 'API Key',
|
||||
description: 'Esignatures API Key',
|
||||
required: true,
|
||||
});
|
||||
@@ -0,0 +1,55 @@
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { esignaturesAuth } from '../common/auth';
|
||||
export const contractSentToASigner = createTrigger({
|
||||
auth: esignaturesAuth,
|
||||
name: 'contractSentToASigner',
|
||||
displayName: 'Contract Sent to a Signer',
|
||||
description: '',
|
||||
props: {},
|
||||
sampleData: {
|
||||
status: 'contract-sent-to-signer',
|
||||
data: {
|
||||
signer: {
|
||||
id: '386b8eb0-aac5-43ce-aa5e-500d5d548934',
|
||||
name: 'test',
|
||||
email: 'test@gmail.com',
|
||||
mobile: null,
|
||||
company_name: 'ss',
|
||||
signing_order: '1',
|
||||
auto_sign: 'no',
|
||||
redirect_url: '',
|
||||
events: [
|
||||
{
|
||||
event: 'email_contract_sent',
|
||||
timestamp: '2025-12-16T10:30:15.390Z',
|
||||
},
|
||||
],
|
||||
},
|
||||
contract: {
|
||||
id: '4efd01d4-d82b-438d-be3e-07099b35bebc',
|
||||
status: 'sent',
|
||||
title: 'Sample Consulting Agreement',
|
||||
metadata: '',
|
||||
labels: [],
|
||||
source: 'ui',
|
||||
test: 'yes',
|
||||
expires_at: '2025-12-30T10:30:12Z',
|
||||
assigned_user_email: 'test@gmail.com',
|
||||
},
|
||||
},
|
||||
},
|
||||
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.status === 'contract-sent-to-signer') {
|
||||
return [context.payload.body];
|
||||
}
|
||||
return [];
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,73 @@
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { esignaturesAuth } from '../common/auth';
|
||||
export const contractSigned = createTrigger({
|
||||
auth: esignaturesAuth,
|
||||
name: 'contractSigned',
|
||||
displayName: 'Contract Signed',
|
||||
description: 'Triggers when a contract is signed',
|
||||
props: {},
|
||||
sampleData: {
|
||||
status: 'contract-signed',
|
||||
data: {
|
||||
contract: {
|
||||
id: '4efd01d4-d82b-438d-be3e-07099b35bebc',
|
||||
status: 'signed',
|
||||
title: 'Sample Consulting Agreement',
|
||||
metadata: '',
|
||||
labels: [],
|
||||
source: 'ui',
|
||||
test: 'yes',
|
||||
contract_pdf_url: '',
|
||||
signers: [
|
||||
{
|
||||
id: '386b8eb0-aac5-43ce-aa5e-500d5d548934',
|
||||
name: 'sanket',
|
||||
email: 'sanketnannaware21@gmail.com',
|
||||
mobile: null,
|
||||
company_name: 'ss',
|
||||
signing_order: '1',
|
||||
auto_sign: 'no',
|
||||
redirect_url: '',
|
||||
events: [
|
||||
{
|
||||
event: 'email_contract_sent',
|
||||
timestamp: '2025-12-16T10:30:15.390Z',
|
||||
},
|
||||
{
|
||||
event: 'contract_viewed',
|
||||
timestamp: '2025-12-16T10:30:33.362Z',
|
||||
remote_ip: '152.59.8.216',
|
||||
},
|
||||
{
|
||||
event: 'sign_contract',
|
||||
timestamp: '2025-12-16T10:30:43.039Z',
|
||||
remote_ip: '152.59.8.216',
|
||||
},
|
||||
{
|
||||
event: 'email_final_contract_sent',
|
||||
timestamp: '2025-12-16T10:30:44.116Z',
|
||||
},
|
||||
],
|
||||
signer_field_values: { 'Signer field 1': '1' },
|
||||
},
|
||||
],
|
||||
finalized_at: '2025-12-16T10:30:43Z',
|
||||
assigned_user_email: 'test@gmail.com',
|
||||
},
|
||||
},
|
||||
},
|
||||
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.status === 'contract-signed') {
|
||||
return [context.payload.body];
|
||||
}
|
||||
return [];
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,49 @@
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { esignaturesAuth } from '../common/auth';
|
||||
export const signatureReceived = createTrigger({
|
||||
auth: esignaturesAuth,
|
||||
name: 'signatureReceived',
|
||||
displayName: 'Signature Received',
|
||||
description: 'Trigger when a singer has signed the contract',
|
||||
props: {},
|
||||
sampleData: {
|
||||
status: 'signer-signed',
|
||||
data: {
|
||||
signer: {
|
||||
id: '6signer6-9999',
|
||||
name: 'Sam Signer',
|
||||
email: 'sam@tenants.com',
|
||||
mobile: '+12481234567',
|
||||
company_name: 'ACME Corp',
|
||||
signing_order: '1',
|
||||
auto_sign: 'no',
|
||||
redirect_url: '',
|
||||
signer_field_values: {
|
||||
city: 'Boston',
|
||||
preferred_contact: 'Phone',
|
||||
},
|
||||
},
|
||||
contract: {
|
||||
id: '1contr11-2222',
|
||||
title: 'Sample NDA',
|
||||
metadata: 'ID0001',
|
||||
source: 'api',
|
||||
test: 'no',
|
||||
},
|
||||
},
|
||||
},
|
||||
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.status === 'signer-signed') {
|
||||
return [context.payload.body];
|
||||
}
|
||||
return [];
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,52 @@
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { esignaturesAuth } from '../common/auth';
|
||||
export const signerDeclined = createTrigger({
|
||||
auth: esignaturesAuth,
|
||||
name: 'signerDeclined',
|
||||
displayName: 'Signer declined',
|
||||
description: 'Trigger when a signer has declined to sign the contract',
|
||||
props: {},
|
||||
sampleData: {
|
||||
status: 'signer-declined',
|
||||
data: {
|
||||
signer: {
|
||||
id: '6signer6-9999',
|
||||
name: 'Sam Signer',
|
||||
email: 'sam@tenants.com',
|
||||
mobile: '+12481234567',
|
||||
company_name: 'ACME Corp',
|
||||
signing_order: '1',
|
||||
auto_sign: 'no',
|
||||
redirect_url: '',
|
||||
events: [
|
||||
{
|
||||
event: 'signature_declined',
|
||||
reason_for_decline: 'Commencement date is 5th of June',
|
||||
timestamp: '2015-10-22T18:19:35.979',
|
||||
},
|
||||
],
|
||||
},
|
||||
contract: {
|
||||
id: '1contr11-2222',
|
||||
title: 'Sample NDA',
|
||||
metadata: 'ID0001',
|
||||
source: 'api',
|
||||
test: 'no',
|
||||
},
|
||||
},
|
||||
},
|
||||
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.status === 'signer-declined') {
|
||||
return [context.payload.body];
|
||||
}
|
||||
return [];
|
||||
},
|
||||
});
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../../dist/out-tsc",
|
||||
"declaration": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
Reference in New Issue
Block a user