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,28 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { parseurAuth, parseurCommon } from '../common';
|
||||
import { parserDropdown } from '../common/properties';
|
||||
|
||||
export const createDocumentFromFile = createAction({
|
||||
auth: parseurAuth,
|
||||
name: 'createDocumentFromFile',
|
||||
displayName: 'Create Document from File',
|
||||
description: 'Creates new document in mailbox from file.',
|
||||
props: {
|
||||
parserId: parserDropdown({ required: true }),
|
||||
file: Property.File({
|
||||
displayName: 'File',
|
||||
description: 'Select the file to upload',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run({ auth: apiKey, propsValue: { parserId, file } }) {
|
||||
if (!parserId) {
|
||||
throw new Error('Parser is required');
|
||||
}
|
||||
return await parseurCommon.createDocumentFromFile({
|
||||
apiKey: apiKey.secret_text,
|
||||
parserId,
|
||||
file,
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,69 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { parseurAuth, parseurCommon } from '../common';
|
||||
|
||||
export const createDocument = createAction({
|
||||
auth: parseurAuth,
|
||||
name: 'createDocument',
|
||||
displayName: 'Create Document',
|
||||
description: 'Creates a new document.',
|
||||
props: {
|
||||
subject: Property.ShortText({
|
||||
displayName: 'Subject',
|
||||
description: 'The subject of the document/email.',
|
||||
required: true,
|
||||
}),
|
||||
from: Property.ShortText({
|
||||
displayName: 'From',
|
||||
description: 'The sender email address.',
|
||||
required: true,
|
||||
}),
|
||||
recipient: Property.ShortText({
|
||||
displayName: 'Recipient',
|
||||
description: 'The recipient email address.',
|
||||
required: true,
|
||||
}),
|
||||
to: Property.ShortText({
|
||||
displayName: 'To',
|
||||
description: 'The "To" email address.',
|
||||
required: false,
|
||||
}),
|
||||
cc: Property.ShortText({
|
||||
displayName: 'CC',
|
||||
description: 'The "CC" email address.',
|
||||
required: false,
|
||||
}),
|
||||
bcc: Property.ShortText({
|
||||
displayName: 'BCC',
|
||||
description: 'The "BCC" email address.',
|
||||
required: false,
|
||||
}),
|
||||
body_html: Property.LongText({
|
||||
displayName: 'Body HTML',
|
||||
description: 'The HTML content of the document/email.',
|
||||
required: false,
|
||||
}),
|
||||
body_plain: Property.LongText({
|
||||
displayName: 'Body Plain',
|
||||
description: 'The plain text content of the document/email.',
|
||||
required: false,
|
||||
}),
|
||||
message_headers: Property.Object({
|
||||
displayName: 'Message Headers',
|
||||
description:
|
||||
'A JSON object representing the email headers (key-value pairs).',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run({ auth: apiKey, propsValue }) {
|
||||
const { message_headers, ...rest } = propsValue;
|
||||
return await parseurCommon.createDocument({
|
||||
apiKey:apiKey.secret_text,
|
||||
...rest,
|
||||
message_headers: message_headers
|
||||
? Object.fromEntries(
|
||||
Object.entries(message_headers).map(([k, v]) => [k, String(v)])
|
||||
)
|
||||
: undefined,
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { parseurAuth, parseurCommon } from '../common';
|
||||
import { parserDropdown } from '../common/properties';
|
||||
|
||||
export const findDocument = createAction({
|
||||
auth: parseurAuth,
|
||||
name: 'findDocument',
|
||||
displayName: 'Find Document',
|
||||
description: 'Finds a document based on search param.',
|
||||
props: {
|
||||
parserId: parserDropdown({ required: true }),
|
||||
search: Property.ShortText({
|
||||
displayName: 'Search',
|
||||
description:
|
||||
'The search term to filter documents by name. Case insensitive. If empty, all documents are returned.',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run({ auth: apiKey, propsValue: { parserId, search } }) {
|
||||
if (!parserId) {
|
||||
throw new Error('Parser ID is required');
|
||||
}
|
||||
return await parseurCommon.listDocuments({
|
||||
apiKey:apiKey.secret_text,
|
||||
parserId,
|
||||
search,
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { parseurAuth, parseurCommon } from '../common';
|
||||
import { documentDropdown, parserDropdown } from '../common/properties';
|
||||
|
||||
export const getParsedDocumentById = createAction({
|
||||
auth: parseurAuth,
|
||||
name: 'getParsedDocumentById',
|
||||
displayName: 'Get Parsed Document by ID',
|
||||
description: 'Fetch parsed JSON / structured output for a given document ID',
|
||||
props: {
|
||||
parserId: parserDropdown({ required: true }),
|
||||
documentId: documentDropdown({ required: true }),
|
||||
},
|
||||
async run({ auth: apiKey, propsValue: { documentId } }) {
|
||||
if (!documentId) {
|
||||
throw new Error('Document ID is required');
|
||||
}
|
||||
return await parseurCommon.getDocument({ apiKey: apiKey.secret_text, documentId });
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { parseurAuth, parseurCommon } from '../common';
|
||||
import { documentDropdown, parserDropdown } from '../common/properties';
|
||||
|
||||
export const reprocessDocument = createAction({
|
||||
auth: parseurAuth,
|
||||
name: 'reprocessDocument',
|
||||
displayName: 'Reprocess Document',
|
||||
description:
|
||||
'Send an existing document back through parsing (e.g. after updating template).',
|
||||
props: {
|
||||
parserId: parserDropdown({ required: true }),
|
||||
documentId: documentDropdown({ required: true }),
|
||||
},
|
||||
async run({ auth: apiKey, propsValue: { documentId } }) {
|
||||
if (!documentId) {
|
||||
throw new Error('Document ID is required');
|
||||
}
|
||||
return await parseurCommon.reprocessDocument({
|
||||
apiKey:apiKey.secret_text,
|
||||
documentId,
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,189 @@
|
||||
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { PieceAuth } from '@activepieces/pieces-framework';
|
||||
import {
|
||||
CreateDocumentFromFileParams,
|
||||
CreateDocumentFromFileResponse,
|
||||
CreateDocumentParams,
|
||||
CreateDocumentResponse,
|
||||
CreateWebhookParams,
|
||||
CreateWebhookResponse,
|
||||
DeleteWebhookParams,
|
||||
EnableWebhookParams,
|
||||
GetParsedDocumentByIdParams,
|
||||
GetParsedDocumentByIdResponse,
|
||||
ListDocumentsParams,
|
||||
ListDocumentsResponse,
|
||||
ListMailboxesParams,
|
||||
ListMailboxesResponse,
|
||||
ReprocessDocumentParams,
|
||||
ReprocessDocumentResponse,
|
||||
} from './types';
|
||||
|
||||
export const parseurAuth = PieceAuth.SecretText({
|
||||
displayName: 'API Key',
|
||||
description:
|
||||
'Create a new API key in Account → API keys in the Parseur app: https://app.parseur.com/account/api-keys',
|
||||
required: true,
|
||||
});
|
||||
|
||||
export const parseurCommon = {
|
||||
baseUrl: 'https://api.parseur.com',
|
||||
endpoints: {
|
||||
listDocuments: (parserId: number) => `/parser/${parserId}/document_set`,
|
||||
getParsedDocumentById: (documentId: string) => `/document/${documentId}`,
|
||||
createDocument: '/email',
|
||||
createDocumentFromFile: (parserId: number) => `/parser/${parserId}/upload`,
|
||||
reprocessDocument: (documentId: string) =>
|
||||
`/document/${documentId}/process`,
|
||||
listMailboxes: '/parser',
|
||||
createWebhook: '/webhook',
|
||||
enableWebhook: (webhookId: number, mailboxId: number) =>
|
||||
`/parser/${mailboxId}/webhook_set/${webhookId}`,
|
||||
deleteWebhook: (webhookId: number) => `/webhook/${webhookId}`,
|
||||
},
|
||||
getHeaders: (apiKey: string) => {
|
||||
return {
|
||||
Authorization: apiKey,
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
},
|
||||
// API methods
|
||||
listDocuments: async ({
|
||||
apiKey,
|
||||
parserId,
|
||||
...queryParams
|
||||
}: ListDocumentsParams) => {
|
||||
const { page, page_size, with_result, ...rest } = queryParams;
|
||||
const parsedQuery = {
|
||||
...(page != undefined ? { page: String(page) } : {}),
|
||||
...(page_size != undefined ? { page_size: String(page_size) } : {}),
|
||||
...(with_result != undefined ? { with_result: String(with_result) } : {}),
|
||||
...rest,
|
||||
};
|
||||
const response = await httpClient.sendRequest<ListDocumentsResponse>({
|
||||
method: HttpMethod.GET,
|
||||
url:
|
||||
parseurCommon.baseUrl + parseurCommon.endpoints.listDocuments(parserId),
|
||||
headers: parseurCommon.getHeaders(apiKey),
|
||||
queryParams: parsedQuery,
|
||||
});
|
||||
return response.body;
|
||||
},
|
||||
getDocument: async ({ apiKey, documentId }: GetParsedDocumentByIdParams) => {
|
||||
const response =
|
||||
await httpClient.sendRequest<GetParsedDocumentByIdResponse>({
|
||||
method: HttpMethod.GET,
|
||||
url:
|
||||
parseurCommon.baseUrl +
|
||||
parseurCommon.endpoints.getParsedDocumentById(documentId),
|
||||
headers: parseurCommon.getHeaders(apiKey),
|
||||
});
|
||||
return response.body;
|
||||
},
|
||||
createDocument: async ({
|
||||
apiKey,
|
||||
...documentParams
|
||||
}: CreateDocumentParams) => {
|
||||
const response = await httpClient.sendRequest<CreateDocumentResponse>({
|
||||
method: HttpMethod.POST,
|
||||
url: parseurCommon.baseUrl + parseurCommon.endpoints.createDocument,
|
||||
headers: parseurCommon.getHeaders(apiKey),
|
||||
body: documentParams,
|
||||
});
|
||||
return response.body;
|
||||
},
|
||||
createDocumentFromFile: async ({
|
||||
apiKey,
|
||||
file,
|
||||
parserId,
|
||||
}: CreateDocumentFromFileParams) => {
|
||||
const data = new FormData();
|
||||
const uint8 = new Uint8Array(file.data);
|
||||
data.append('file', new Blob([uint8]), file.filename);
|
||||
data.append('parserId', String(parserId));
|
||||
const response =
|
||||
await httpClient.sendRequest<CreateDocumentFromFileResponse>({
|
||||
method: HttpMethod.POST,
|
||||
url:
|
||||
parseurCommon.baseUrl +
|
||||
parseurCommon.endpoints.createDocumentFromFile(parserId),
|
||||
headers: {
|
||||
...parseurCommon.getHeaders(apiKey),
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
body: data,
|
||||
});
|
||||
return response.body;
|
||||
},
|
||||
reprocessDocument: async ({
|
||||
apiKey,
|
||||
documentId,
|
||||
}: ReprocessDocumentParams) => {
|
||||
const response = await httpClient.sendRequest<ReprocessDocumentResponse>({
|
||||
method: HttpMethod.POST,
|
||||
url:
|
||||
parseurCommon.baseUrl +
|
||||
parseurCommon.endpoints.reprocessDocument(documentId),
|
||||
headers: parseurCommon.getHeaders(apiKey),
|
||||
});
|
||||
return response.body;
|
||||
},
|
||||
listMailboxes: async ({ apiKey, ...queryParams }: ListMailboxesParams) => {
|
||||
const { page, page_size, ...rest } = queryParams;
|
||||
const parsedQuery = {
|
||||
...(page != undefined ? { page: String(page) } : {}),
|
||||
...(page_size != undefined ? { page_size: String(page_size) } : {}),
|
||||
...rest,
|
||||
};
|
||||
const response = await httpClient.sendRequest<ListMailboxesResponse>({
|
||||
method: HttpMethod.GET,
|
||||
url: parseurCommon.baseUrl + parseurCommon.endpoints.listMailboxes,
|
||||
headers: parseurCommon.getHeaders(apiKey),
|
||||
queryParams: parsedQuery,
|
||||
});
|
||||
return response.body;
|
||||
},
|
||||
createWebhook: async ({ apiKey, ...webhookParams }: CreateWebhookParams) => {
|
||||
const reponse = await httpClient.sendRequest<CreateWebhookResponse>({
|
||||
method: HttpMethod.POST,
|
||||
url: parseurCommon.baseUrl + parseurCommon.endpoints.createWebhook,
|
||||
headers: parseurCommon.getHeaders(apiKey),
|
||||
body: webhookParams,
|
||||
});
|
||||
return reponse.body;
|
||||
},
|
||||
enableWebhook: async ({
|
||||
apiKey,
|
||||
webhookId,
|
||||
mailboxId,
|
||||
}: EnableWebhookParams) => {
|
||||
const response = await httpClient.sendRequest<void>({
|
||||
method: HttpMethod.POST,
|
||||
url:
|
||||
parseurCommon.baseUrl +
|
||||
parseurCommon.endpoints.enableWebhook(webhookId, mailboxId),
|
||||
headers: parseurCommon.getHeaders(apiKey),
|
||||
});
|
||||
if (response.status === 200 || response.status === 204) {
|
||||
return { success: true };
|
||||
} else {
|
||||
return { success: false };
|
||||
}
|
||||
},
|
||||
deleteWebhook: async ({ apiKey, webhookId }: DeleteWebhookParams) => {
|
||||
const response = await httpClient.sendRequest<void>({
|
||||
method: HttpMethod.DELETE,
|
||||
url:
|
||||
parseurCommon.baseUrl +
|
||||
parseurCommon.endpoints.deleteWebhook(webhookId),
|
||||
headers: parseurCommon.getHeaders(apiKey),
|
||||
});
|
||||
if (response.status === 200 || response.status === 204) {
|
||||
return { success: true };
|
||||
} else {
|
||||
return { success: false };
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// Common Properties
|
||||
@@ -0,0 +1,97 @@
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
import { parseurAuth, parseurCommon } from '.';
|
||||
|
||||
export const parserDropdown = ({ required = true }) =>
|
||||
Property.Dropdown({
|
||||
auth: parseurAuth,
|
||||
displayName: 'Parser',
|
||||
description: 'Select the parser',
|
||||
required,
|
||||
refreshers: ['auth'],
|
||||
refreshOnSearch: true,
|
||||
options: async ({ auth: apiKey }, { searchValue: search }) => {
|
||||
if (!apiKey) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please select an API Key first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
if (search != undefined) {
|
||||
const response = await parseurCommon.listMailboxes({
|
||||
apiKey: apiKey.secret_text,
|
||||
search,
|
||||
});
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.results.map((parser) => ({
|
||||
label: parser.name,
|
||||
value: parser.id,
|
||||
})),
|
||||
};
|
||||
} else {
|
||||
const response = await parseurCommon.listMailboxes({
|
||||
apiKey: apiKey.secret_text,
|
||||
});
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.results.map((parser) => ({
|
||||
label: parser.name,
|
||||
value: parser.id,
|
||||
})),
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const documentDropdown = ({ required = true }) =>
|
||||
Property.Dropdown({
|
||||
auth: parseurAuth,
|
||||
displayName: 'Document',
|
||||
description: 'Select the document',
|
||||
required,
|
||||
refreshers: ['auth', 'parserId'],
|
||||
refreshOnSearch: true,
|
||||
options: async ({ auth: apiKey, parserId }, { searchValue: search }) => {
|
||||
if (!apiKey) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please select an API Key first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
if (!parserId) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please select a Parser first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
if (search != undefined) {
|
||||
const response = await parseurCommon.listDocuments({
|
||||
apiKey: apiKey.secret_text,
|
||||
parserId: parserId as number,
|
||||
search,
|
||||
});
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.results.map((document) => ({
|
||||
label: document.name,
|
||||
value: document.id.toString(),
|
||||
})),
|
||||
};
|
||||
} else {
|
||||
const response = await parseurCommon.listDocuments({
|
||||
apiKey: apiKey.secret_text,
|
||||
parserId: parserId as number,
|
||||
});
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.results.map((document) => ({
|
||||
label: document.name,
|
||||
value: document.id.toString(),
|
||||
})),
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,382 @@
|
||||
import { ApFile } from '@activepieces/pieces-framework';
|
||||
|
||||
// Common Types
|
||||
export interface AuthenticationParams {
|
||||
apiKey: string;
|
||||
}
|
||||
|
||||
type TemplateSample = {
|
||||
template_id: number;
|
||||
name: string;
|
||||
sample_count: number;
|
||||
};
|
||||
|
||||
type OcrPage = {
|
||||
image: {
|
||||
url: string;
|
||||
width: number;
|
||||
height: number;
|
||||
content_type: string;
|
||||
};
|
||||
position: number;
|
||||
included_in_range: boolean;
|
||||
};
|
||||
|
||||
type Webhook = {
|
||||
id: number;
|
||||
event:
|
||||
| 'document.processed'
|
||||
| 'document.processed.flattened'
|
||||
| 'document.template_needed'
|
||||
| 'document.export_failed'
|
||||
| 'table.processed';
|
||||
target: string;
|
||||
name: string;
|
||||
headers: Record<string, string>;
|
||||
category: 'CUSTOM' | 'ZAPIER' | 'MAKE' | 'FLOW' | 'N8N';
|
||||
parser_field_set: string[];
|
||||
};
|
||||
|
||||
interface BaseParser {
|
||||
account_uuid: string;
|
||||
ai_engine: string;
|
||||
attachments_only: boolean;
|
||||
attachments_only_override: null;
|
||||
can_transform: boolean;
|
||||
disable_deskew: boolean;
|
||||
enable_layouted_text: boolean;
|
||||
enable_image_ocr: boolean;
|
||||
document_count: number;
|
||||
document_per_status_count: {
|
||||
INCOMING: number;
|
||||
ANALYZING: number;
|
||||
PROGRESS: number;
|
||||
PARSEDOK: number;
|
||||
PARSEDKO: number;
|
||||
QUOTAEXC: number;
|
||||
SKIPPED: number;
|
||||
SPLIT: number;
|
||||
DELETED: number;
|
||||
EXPORTKO: number;
|
||||
TRANSKO: number;
|
||||
INVALID: number;
|
||||
};
|
||||
email_prefix: string;
|
||||
even_pages: boolean;
|
||||
force_ocr: boolean;
|
||||
id: number;
|
||||
is_master: boolean;
|
||||
last_activity: string;
|
||||
name: string;
|
||||
odd_pages: boolean;
|
||||
page_range_set: string[];
|
||||
parser_object_count: number;
|
||||
parser_object_set_last_modified: null;
|
||||
process_attachments: boolean;
|
||||
retention_policy: number;
|
||||
template_count: number;
|
||||
webhook_count: number;
|
||||
attachments_field: boolean;
|
||||
original_document_field: boolean;
|
||||
searchable_pdf_field: boolean;
|
||||
headers_field: boolean;
|
||||
received_field: boolean;
|
||||
received_date_field: boolean;
|
||||
received_time_field: boolean;
|
||||
processed_field: boolean;
|
||||
processed_date_field: boolean;
|
||||
processed_time_field: boolean;
|
||||
sender_field: boolean;
|
||||
sender_name_field: boolean;
|
||||
split_page_range_field: boolean;
|
||||
recipient_field: boolean;
|
||||
to_field: boolean;
|
||||
cc_field: boolean;
|
||||
bcc_field: boolean;
|
||||
reply_to_field: boolean;
|
||||
recipient_suffix_field: boolean;
|
||||
original_recipient_field: boolean;
|
||||
subject_field: boolean;
|
||||
template_field: boolean;
|
||||
html_document_field: boolean;
|
||||
text_document_field: boolean;
|
||||
content_field: boolean;
|
||||
last_reply_field: boolean;
|
||||
document_id_field: boolean;
|
||||
parent_id_field: boolean;
|
||||
document_url_field: boolean;
|
||||
public_document_url_field: boolean;
|
||||
page_count_field: boolean;
|
||||
credit_count_field: boolean;
|
||||
mailbox_id_field: boolean;
|
||||
parsing_engine_field: boolean;
|
||||
}
|
||||
|
||||
interface Parser extends BaseParser {
|
||||
split_keywords: null;
|
||||
split_page: null;
|
||||
split_page_range_set: string[];
|
||||
available_webhook_set: string[];
|
||||
webhook_set: string[];
|
||||
table_set: string[];
|
||||
}
|
||||
|
||||
interface ParserDiet extends BaseParser {
|
||||
split_keywords: { keyword: string; is_before: boolean }[] | null;
|
||||
split_page: number | null;
|
||||
split_page_range_set: { start_index: number; end_index: number }[];
|
||||
template_count: number;
|
||||
webhook_count: number;
|
||||
attachments_field: boolean;
|
||||
original_document_field: boolean;
|
||||
available_webhook_set: Webhook[];
|
||||
webhook_set: Webhook[];
|
||||
table_set: { id: string; name: string }[];
|
||||
}
|
||||
|
||||
interface Document {
|
||||
attached_to: null;
|
||||
id: number;
|
||||
match_master_template: boolean;
|
||||
name: string;
|
||||
ocr_ready_url: null;
|
||||
original_document_url: string;
|
||||
parser: number;
|
||||
processed: string;
|
||||
received: string;
|
||||
sample_set: string[];
|
||||
status_source: string;
|
||||
status: string;
|
||||
template: null;
|
||||
credits_used: number;
|
||||
conventional_credits_used: number;
|
||||
ai_credits_used: number;
|
||||
is_ai_ready: boolean;
|
||||
is_ocr_ready: boolean;
|
||||
is_processable: boolean;
|
||||
is_splittable: boolean;
|
||||
is_split: boolean;
|
||||
json_download_url: string;
|
||||
csv_download_url: string;
|
||||
xls_download_url: string;
|
||||
}
|
||||
|
||||
interface DocumentDiet {
|
||||
attached_to: number | null;
|
||||
id: number;
|
||||
name: string;
|
||||
match_master_template: boolean;
|
||||
ocr_ready_url: string | null;
|
||||
original_document_url: string;
|
||||
parser: number;
|
||||
processed: string;
|
||||
received: string;
|
||||
sample_set: TemplateSample[];
|
||||
status_source: 'AI' | 'AUTO' | 'CSV' | 'METADATA' | 'TEMPLATE' | 'TRANSFORM';
|
||||
status:
|
||||
| 'INCOMING'
|
||||
| 'ANALYZING'
|
||||
| 'PROGRESS'
|
||||
| 'PARSEDOK'
|
||||
| 'PARSEDKO'
|
||||
| 'SKIPPED'
|
||||
| 'SPLIT'
|
||||
| 'EXPORTKO'
|
||||
| 'TRANSKO'
|
||||
| 'INVALID';
|
||||
template: number | null;
|
||||
credits_used: number;
|
||||
conventional_credits_used: number;
|
||||
ai_credits_used: number;
|
||||
is_ai_ready: boolean;
|
||||
is_ocr_ready: boolean;
|
||||
is_processable: boolean;
|
||||
is_splittable: boolean;
|
||||
is_split: boolean;
|
||||
json_download_url: string;
|
||||
csv_download_url: string;
|
||||
xls_download_url: string;
|
||||
result: string | null;
|
||||
}
|
||||
|
||||
export interface WebhookInformation {
|
||||
webhookId: number;
|
||||
}
|
||||
// API Types
|
||||
export interface ListDocumentsParams extends AuthenticationParams {
|
||||
parserId: number;
|
||||
page?: number;
|
||||
page_size?: number;
|
||||
search?: string;
|
||||
ordering?:
|
||||
| 'name'
|
||||
| '-name'
|
||||
| 'created'
|
||||
| '-created'
|
||||
| 'processed'
|
||||
| '-processed'
|
||||
| 'status'
|
||||
| '-status';
|
||||
received_after?: string; // yyyy-mm-dd
|
||||
received_before?: string; // yyyy-mm-dd
|
||||
tz?: string; // Example: "Asia/Singapore"
|
||||
with_result?: boolean;
|
||||
}
|
||||
|
||||
export interface ListDocumentsResponse {
|
||||
count: number;
|
||||
current: number;
|
||||
total: number;
|
||||
results: (DocumentDiet | Document)[];
|
||||
}
|
||||
|
||||
export interface GetParsedDocumentByIdParams extends AuthenticationParams {
|
||||
documentId: string;
|
||||
}
|
||||
|
||||
export interface GetParsedDocumentByIdResponse {
|
||||
attached_to: number | null;
|
||||
id: number;
|
||||
match_master_template: boolean;
|
||||
name: string;
|
||||
ocr_ready_url: string | null;
|
||||
original_document_url: string;
|
||||
parser: number;
|
||||
processed: string;
|
||||
received: string;
|
||||
sample_set: TemplateSample[];
|
||||
status_source: 'AI' | 'AUTO' | 'CSV' | 'METADATA' | 'TEMPLATE' | 'TRANSFORM';
|
||||
status:
|
||||
| 'INCOMING'
|
||||
| 'ANALYZING'
|
||||
| 'PROGRESS'
|
||||
| 'PARSEDOK'
|
||||
| 'PARSEDKO'
|
||||
| 'SKIPPED'
|
||||
| 'SPLIT'
|
||||
| 'EXPORTKO'
|
||||
| 'TRANSKO'
|
||||
| 'INVALID';
|
||||
template: number | null;
|
||||
credits_used: number;
|
||||
conventional_credits_used: number;
|
||||
ai_credits_used: number;
|
||||
is_ai_ready: boolean;
|
||||
is_ocr_ready: boolean;
|
||||
is_processable: boolean;
|
||||
is_splittable: boolean;
|
||||
json_download_url: string;
|
||||
csv_download_url: string;
|
||||
xls_download_url: string;
|
||||
result: string | null;
|
||||
content: string;
|
||||
next_id: number | null;
|
||||
previous_id: number | null;
|
||||
ocr_page_set: OcrPage[];
|
||||
}
|
||||
|
||||
export interface CreateDocumentParams extends AuthenticationParams {
|
||||
subject: string;
|
||||
from: string;
|
||||
recipient: string;
|
||||
to?: string;
|
||||
cc?: string;
|
||||
bcc?: string;
|
||||
body_html?: string;
|
||||
body_plain?: string;
|
||||
message_headers?: Record<string, string>;
|
||||
}
|
||||
|
||||
export interface CreateDocumentResponse {
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface CreateDocumentFromFileParams extends AuthenticationParams {
|
||||
parserId: number;
|
||||
file: ApFile;
|
||||
}
|
||||
|
||||
export interface CreateDocumentFromFileResponse {
|
||||
message: string;
|
||||
attachments: { name: string; DocumentID: string }[];
|
||||
}
|
||||
|
||||
export interface ReprocessDocumentParams extends AuthenticationParams {
|
||||
documentId: string;
|
||||
}
|
||||
|
||||
export interface ReprocessDocumentResponse {
|
||||
notification_set: {
|
||||
info: string[];
|
||||
};
|
||||
}
|
||||
|
||||
export interface ListMailboxesParams extends AuthenticationParams {
|
||||
page?: number;
|
||||
page_size?: number;
|
||||
search?: string;
|
||||
ordering?:
|
||||
| 'name'
|
||||
| '-name'
|
||||
| 'document_count'
|
||||
| '-document_count'
|
||||
| 'template_count'
|
||||
| '-template_count'
|
||||
| 'PARSEDOK_count'
|
||||
| '-PARSEDOK_count'
|
||||
| 'PARSEDKO_count'
|
||||
| '-PARSEDKO_count'
|
||||
| 'QUOTAEXC_count'
|
||||
| '-QUOTAEXC_count'
|
||||
| 'EXPORTKO_count'
|
||||
| '-EXPORTKO_count'
|
||||
| 'TRANSKO_count'
|
||||
| '-TRANSKO_count';
|
||||
}
|
||||
|
||||
export interface ListMailboxesResponse {
|
||||
count: number;
|
||||
current: number;
|
||||
total: number;
|
||||
results: (ParserDiet | Parser)[];
|
||||
}
|
||||
|
||||
export interface CreateWebhookParams extends AuthenticationParams {
|
||||
event:
|
||||
| 'document.processed'
|
||||
| 'document.processed.flattened'
|
||||
| 'document.template_needed'
|
||||
| 'document.export_failed'
|
||||
| 'table.processed';
|
||||
target: string;
|
||||
name?: string;
|
||||
headers?: Record<string, string>;
|
||||
category: 'CUSTOM' | 'ZAPIER' | 'MAKE' | 'FLOW' | 'N8N';
|
||||
parser_field_set?: string[];
|
||||
}
|
||||
|
||||
export interface CreateWebhookResponse {
|
||||
id: number;
|
||||
event:
|
||||
| 'document.processed'
|
||||
| 'document.processed.flattened'
|
||||
| 'document.template_needed'
|
||||
| 'document.export_failed'
|
||||
| 'table.processed';
|
||||
target: string;
|
||||
name: string;
|
||||
headers: Record<string, string>;
|
||||
category: 'CUSTOM' | 'ZAPIER' | 'MAKE' | 'FLOW' | 'N8N';
|
||||
parser_field_set: string[];
|
||||
}
|
||||
|
||||
export interface EnableWebhookParams extends AuthenticationParams {
|
||||
webhookId: number;
|
||||
mailboxId: number;
|
||||
}
|
||||
|
||||
export interface DeleteWebhookParams extends AuthenticationParams {
|
||||
webhookId: number;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { parseurAuth, parseurCommon } from '../common';
|
||||
import { parserDropdown } from '../common/properties';
|
||||
import { WebhookInformation } from '../common/types';
|
||||
|
||||
export const newDocumentExportFailed = createTrigger({
|
||||
auth: parseurAuth,
|
||||
name: 'newDocumentExportFailed',
|
||||
displayName: 'New Document Export Failed',
|
||||
description:
|
||||
'Fires when an automated export endpoint (webhook / integration) fails for a processed document.',
|
||||
props: { mailboxId: parserDropdown({ required: true }) },
|
||||
sampleData: {},
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
async onEnable(context) {
|
||||
const response = await parseurCommon.createWebhook({
|
||||
apiKey: context.auth.secret_text,
|
||||
event: 'document.export_failed',
|
||||
target: context.webhookUrl,
|
||||
category: 'CUSTOM',
|
||||
});
|
||||
await parseurCommon.enableWebhook({
|
||||
apiKey: context.auth.secret_text,
|
||||
webhookId: response.id,
|
||||
mailboxId: context.propsValue.mailboxId as number,
|
||||
});
|
||||
await context.store.put<WebhookInformation>('_newDocumentExportFailed', {
|
||||
webhookId: response.id,
|
||||
});
|
||||
},
|
||||
async onDisable(context) {
|
||||
const webhookInfo = await context.store.get<WebhookInformation>(
|
||||
'_newDocumentExportFailed'
|
||||
);
|
||||
if (!webhookInfo) {
|
||||
return;
|
||||
}
|
||||
await parseurCommon.deleteWebhook({
|
||||
apiKey: context.auth.secret_text,
|
||||
webhookId: webhookInfo.webhookId,
|
||||
});
|
||||
await context.store.delete('_newDocumentExportFailed');
|
||||
},
|
||||
async run(context) {
|
||||
return [context.payload.body];
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,49 @@
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { parseurAuth, parseurCommon } from '../common';
|
||||
import { parserDropdown } from '../common/properties';
|
||||
import { WebhookInformation } from '../common/types';
|
||||
|
||||
export const newDocumentNotProcessed = createTrigger({
|
||||
auth: parseurAuth,
|
||||
name: 'newDocumentNotProcessed',
|
||||
displayName: 'New Document Not Processed',
|
||||
description:
|
||||
'Fires when Parseur fails to parse a document (e.g. no matching template).',
|
||||
props: {
|
||||
mailboxId: parserDropdown({ required: false }),
|
||||
},
|
||||
sampleData: {},
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
async onEnable(context) {
|
||||
const response = await parseurCommon.createWebhook({
|
||||
apiKey: context.auth.secret_text,
|
||||
event: 'document.template_needed',
|
||||
target: context.webhookUrl,
|
||||
category: 'CUSTOM',
|
||||
});
|
||||
await parseurCommon.enableWebhook({
|
||||
apiKey: context.auth.secret_text,
|
||||
webhookId: response.id,
|
||||
mailboxId: context.propsValue.mailboxId as number,
|
||||
});
|
||||
await context.store.put<WebhookInformation>('_newDocumentNotProcessed', {
|
||||
webhookId: response.id,
|
||||
});
|
||||
},
|
||||
async onDisable(context) {
|
||||
const webhookInfo = await context.store.get<WebhookInformation>(
|
||||
'_newDocumentNotProcessed'
|
||||
);
|
||||
if (!webhookInfo) {
|
||||
return;
|
||||
}
|
||||
await parseurCommon.deleteWebhook({
|
||||
apiKey: context.auth.secret_text,
|
||||
webhookId: webhookInfo.webhookId,
|
||||
});
|
||||
await context.store.delete('_newDocumentNotProcessed');
|
||||
},
|
||||
async run(context) {
|
||||
return [context.payload.body];
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,49 @@
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { parseurAuth, parseurCommon } from '../common';
|
||||
import { parserDropdown } from '../common/properties';
|
||||
import { WebhookInformation } from '../common/types';
|
||||
|
||||
export const newDocumentProcessed = createTrigger({
|
||||
auth: parseurAuth,
|
||||
name: 'newDocumentProcessed',
|
||||
displayName: 'New Document Processed',
|
||||
description:
|
||||
'Fires when a new document is successfully processed and parsed by Parseur.',
|
||||
props: {
|
||||
mailboxId: parserDropdown({ required: true }),
|
||||
},
|
||||
sampleData: {},
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
async onEnable(context) {
|
||||
const webhookCreateResponse = await parseurCommon.createWebhook({
|
||||
apiKey: context.auth.secret_text,
|
||||
event: 'document.processed',
|
||||
target: context.webhookUrl,
|
||||
category: 'CUSTOM',
|
||||
});
|
||||
await parseurCommon.enableWebhook({
|
||||
apiKey: context.auth.secret_text,
|
||||
webhookId: webhookCreateResponse.id,
|
||||
mailboxId: context.propsValue.mailboxId as number,
|
||||
});
|
||||
await context.store.put<WebhookInformation>('_newDocumentProcessed', {
|
||||
webhookId: webhookCreateResponse.id,
|
||||
});
|
||||
},
|
||||
async onDisable(context) {
|
||||
const webhookInfo = await context.store.get<WebhookInformation>(
|
||||
'_newDocumentProcessed'
|
||||
);
|
||||
if (!webhookInfo) {
|
||||
return;
|
||||
}
|
||||
await parseurCommon.deleteWebhook({
|
||||
apiKey: context.auth.secret_text,
|
||||
webhookId: webhookInfo.webhookId,
|
||||
});
|
||||
await context.store.delete('_newDocumentProcessed');
|
||||
},
|
||||
async run(context) {
|
||||
return [context.payload.body];
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,55 @@
|
||||
import {
|
||||
DedupeStrategy,
|
||||
Polling,
|
||||
pollingHelper,
|
||||
} from '@activepieces/pieces-common';
|
||||
import {
|
||||
AppConnectionValueForAuthProperty,
|
||||
createTrigger,
|
||||
PiecePropValueSchema,
|
||||
TriggerStrategy,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { parseurAuth, parseurCommon } from '../common';
|
||||
|
||||
const polling: Polling<
|
||||
AppConnectionValueForAuthProperty<typeof parseurAuth>,
|
||||
Record<string, never>
|
||||
> = {
|
||||
strategy: DedupeStrategy.LAST_ITEM,
|
||||
items: async ({ auth: apiKey }) => {
|
||||
const response = await parseurCommon.listMailboxes({
|
||||
apiKey: apiKey.secret_text,
|
||||
});
|
||||
const items = response.results;
|
||||
return items.map((item) => ({
|
||||
id: item.id,
|
||||
data: item,
|
||||
}));
|
||||
},
|
||||
};
|
||||
|
||||
export const newMailbox = createTrigger({
|
||||
auth: parseurAuth,
|
||||
name: 'newMailbox',
|
||||
displayName: 'New Mailbox',
|
||||
description: 'Fires when a new mailbox is created in the Parseur account.',
|
||||
props: {},
|
||||
sampleData: {},
|
||||
type: TriggerStrategy.POLLING,
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context);
|
||||
},
|
||||
async onEnable(context) {
|
||||
const { store, auth, propsValue } = context;
|
||||
await pollingHelper.onEnable(polling, { store, auth, propsValue });
|
||||
},
|
||||
|
||||
async onDisable(context) {
|
||||
const { store, auth, propsValue } = context;
|
||||
await pollingHelper.onDisable(polling, { store, auth, propsValue });
|
||||
},
|
||||
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,49 @@
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { parseurAuth, parseurCommon } from '../common';
|
||||
import { parserDropdown } from '../common/properties';
|
||||
import { WebhookInformation } from '../common/types';
|
||||
|
||||
export const newTableFieldProcessed = createTrigger({
|
||||
auth: parseurAuth,
|
||||
name: 'newTableFieldProcessed',
|
||||
displayName: 'New Table Field Processed',
|
||||
description:
|
||||
'Fires when a document with table fields is processed, and triggers for each row (table field) separately.',
|
||||
props: {
|
||||
mailboxId: parserDropdown({ required: true }),
|
||||
},
|
||||
sampleData: {},
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
async onEnable(context) {
|
||||
const response = await parseurCommon.createWebhook({
|
||||
apiKey: context.auth.secret_text,
|
||||
event: 'table.processed',
|
||||
target: context.webhookUrl,
|
||||
category: 'CUSTOM',
|
||||
});
|
||||
await parseurCommon.enableWebhook({
|
||||
apiKey: context.auth.secret_text,
|
||||
webhookId: response.id,
|
||||
mailboxId: context.propsValue.mailboxId as number,
|
||||
});
|
||||
await context.store.put<WebhookInformation>('_newTableFieldProcessed', {
|
||||
webhookId: response.id,
|
||||
});
|
||||
},
|
||||
async onDisable(context) {
|
||||
const webhookInfo = await context.store.get<WebhookInformation>(
|
||||
'_newTableFieldProcessed'
|
||||
);
|
||||
if (!webhookInfo) {
|
||||
return;
|
||||
}
|
||||
await parseurCommon.deleteWebhook({
|
||||
apiKey: context.auth.secret_text,
|
||||
webhookId: webhookInfo.webhookId,
|
||||
});
|
||||
await context.store.delete('_newTableFieldProcessed');
|
||||
},
|
||||
async run(context) {
|
||||
return [context.payload.body];
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user