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-documerge
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Building
|
||||
|
||||
Run `nx build pieces-documerge` to build the library.
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "@activepieces/piece-documerge",
|
||||
"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-documerge",
|
||||
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "packages/pieces/community/documerge/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/documerge",
|
||||
"tsConfig": "packages/pieces/community/documerge/tsconfig.lib.json",
|
||||
"packageJson": "packages/pieces/community/documerge/package.json",
|
||||
"main": "packages/pieces/community/documerge/src/index.ts",
|
||||
"assets": [
|
||||
"packages/pieces/community/documerge/*.md",
|
||||
{
|
||||
"input": "packages/pieces/community/documerge/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/documerge",
|
||||
"command": "bun install --no-save --silent"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": [
|
||||
"{options.outputFile}"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { createPiece } from '@activepieces/pieces-framework';
|
||||
import { PieceCategory } from '@activepieces/shared';
|
||||
import { documergeAuth } from './lib/common/auth';
|
||||
import { combineFiles } from './lib/actions/combine-files';
|
||||
import { convertFileToPdf } from './lib/actions/convert-file-to-pdf';
|
||||
import { createDataRouteMerge } from './lib/actions/create-data-route-merge';
|
||||
import { createDocumentMerge } from './lib/actions/create-document-merge';
|
||||
import { splitPdf } from './lib/actions/split-pdf';
|
||||
import { newMergedDocument } from './lib/triggers/new-merged-document';
|
||||
import { newMergedRoute } from './lib/triggers/new-merged-route';
|
||||
|
||||
export const documerge = createPiece({
|
||||
displayName: 'DocuMerge',
|
||||
description: 'Merge and generate documents with dynamic data',
|
||||
auth: documergeAuth,
|
||||
minimumSupportedRelease: '0.36.1',
|
||||
logoUrl: 'https://cdn.activepieces.com/pieces/documerge.png',
|
||||
categories: [PieceCategory.CONTENT_AND_FILES],
|
||||
authors: ['onyedikachi-david'],
|
||||
actions: [combineFiles, convertFileToPdf, createDataRouteMerge, createDocumentMerge, splitPdf],
|
||||
triggers: [newMergedDocument, newMergedRoute],
|
||||
});
|
||||
@@ -0,0 +1,95 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { documergeAuth } from '../common/auth';
|
||||
import { DocuMergeClient } from '../common/client';
|
||||
|
||||
export const combineFiles = createAction({
|
||||
auth: documergeAuth,
|
||||
name: 'combine_files',
|
||||
displayName: 'Combine Files',
|
||||
description: 'Combine multiple files into a single PDF or DOCX',
|
||||
props: {
|
||||
output: Property.StaticDropdown({
|
||||
displayName: 'Output Format',
|
||||
description: 'The format of the combined file',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'PDF', value: 'pdf' },
|
||||
{ label: 'DOCX', value: 'docx' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
files: Property.Array({
|
||||
displayName: 'Files',
|
||||
description: 'Array of file identifiers to combine',
|
||||
required: true,
|
||||
}),
|
||||
name: Property.ShortText({
|
||||
displayName: 'Name',
|
||||
description: 'Name for the combined file',
|
||||
required: false,
|
||||
}),
|
||||
url: Property.ShortText({
|
||||
displayName: 'URL',
|
||||
description: 'URL of a file to include (must be a valid URL)',
|
||||
required: false,
|
||||
}),
|
||||
contents: Property.LongText({
|
||||
displayName: 'Contents',
|
||||
description: 'Additional content to include',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { output, files, name, url, contents } = context.propsValue;
|
||||
|
||||
if (!files || files.length === 0) {
|
||||
throw new Error('At least one file is required');
|
||||
}
|
||||
|
||||
const client = new DocuMergeClient(context.auth.secret_text);
|
||||
|
||||
const body: Record<string, unknown> = {
|
||||
output,
|
||||
files: files.filter((f): f is string => typeof f === 'string'),
|
||||
};
|
||||
|
||||
if (name) {
|
||||
body['name'] = name;
|
||||
}
|
||||
|
||||
if (url) {
|
||||
body['url'] = url;
|
||||
}
|
||||
|
||||
if (contents) {
|
||||
body['contents'] = contents;
|
||||
}
|
||||
|
||||
const fileData = await client.makeBinaryRequest(
|
||||
HttpMethod.POST,
|
||||
'/api/tools/combine',
|
||||
body
|
||||
);
|
||||
|
||||
const fileExtension = output === 'pdf' ? 'pdf' : 'docx';
|
||||
const fileName = name
|
||||
? `${name}.${fileExtension}`
|
||||
: `combined_file_${Date.now()}.${fileExtension}`;
|
||||
|
||||
const fileUrl = await context.files.write({
|
||||
fileName,
|
||||
data: Buffer.from(fileData),
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
fileName,
|
||||
fileUrl,
|
||||
format: output,
|
||||
size: fileData.byteLength,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { documergeAuth } from '../common/auth';
|
||||
import { DocuMergeClient } from '../common/client';
|
||||
|
||||
export const convertFileToPdf = createAction({
|
||||
auth: documergeAuth,
|
||||
name: 'convert_file_to_pdf',
|
||||
displayName: 'Convert File to PDF',
|
||||
description: 'Convert a given file to PDF',
|
||||
props: {
|
||||
fileName: Property.ShortText({
|
||||
displayName: 'File Name',
|
||||
description: 'Name of the file to convert',
|
||||
required: true,
|
||||
}),
|
||||
fileUrl: Property.ShortText({
|
||||
displayName: 'File URL',
|
||||
description: 'URL of the file to convert (must be a valid URL)',
|
||||
required: false,
|
||||
}),
|
||||
contents: Property.LongText({
|
||||
displayName: 'Contents',
|
||||
description: 'Additional content to include',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { fileName, fileUrl, contents } = context.propsValue;
|
||||
|
||||
if (!fileName) {
|
||||
throw new Error('File name is required');
|
||||
}
|
||||
|
||||
const client = new DocuMergeClient(context.auth.secret_text);
|
||||
|
||||
const body: Record<string, unknown> = {
|
||||
file: {
|
||||
name: fileName,
|
||||
},
|
||||
};
|
||||
|
||||
if (fileUrl) {
|
||||
(body['file'] as Record<string, unknown>)['url'] = fileUrl;
|
||||
}
|
||||
|
||||
if (contents) {
|
||||
body['contents'] = contents;
|
||||
}
|
||||
|
||||
const fileData = await client.makeBinaryRequest(
|
||||
HttpMethod.POST,
|
||||
'/api/tools/pdf/convert',
|
||||
body
|
||||
);
|
||||
|
||||
const pdfFileName = fileName.endsWith('.pdf')
|
||||
? fileName
|
||||
: `${fileName.replace(/\.[^/.]+$/, '')}.pdf`;
|
||||
|
||||
const fileUrlResult = await context.files.write({
|
||||
fileName: pdfFileName,
|
||||
data: Buffer.from(fileData),
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
fileName: pdfFileName,
|
||||
fileUrl: fileUrlResult,
|
||||
format: 'pdf',
|
||||
size: fileData.byteLength,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { documergeAuth } from '../common/auth';
|
||||
import { DocuMergeClient } from '../common/client';
|
||||
|
||||
export const createDataRouteMerge = createAction({
|
||||
auth: documergeAuth,
|
||||
name: 'create_data_route_merge',
|
||||
displayName: 'Create Data Route Merge',
|
||||
description: 'Send data to your Data Route URL',
|
||||
props: {
|
||||
routeKey: Property.ShortText({
|
||||
displayName: 'Route Key',
|
||||
description: 'The key of the data route to merge',
|
||||
required: true,
|
||||
}),
|
||||
fields: Property.Object({
|
||||
displayName: 'Fields',
|
||||
description: 'Field data to merge into the document',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { routeKey, fields } = context.propsValue;
|
||||
|
||||
if (!routeKey) {
|
||||
throw new Error('Route key is required');
|
||||
}
|
||||
|
||||
const client = new DocuMergeClient(context.auth.secret_text);
|
||||
|
||||
const response = await client.post<{ message: string }>(
|
||||
`/api/routes/merge/${encodeURIComponent(routeKey)}`,
|
||||
fields || {}
|
||||
);
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { documergeAuth } from '../common/auth';
|
||||
import { DocuMergeClient } from '../common/client';
|
||||
|
||||
export const createDocumentMerge = createAction({
|
||||
auth: documergeAuth,
|
||||
name: 'create_document_merge',
|
||||
displayName: 'Create Document Merge',
|
||||
description: 'Send data to your Merge URL',
|
||||
props: {
|
||||
documentKey: Property.ShortText({
|
||||
displayName: 'Document Key',
|
||||
description: 'The key of the document to merge',
|
||||
required: true,
|
||||
}),
|
||||
fields: Property.Object({
|
||||
displayName: 'Fields',
|
||||
description: 'Field data to merge into the document',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { documentKey, fields } = context.propsValue;
|
||||
|
||||
if (!documentKey) {
|
||||
throw new Error('Document key is required');
|
||||
}
|
||||
|
||||
const client = new DocuMergeClient(context.auth.secret_text);
|
||||
|
||||
const response = await client.post<{ message: string }>(
|
||||
`/api/documents/merge/${encodeURIComponent(documentKey)}`,
|
||||
fields || {}
|
||||
);
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { documergeAuth } from '../common/auth';
|
||||
import { DocuMergeClient } from '../common/client';
|
||||
|
||||
export const splitPdf = createAction({
|
||||
auth: documergeAuth,
|
||||
name: 'split_pdf',
|
||||
displayName: 'Split PDF',
|
||||
description: 'Extract or remove specific pages from a PDF file',
|
||||
props: {
|
||||
fileName: Property.ShortText({
|
||||
displayName: 'File Name',
|
||||
description: 'Name of the PDF file',
|
||||
required: true,
|
||||
}),
|
||||
fileUrl: Property.ShortText({
|
||||
displayName: 'File URL',
|
||||
description: 'URL of the PDF file (must be a valid URL)',
|
||||
required: false,
|
||||
}),
|
||||
contents: Property.LongText({
|
||||
displayName: 'Contents',
|
||||
description: 'Base64 encoded file contents',
|
||||
required: false,
|
||||
}),
|
||||
extract: Property.Array({
|
||||
displayName: 'Pages to Extract',
|
||||
description: 'Page numbers or ranges to extract (e.g., "1", "2-5", "1, 3-5")',
|
||||
required: false,
|
||||
}),
|
||||
remove: Property.Array({
|
||||
displayName: 'Pages to Remove',
|
||||
description: 'Page numbers or ranges to remove (e.g., "1", "2-5", "1, 3-5")',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { fileName, fileUrl, contents, extract, remove } = context.propsValue;
|
||||
|
||||
if (!fileName) {
|
||||
throw new Error('File name is required');
|
||||
}
|
||||
|
||||
const client = new DocuMergeClient(context.auth.secret_text);
|
||||
|
||||
const body: Record<string, unknown> = {
|
||||
file: {
|
||||
name: fileName,
|
||||
},
|
||||
};
|
||||
|
||||
if (fileUrl) {
|
||||
(body['file'] as Record<string, unknown>)['url'] = fileUrl;
|
||||
}
|
||||
|
||||
if (contents) {
|
||||
(body['file'] as Record<string, unknown>)['contents'] = contents;
|
||||
}
|
||||
|
||||
if (extract && extract.length > 0) {
|
||||
body['extract'] = extract.filter((e): e is string => typeof e === 'string');
|
||||
}
|
||||
|
||||
if (remove && remove.length > 0) {
|
||||
body['remove'] = remove.filter((r): r is string => typeof r === 'string');
|
||||
}
|
||||
|
||||
const fileData = await client.makeBinaryRequest(
|
||||
HttpMethod.POST,
|
||||
'/api/tools/pdf/split',
|
||||
body
|
||||
);
|
||||
|
||||
const pdfFileName = fileName.endsWith('.pdf')
|
||||
? fileName.replace('.pdf', '_split.pdf')
|
||||
: `${fileName}_split.pdf`;
|
||||
|
||||
const fileUrlResult = await context.files.write({
|
||||
fileName: pdfFileName,
|
||||
data: Buffer.from(fileData),
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
fileName: pdfFileName,
|
||||
fileUrl: fileUrlResult,
|
||||
format: 'pdf',
|
||||
size: fileData.byteLength,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { PieceAuth } from '@activepieces/pieces-framework';
|
||||
import { DocuMergeClient } from './client';
|
||||
|
||||
export const documergeAuth = PieceAuth.SecretText({
|
||||
displayName: 'API Key',
|
||||
description:
|
||||
'Get your API token from your dashboard by clicking API Tokens in the top right corner of your profile.',
|
||||
required: true,
|
||||
validate: async ({ auth }) => {
|
||||
if (!auth || typeof auth !== 'string') {
|
||||
return {
|
||||
valid: false,
|
||||
error: 'Please provide a valid API key.',
|
||||
};
|
||||
}
|
||||
|
||||
const client = new DocuMergeClient(auth);
|
||||
try {
|
||||
await client.get('/api/documents');
|
||||
|
||||
return {
|
||||
valid: true,
|
||||
};
|
||||
} catch (error: any) {
|
||||
const status = error?.response?.status;
|
||||
const message = error?.message || 'Unknown error occurred';
|
||||
|
||||
if (status === 401 || status === 403) {
|
||||
return {
|
||||
valid: false,
|
||||
error: 'Invalid API key. Please verify the key in your DocuMerge dashboard and try again.',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
valid: false,
|
||||
error: `Authentication failed: ${message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
import {
|
||||
AuthenticationType,
|
||||
httpClient,
|
||||
HttpMethod,
|
||||
HttpRequest,
|
||||
QueryParams,
|
||||
} from '@activepieces/pieces-common';
|
||||
|
||||
const BASE_URL = 'https://app.documerge.ai';
|
||||
|
||||
export class DocuMergeClient {
|
||||
constructor(private readonly apiKey: string) {}
|
||||
|
||||
async makeRequest<T>(
|
||||
method: HttpMethod,
|
||||
endpoint: string,
|
||||
body?: unknown,
|
||||
queryParams?: QueryParams
|
||||
): Promise<T> {
|
||||
const url = endpoint.startsWith('/')
|
||||
? `${BASE_URL}${endpoint}`
|
||||
: `${BASE_URL}/${endpoint}`;
|
||||
|
||||
const request: HttpRequest = {
|
||||
method,
|
||||
url,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: this.apiKey,
|
||||
},
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json',
|
||||
},
|
||||
body,
|
||||
queryParams,
|
||||
};
|
||||
|
||||
const response = await httpClient.sendRequest<T>(request);
|
||||
return response.body;
|
||||
}
|
||||
|
||||
async get<T>(endpoint: string, queryParams?: QueryParams): Promise<T> {
|
||||
return this.makeRequest<T>(HttpMethod.GET, endpoint, undefined, queryParams);
|
||||
}
|
||||
|
||||
async post<T>(endpoint: string, body?: unknown, queryParams?: QueryParams): Promise<T> {
|
||||
return this.makeRequest<T>(HttpMethod.POST, endpoint, body, queryParams);
|
||||
}
|
||||
|
||||
async patch<T>(endpoint: string, body?: unknown, queryParams?: QueryParams): Promise<T> {
|
||||
return this.makeRequest<T>(HttpMethod.PATCH, endpoint, body, queryParams);
|
||||
}
|
||||
|
||||
async put<T>(endpoint: string, body?: unknown, queryParams?: QueryParams): Promise<T> {
|
||||
return this.makeRequest<T>(HttpMethod.PUT, endpoint, body, queryParams);
|
||||
}
|
||||
|
||||
async delete<T>(endpoint: string, queryParams?: QueryParams): Promise<T> {
|
||||
return this.makeRequest<T>(HttpMethod.DELETE, endpoint, undefined, queryParams);
|
||||
}
|
||||
|
||||
async makeBinaryRequest(
|
||||
method: HttpMethod,
|
||||
endpoint: string,
|
||||
body?: unknown,
|
||||
queryParams?: QueryParams
|
||||
): Promise<ArrayBuffer> {
|
||||
const url = endpoint.startsWith('/')
|
||||
? `${BASE_URL}${endpoint}`
|
||||
: `${BASE_URL}/${endpoint}`;
|
||||
|
||||
const request: HttpRequest = {
|
||||
method,
|
||||
url,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: this.apiKey,
|
||||
},
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json',
|
||||
},
|
||||
body,
|
||||
queryParams,
|
||||
responseType: 'arraybuffer',
|
||||
};
|
||||
|
||||
const response = await httpClient.sendRequest<ArrayBuffer>(request);
|
||||
const responseBody: unknown = response.body;
|
||||
|
||||
if (typeof responseBody === 'string') {
|
||||
return Buffer.from(responseBody, 'binary').buffer as ArrayBuffer;
|
||||
}
|
||||
|
||||
if (responseBody instanceof ArrayBuffer) {
|
||||
return responseBody;
|
||||
}
|
||||
|
||||
if (Buffer.isBuffer(responseBody)) {
|
||||
const buf = responseBody as Buffer;
|
||||
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength) as ArrayBuffer;
|
||||
}
|
||||
|
||||
return Buffer.from(responseBody as string).buffer as ArrayBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import {
|
||||
createTrigger,
|
||||
Property,
|
||||
TriggerStrategy,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { documergeAuth } from '../common/auth';
|
||||
|
||||
export const newMergedDocument = createTrigger({
|
||||
auth: documergeAuth,
|
||||
name: 'new_merged_document',
|
||||
displayName: 'New Merged Document',
|
||||
description: 'Triggers when a merged/populated document is created',
|
||||
props: {
|
||||
webhookInstructions: Property.MarkDown({
|
||||
value: `
|
||||
## Setup Instructions
|
||||
|
||||
To use this trigger, configure a Webhook Delivery Method in DocuMerge:
|
||||
|
||||
1. Go to your DocuMerge dashboard
|
||||
2. Navigate to your Document or Route settings
|
||||
3. Add a new **Webhook Delivery Method**
|
||||
4. Set the **URL** to:
|
||||
\`\`\`text
|
||||
{{webhookUrl}}
|
||||
\`\`\`
|
||||
5. Configure the webhook options:
|
||||
- ✅ **Send temporary download url (file_url)** - Provides a 1-hour download link
|
||||
- ✅ **Send data using JSON** - Sends data as JSON
|
||||
- ✅ **Send merge data** - Includes field data in the payload
|
||||
6. Click **Submit** to save
|
||||
|
||||
The webhook will trigger whenever a document is merged.
|
||||
`,
|
||||
}),
|
||||
},
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
sampleData: {
|
||||
file_url: 'https://app.documerge.ai/download/temp/abc123...',
|
||||
fields: {
|
||||
first_name: 'John',
|
||||
last_name: 'Doe',
|
||||
email: 'john.doe@example.com',
|
||||
company: 'Acme Inc',
|
||||
},
|
||||
document_name: 'Contract_JohnDoe.pdf',
|
||||
document_id: '12345',
|
||||
merged_at: '2024-01-15T10:30:00Z',
|
||||
},
|
||||
async onEnable(context) {
|
||||
// Webhook URL is automatically provided by Activepieces
|
||||
// User needs to manually configure the webhook URL in DocuMerge dashboard
|
||||
},
|
||||
async onDisable(context) {
|
||||
// User should remove webhook delivery method from DocuMerge dashboard
|
||||
},
|
||||
async run(context) {
|
||||
return [context.payload.body];
|
||||
},
|
||||
});
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import {
|
||||
createTrigger,
|
||||
Property,
|
||||
TriggerStrategy,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { documergeAuth } from '../common/auth';
|
||||
|
||||
export const newMergedRoute = createTrigger({
|
||||
auth: documergeAuth,
|
||||
name: 'new_merged_route',
|
||||
displayName: 'New Merged Route',
|
||||
description: 'Triggers when a merged/populated route is created',
|
||||
props: {
|
||||
webhookInstructions: Property.MarkDown({
|
||||
value: `
|
||||
## Setup Instructions
|
||||
|
||||
To use this trigger, configure a Webhook Delivery Method in DocuMerge:
|
||||
|
||||
1. Go to your DocuMerge dashboard
|
||||
2. Navigate to your **Route** settings
|
||||
3. Add a new **Webhook Delivery Method**
|
||||
4. Set the **URL** to:
|
||||
\`\`\`text
|
||||
{{webhookUrl}}
|
||||
\`\`\`
|
||||
5. Configure the webhook options:
|
||||
- ✅ **Send temporary download url (file_url)** - Provides a 1-hour download link
|
||||
- ✅ **Send data using JSON** - Sends data as JSON
|
||||
- ✅ **Send merge data** - Includes field data in the payload
|
||||
6. Click **Submit** to save
|
||||
|
||||
The webhook will trigger whenever a route merge is completed.
|
||||
`,
|
||||
}),
|
||||
},
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
sampleData: {
|
||||
file_url: 'https://app.documerge.ai/download/temp/xyz789...',
|
||||
fields: {
|
||||
first_name: 'Jane',
|
||||
last_name: 'Smith',
|
||||
email: 'jane.smith@example.com',
|
||||
company: 'Tech Corp',
|
||||
},
|
||||
route_name: 'Customer Onboarding',
|
||||
route_id: '67890',
|
||||
merged_at: '2024-01-15T14:45:00Z',
|
||||
},
|
||||
async onEnable(context) {
|
||||
// Webhook URL is automatically provided by Activepieces
|
||||
// User needs to manually configure the webhook URL in DocuMerge dashboard
|
||||
},
|
||||
async onDisable(context) {
|
||||
// User should remove webhook delivery method from DocuMerge dashboard
|
||||
},
|
||||
async run(context) {
|
||||
return [context.payload.body];
|
||||
},
|
||||
});
|
||||
|
||||
@@ -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