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-omni-co
This library was generated with [Nx](https://nx.dev).
## Building
Run `nx build pieces-omni-co` to build the library.

View File

@@ -0,0 +1,10 @@
{
"name": "@activepieces/piece-omni-co",
"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-omni-co",
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/pieces/community/omni-co/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/omni-co",
"tsConfig": "packages/pieces/community/omni-co/tsconfig.lib.json",
"packageJson": "packages/pieces/community/omni-co/package.json",
"main": "packages/pieces/community/omni-co/src/index.ts",
"assets": [
"packages/pieces/community/omni-co/*.md",
{
"input": "packages/pieces/community/omni-co/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/omni-co",
"command": "bun install --no-save --silent"
}
},
"lint": {
"executor": "@nx/eslint:lint",
"outputs": [
"{options.outputFile}"
]
}
}
}

View File

@@ -0,0 +1,114 @@
{
"\n": "\n",
"Create a document": "Create a document",
"Create a schedule": "Create a schedule",
"Delete a document": "Delete a document",
"Delete a schedule": "Delete a schedule",
"Edit schedule": "Edit schedule",
"Generate query": "Generate query",
"Move document": "Move document",
"Run query": "Run query",
"Custom API Call": "Custom API Call",
"Creates a new document": "Creates a new document",
"Creates a scheduled task for a dashboard with support for email, SFTP, and webhook destinations": "Creates a scheduled task for a dashboard with support for email, SFTP, and webhook destinations",
"Deletes the specified document and places it in the Trash": "Deletes the specified document and places it in the Trash",
"Deletes a schedule using its UUID": "Deletes a schedule using its UUID",
"Updates a scheduled task. Only properties included will be updated": "Updates a scheduled task. Only properties included will be updated",
"Transforms a natural language description into a structured Omni query": "Transforms a natural language description into a structured Omni query",
"Moves a document to a new folder or to the root level": "Moves a document to a new folder or to the root level",
"Runs a query and returns the results as base64 encoded Apache Arrow table or in specified format": "Runs a query and returns the results as base64 encoded Apache Arrow table or in specified format",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Model ID": "Model ID",
"Document Name": "Document Name",
"Query Presentations": "Query Presentations",
"Dashboard Identifier": "Dashboard Identifier",
"Schedule Name": "Schedule Name",
"Schedule (Cron Expression)": "Schedule (Cron Expression)",
"Timezone": "Timezone",
"Format": "Format",
"Destination Type": "Destination Type",
"URL": "URL",
"Recipients": "Recipients",
"Email Subject": "Email Subject",
"Paper Format": "Paper Format",
"Paper Orientation": "Paper Orientation",
"Document": "Document",
"Schedule": "Schedule",
"Prompt": "Prompt",
"Current Topic Name": "Current Topic Name",
"Branch ID": "Branch ID",
"Context Query": "Context Query",
"Structured Output": "Structured Output",
"Folder Path": "Folder Path",
"Scope": "Scope",
"Query": "Query",
"Limit": "Limit",
"Cache Policy": "Cache Policy",
"Format Results": "Format Results",
"Result Type": "Result Type",
"Plan Only": "Plan Only",
"User ID": "User ID",
"Method": "Method",
"Headers": "Headers",
"Query Parameters": "Query Parameters",
"Body": "Body",
"Response is Binary ?": "Response is Binary ?",
"No Error on Failure": "No Error on Failure",
"Timeout (in seconds)": "Timeout (in seconds)",
"Select the model containing the database": "Select the model containing the database",
"The name of the document": "The name of the document",
"An array of queryPresentation objects, each representing a query in the document's workbook": "An array of queryPresentation objects, each representing a query in the document's workbook",
" The string after /dashboards is the dashboards ID; for example: https://blobsrus.omniapp.co/dashboards/12db1a0a": " The string after /dashboards is the dashboards ID; for example: https://blobsrus.omniapp.co/dashboards/12db1a0a",
"The name of the schedule/task": "The name of the schedule/task",
"Cron expression for the schedule (e.g., \"0 9 ? * * *\" for 9 AM UTC daily) https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-scheduled-rule-pattern.html": "Cron expression for the schedule (e.g., \"0 9 ? * * *\" for 9 AM UTC daily) https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-scheduled-rule-pattern.html",
"Timezone for the schedule (e.g., \"UTC\", \"America/New_York\") Refer : https://data.iana.org/time-zones/tzdb-2021a/zone1970.tab": "Timezone for the schedule (e.g., \"UTC\", \"America/New_York\") Refer : https://data.iana.org/time-zones/tzdb-2021a/zone1970.tab",
"Output format for the schedule": "Output format for the schedule",
"Type of destination for the schedule": "Type of destination for the schedule",
"Webhook URL (required when destinationType is webhook)": "Webhook URL (required when destinationType is webhook)",
"Email recipients (required when destinationType is email)": "Email recipients (required when destinationType is email)",
"Subject line for email delivery": "Subject line for email delivery",
"Paper format for PDF output": "Paper format for PDF output",
"Paper orientation for PDF output": "Paper orientation for PDF output",
"Select the document": "Select the document",
"Select the schedule": "Select the schedule",
"The natural language description of the query you want to generate (e.g., \"Show me all users who signed up in the last month\")": "The natural language description of the query you want to generate (e.g., \"Show me all users who signed up in the last month\")",
"The name of the topic to use as context for the query generation": "The name of the topic to use as context for the query generation",
"The ID of the model branch to use for query generation. If not provided, the main branch will be used": "The ID of the model branch to use for query generation. If not provided, the main branch will be used",
"The query object to provide as context. This can be used to reference previous queries or provide additional context for the generation": "The query object to provide as context. This can be used to reference previous queries or provide additional context for the generation",
"When enabled, the API will return a more strictly structured query format": "When enabled, the API will return a more strictly structured query format",
"The path of the destination folder. Use null to move the document to the root level (no folder)": "The path of the destination folder. Use null to move the document to the root level (no folder)",
"Optional sharing scope for the document. If not provided, the scope will be computed": "Optional sharing scope for the document. If not provided, the scope will be computed",
"A JSON object representing the query to be run. You can retrieve a query's JSON object from an Omni workbook by opening the Inspector panel (Option + 9 on Mac, Alt + 9 on Windows) and copying the Query structure": "A JSON object representing the query to be run. You can retrieve a query's JSON object from an Omni workbook by opening the Inspector panel (Option + 9 on Mac, Alt + 9 on Windows) and copying the Query structure",
"Number of rows to be returned (defaults to 1000). Set to null for unlimited results": "Number of rows to be returned (defaults to 1000). Set to null for unlimited results",
"Optional cache policy to control how query caching behaves": "Optional cache policy to control how query caching behaves",
"Apply formatting to numeric and currency values (currency symbols and thousand separators)": "Apply formatting to numeric and currency values (currency symbols and thousand separators)",
"Specifies the format of query results. If omitted, returns base64 encoded Apache Arrow format": "Specifies the format of query results. If omitted, returns base64 encoded Apache Arrow format",
"If enabled, returns the query execution plan without running the query": "If enabled, returns the query execution plan without running the query",
"Optional UUID to run the query as a specific user": "Optional UUID to run the query as a specific user",
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
"Link Only": "Link Only",
"PDF": "PDF",
"PNG": "PNG",
"CSV": "CSV",
"XLSX": "XLSX",
"JSON": "JSON",
"Email": "Email",
"Webhook": "Webhook",
"SFTP": "SFTP",
"Letter": "Letter",
"A4": "A4",
"Portrait": "Portrait",
"Landscape": "Landscape",
"Organization": "Organization",
"Restricted": "Restricted",
"Standard": "Standard",
"Skip Requery (default)": "Skip Requery (default)",
"Skip Cache": "Skip Cache",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD"
}

View File

@@ -0,0 +1,39 @@
import { createPiece } from '@activepieces/pieces-framework';
import { PieceCategory } from '@activepieces/shared';
import { omniAuth } from './lib/common/auth';
import { createADocument } from './lib/actions/create-a-document';
import { createASchedule } from './lib/actions/create-a-schedule';
import { deleteADocument } from './lib/actions/delete-a-document';
import { deleteASchedule } from './lib/actions/delete-a-schedule';
import { moveDocument } from './lib/actions/move-document';
import { runQuery } from './lib/actions/run-query';
import { editSchedule } from './lib/actions/edit-schedule';
import { generateQuery } from './lib/actions/generate-query';
import { createCustomApiCallAction } from '@activepieces/pieces-common';
export const omniCo = createPiece({
displayName: 'Omni',
auth: omniAuth,
minimumSupportedRelease: '0.36.1',
logoUrl: 'https://cdn.activepieces.com/pieces/omni-co.png',
categories: [PieceCategory.BUSINESS_INTELLIGENCE],
authors: ['sanket-a11y'],
actions: [
createADocument,
createASchedule,
deleteADocument,
deleteASchedule,
editSchedule,
generateQuery,
moveDocument,
runQuery,
createCustomApiCallAction({
baseUrl: () => 'https://blobsrus.omniapp.co/api/v1',
auth: omniAuth,
authMapping: async (auth) => ({
Authorization: `Bearer ${auth.secret_text}`,
}),
}),
],
triggers: [],
});

View File

@@ -0,0 +1,47 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { omniAuth } from '../common/auth';
import { makeRequest } from '../common/client';
import { HttpMethod } from '@activepieces/pieces-common';
import { modelIdDropdown } from '../common/props';
export const createADocument = createAction({
auth: omniAuth,
name: 'createADocument',
displayName: 'Create a document',
description: 'Creates a new document',
props: {
modelId: modelIdDropdown,
name: Property.ShortText({
displayName: 'Document Name',
description: 'The name of the document',
required: true,
}),
queryPresentations: Property.Array({
displayName: 'Query Presentations',
description:
"An array of queryPresentation objects, each representing a query in the document's workbook",
required: false,
}),
},
async run(context) {
const { modelId, name, queryPresentations } = context.propsValue;
const body: Record<string, unknown> = {
modelId,
name,
};
if (queryPresentations) {
body['queryPresentations'] = queryPresentations;
}
const response = await makeRequest(
context.auth.secret_text,
HttpMethod.POST,
'/documents',
body
);
return response;
},
});

View File

@@ -0,0 +1,158 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { omniAuth } from '../common/auth';
import { makeRequest } from '../common/client';
import { HttpMethod } from '@activepieces/pieces-common';
export const createASchedule = createAction({
auth: omniAuth,
name: 'createASchedule',
displayName: 'Create a schedule',
description:
'Creates a scheduled task for a dashboard with support for email, SFTP, and webhook destinations',
props: {
identifier: Property.ShortText({
displayName: 'Dashboard Identifier',
description:
' The string after /dashboards is the dashboards ID; for example: https://blobsrus.omniapp.co/dashboards/12db1a0a',
required: true,
}),
name: Property.ShortText({
displayName: 'Schedule Name',
description: 'The name of the schedule/task',
required: true,
}),
schedule: Property.ShortText({
displayName: 'Schedule (Cron Expression)',
description:
'Cron expression for the schedule (e.g., "0 9 ? * * *" for 9 AM UTC daily) https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-scheduled-rule-pattern.html',
required: true,
}),
timezone: Property.ShortText({
displayName: 'Timezone',
description:
'Timezone for the schedule (e.g., "UTC", "America/New_York") Refer : https://data.iana.org/time-zones/tzdb-2021a/zone1970.tab',
required: true,
}),
format: Property.StaticDropdown({
displayName: 'Format',
description: 'Output format for the schedule',
options: {
disabled: false,
options: [
{ label: 'Link Only', value: 'link_only' },
{ label: 'PDF', value: 'pdf' },
{ label: 'PNG', value: 'png' },
{ label: 'CSV', value: 'csv' },
{ label: 'XLSX', value: 'xlsx' },
{ label: 'JSON', value: 'json' },
],
},
required: true,
}),
destinationType: Property.StaticDropdown({
displayName: 'Destination Type',
description: 'Type of destination for the schedule',
options: {
disabled: false,
options: [
{ label: 'Email', value: 'email' },
{ label: 'Webhook', value: 'webhook' },
{ label: 'SFTP', value: 'sftp' },
],
},
required: true,
}),
url: Property.ShortText({
displayName: 'URL',
description: 'Webhook URL (required when destinationType is webhook)',
required: false,
}),
recipients: Property.Array({
displayName: 'Recipients',
description: 'Email recipients (required when destinationType is email)',
required: false,
}),
subject: Property.ShortText({
displayName: 'Email Subject',
description: 'Subject line for email delivery',
required: false,
}),
paperFormat: Property.StaticDropdown({
displayName: 'Paper Format',
description: 'Paper format for PDF output',
options: {
disabled: false,
options: [
{ label: 'Letter', value: 'letter' },
{ label: 'A4', value: 'a4' },
],
},
required: false,
}),
paperOrientation: Property.StaticDropdown({
displayName: 'Paper Orientation',
description: 'Paper orientation for PDF output',
options: {
disabled: false,
options: [
{ label: 'Portrait', value: 'portrait' },
{ label: 'Landscape', value: 'landscape' },
],
},
required: false,
}),
},
async run(context) {
const {
identifier,
name,
schedule,
timezone,
format,
destinationType,
url,
recipients,
subject,
paperFormat,
paperOrientation,
} = context.propsValue;
const body: Record<string, unknown> = {
identifier,
name,
schedule,
timezone,
format,
destinationType,
};
if (url) {
body['url'] = url;
}
if (recipients) {
body['recipients'] = recipients;
}
if (subject) {
body['subject'] = subject;
}
if (paperFormat) {
body['paperFormat'] = paperFormat;
}
if (paperOrientation) {
body['paperOrientation'] = paperOrientation;
}
const response = await makeRequest(
context.auth.secret_text,
HttpMethod.POST,
'/schedules',
body
);
return response;
},
});

View File

@@ -0,0 +1,27 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { omniAuth } from '../common/auth';
import { makeRequest } from '../common/client';
import { HttpMethod } from '@activepieces/pieces-common';
import { documentIdDropdown } from '../common/props';
export const deleteADocument = createAction({
auth: omniAuth,
name: 'deleteADocument',
displayName: 'Delete a document',
description: 'Deletes the specified document and places it in the Trash',
props: {
documentId: documentIdDropdown,
},
async run(context) {
const { documentId } = context.propsValue;
const response = await makeRequest(
context.auth.secret_text,
HttpMethod.DELETE,
`/documents/${documentId}`,
{}
);
return response;
},
});

View File

@@ -0,0 +1,27 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { omniAuth } from '../common/auth';
import { makeRequest } from '../common/client';
import { HttpMethod } from '@activepieces/pieces-common';
import { scheduleIdDropdown } from '../common/props';
export const deleteASchedule = createAction({
auth: omniAuth,
name: 'deleteASchedule',
displayName: 'Delete a schedule',
description: 'Deletes a schedule using its UUID',
props: {
scheduleId: scheduleIdDropdown,
},
async run(context) {
const { scheduleId } = context.propsValue;
const response = await makeRequest(
context.auth.secret_text,
HttpMethod.DELETE,
`/schedules/${scheduleId}`,
{}
);
return response;
},
});

View File

@@ -0,0 +1,167 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { omniAuth } from '../common/auth';
import { makeRequest } from '../common/client';
import { HttpMethod } from '@activepieces/pieces-common';
import { scheduleIdDropdown } from '../common/props';
export const editSchedule = createAction({
auth: omniAuth,
name: 'editSchedule',
displayName: 'Edit schedule',
description:
'Updates a scheduled task. Only properties included will be updated',
props: {
scheduleId: scheduleIdDropdown,
name: Property.ShortText({
displayName: 'Schedule Name',
description: 'The name of the schedule/task',
required: true,
}),
schedule: Property.ShortText({
displayName: 'Schedule (Cron Expression)',
description:
'Cron expression for the schedule (e.g., "0 9 ? * * *" for 9 AM UTC daily) https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-scheduled-rule-pattern.html',
required: true,
}),
timezone: Property.ShortText({
displayName: 'Timezone',
description:
'Timezone for the schedule (e.g., "UTC", "America/New_York") Refer : https://data.iana.org/time-zones/tzdb-2021a/zone1970.tab',
required: true,
}),
format: Property.StaticDropdown({
displayName: 'Format',
description: 'Output format for the schedule',
options: {
disabled: false,
options: [
{ label: 'Link Only', value: 'link_only' },
{ label: 'PDF', value: 'pdf' },
{ label: 'PNG', value: 'png' },
{ label: 'CSV', value: 'csv' },
{ label: 'XLSX', value: 'xlsx' },
{ label: 'JSON', value: 'json' },
],
},
required: true,
}),
destinationType: Property.StaticDropdown({
displayName: 'Destination Type',
description: 'Type of destination for the schedule',
options: {
disabled: false,
options: [
{ label: 'Email', value: 'email' },
{ label: 'Webhook', value: 'webhook' },
{ label: 'SFTP', value: 'sftp' },
],
},
required: true,
}),
url: Property.ShortText({
displayName: 'URL',
description: 'Webhook URL (required when destinationType is webhook)',
required: false,
}),
recipients: Property.Array({
displayName: 'Recipients',
description: 'Email recipients (required when destinationType is email)',
required: false,
}),
subject: Property.ShortText({
displayName: 'Email Subject',
description: 'Subject line for email delivery',
required: false,
}),
paperFormat: Property.StaticDropdown({
displayName: 'Paper Format',
description: 'Paper format for PDF output',
options: {
disabled: false,
options: [
{ label: 'Letter', value: 'letter' },
{ label: 'A4', value: 'a4' },
],
},
required: false,
}),
paperOrientation: Property.StaticDropdown({
displayName: 'Paper Orientation',
description: 'Paper orientation for PDF output',
options: {
disabled: false,
options: [
{ label: 'Portrait', value: 'portrait' },
{ label: 'Landscape', value: 'landscape' },
],
},
required: false,
}),
},
async run(context) {
const {
scheduleId,
name,
schedule,
timezone,
format,
destinationType,
url,
recipients,
subject,
paperFormat,
paperOrientation,
} = context.propsValue;
const body: Record<string, unknown> = {};
if (name) {
body['name'] = name;
}
if (schedule) {
body['schedule'] = schedule;
}
if (timezone) {
body['timezone'] = timezone;
}
if (format) {
body['format'] = format;
}
if (destinationType) {
body['destinationType'] = destinationType;
}
if (url) {
body['url'] = url;
}
if (recipients) {
body['recipients'] = recipients;
}
if (subject) {
body['subject'] = subject;
}
if (paperFormat) {
body['paperFormat'] = paperFormat;
}
if (paperOrientation) {
body['paperOrientation'] = paperOrientation;
}
const response = await makeRequest(
context.auth.secret_text,
HttpMethod.PUT,
`/schedules/${scheduleId}`,
body
);
return response;
},
});

View File

@@ -0,0 +1,87 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { omniAuth } from '../common/auth';
import { makeRequest } from '../common/client';
import { HttpMethod } from '@activepieces/pieces-common';
import { modelIdDropdown } from '../common/props';
export const generateQuery = createAction({
auth: omniAuth,
name: 'generateQuery',
displayName: 'Generate query',
description:
'Transforms a natural language description into a structured Omni query',
props: {
modelId: modelIdDropdown,
prompt: Property.LongText({
displayName: 'Prompt',
description:
'The natural language description of the query you want to generate (e.g., "Show me all users who signed up in the last month")',
required: true,
}),
currentTopicName: Property.ShortText({
displayName: 'Current Topic Name',
description:
'The name of the topic to use as context for the query generation',
required: false,
}),
branchId: Property.ShortText({
displayName: 'Branch ID',
description:
'The ID of the model branch to use for query generation. If not provided, the main branch will be used',
required: false,
}),
contextQuery: Property.Json({
displayName: 'Context Query',
description:
'The query object to provide as context. This can be used to reference previous queries or provide additional context for the generation',
required: false,
}),
structured: Property.Checkbox({
displayName: 'Structured Output',
description:
'When enabled, the API will return a more strictly structured query format',
required: false,
defaultValue: false,
}),
},
async run(context) {
const {
modelId,
prompt,
currentTopicName,
branchId,
contextQuery,
structured,
} = context.propsValue;
const body: Record<string, unknown> = {
modelId,
prompt,
};
if (currentTopicName) {
body['currentTopicName'] = currentTopicName;
}
if (branchId) {
body['branchId'] = branchId;
}
if (contextQuery) {
body['contextQuery'] = contextQuery;
}
if (structured) {
body['structured'] = structured;
}
const response = await makeRequest(
context.auth.secret_text,
HttpMethod.POST,
'/ai/generate-query',
body
);
return response;
},
});

View File

@@ -0,0 +1,54 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { omniAuth } from '../common/auth';
import { makeRequest } from '../common/client';
import { HttpMethod } from '@activepieces/pieces-common';
import { documentIdDropdown } from '../common/props';
export const moveDocument = createAction({
auth: omniAuth,
name: 'moveDocument',
displayName: 'Move document',
description: 'Moves a document to a new folder or to the root level',
props: {
identifier: documentIdDropdown,
folderPath: Property.ShortText({
displayName: 'Folder Path',
description:
'The path of the destination folder. Use null to move the document to the root level (no folder)',
required: true,
}),
scope: Property.StaticDropdown({
displayName: 'Scope',
description:
'Optional sharing scope for the document. If not provided, the scope will be computed',
options: {
disabled: false,
options: [
{ label: 'Organization', value: 'organization' },
{ label: 'Restricted', value: 'restricted' },
],
},
required: false,
}),
},
async run(context) {
const { identifier, folderPath, scope } = context.propsValue;
const body: Record<string, unknown> = {
folderPath: folderPath === 'null' ? null : folderPath,
};
if (scope) {
body['scope'] = scope;
}
const response = await makeRequest(
context.auth.secret_text,
HttpMethod.PUT,
`/documents/${identifier}/move`,
body
);
return response;
},
});

View File

@@ -0,0 +1,113 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { omniAuth } from '../common/auth';
import { makeRequest } from '../common/client';
import { HttpMethod } from '@activepieces/pieces-common';
export const runQuery = createAction({
auth: omniAuth,
name: 'runQuery',
displayName: 'Run query',
description:
'Runs a query and returns the results as base64 encoded Apache Arrow table or in specified format',
props: {
query: Property.Json({
displayName: 'Query',
description:
"A JSON object representing the query to be run. You can retrieve a query's JSON object from an Omni workbook by opening the Inspector panel (Option + 9 on Mac, Alt + 9 on Windows) and copying the Query structure",
required: true,
}),
limit: Property.Number({
displayName: 'Limit',
description:
'Number of rows to be returned (defaults to 1000). Set to null for unlimited results',
required: false,
}),
cache: Property.StaticDropdown({
displayName: 'Cache Policy',
description: 'Optional cache policy to control how query caching behaves',
options: {
disabled: false,
options: [
{ label: 'Standard', value: 'Standard' },
{ label: 'Skip Requery (default)', value: 'SkipRequery' },
{ label: 'Skip Cache', value: 'SkipCache' },
],
},
required: false,
}),
formatResults: Property.Checkbox({
displayName: 'Format Results',
description:
'Apply formatting to numeric and currency values (currency symbols and thousand separators)',
required: false,
defaultValue: true,
}),
resultType: Property.StaticDropdown({
displayName: 'Result Type',
description:
'Specifies the format of query results. If omitted, returns base64 encoded Apache Arrow format',
options: {
disabled: false,
options: [
{ label: 'CSV', value: 'csv' },
{ label: 'JSON', value: 'json' },
{ label: 'XLSX', value: 'xlsx' },
],
},
required: false,
}),
planOnly: Property.Checkbox({
displayName: 'Plan Only',
description:
'If enabled, returns the query execution plan without running the query',
required: false,
defaultValue: false,
}),
userId: Property.ShortText({
displayName: 'User ID',
description: 'Optional UUID to run the query as a specific user',
required: false,
}),
},
async run(context) {
const { query, limit, cache, formatResults, resultType, planOnly, userId } =
context.propsValue;
const body: Record<string, unknown> = {
query,
};
if (limit !== undefined && limit !== null) {
body['limit'] = limit;
}
if (cache) {
body['cache'] = cache;
}
if (formatResults !== undefined) {
body['formatResults'] = formatResults;
}
if (resultType) {
body['resultType'] = resultType;
}
if (planOnly) {
body['planOnly'] = planOnly;
}
if (userId) {
body['userId'] = userId;
}
const response = await makeRequest(
context.auth.secret_text,
HttpMethod.POST,
'/query/run',
body
);
return response;
},
});

View File

@@ -0,0 +1,29 @@
import { PieceAuth } from '@activepieces/pieces-framework';
import { makeRequest } from './client';
import { HttpMethod } from '@activepieces/pieces-common';
export const omniAuth = PieceAuth.SecretText({
displayName: 'Omni API Key',
description: `
`,
required: true,
validate: async ({ auth }) => {
if (auth) {
try {
await makeRequest(auth as string, HttpMethod.GET, '/models', {});
return {
valid: true,
};
} catch (error) {
return {
valid: false,
error: 'Invalid Api Key',
};
}
}
return {
valid: false,
error: 'Invalid Api Key',
};
},
});

View File

@@ -0,0 +1,25 @@
import { HttpMethod, httpClient } from '@activepieces/pieces-common';
export const BASE_URL = `https://blobsrus.omniapp.co/api/v1`;
export async function makeRequest(
api_key: string,
method: HttpMethod,
path: string,
body?: unknown
) {
try {
const response = await httpClient.sendRequest({
method,
url: `${BASE_URL}${path}`,
headers: {
Authorization: `Bearer ${api_key}`,
'Content-Type': 'application/json',
},
body,
});
return response.body;
} catch (error: any) {
throw new Error(`Unexpected error: ${error.message || String(error)}`);
}
}

View File

@@ -0,0 +1,127 @@
import { HttpMethod } from '@activepieces/pieces-common';
import { makeRequest } from './client';
import { Property } from '@activepieces/pieces-framework';
import { omniAuth } from './auth';
export const modelIdDropdown = Property.Dropdown({
auth: omniAuth,
displayName: 'Model ID',
description: 'Select the model containing the database',
required: true,
refreshers: [],
options: async ({ auth }) => {
if (!auth) {
return {
disabled: true,
options: [],
placeholder: 'Please connect your account first',
};
}
try {
const models = await makeRequest(
auth.secret_text,
HttpMethod.GET,
'/models',
{}
);
return {
disabled: false,
options: models.records.map((model: any) => ({
label: model.name,
value: model.id,
})),
};
} catch (error) {
return {
disabled: true,
options: [],
placeholder: 'Error loading teams',
};
}
},
});
export const documentIdDropdown = Property.Dropdown({
auth: omniAuth,
displayName: 'Document',
description: 'Select the document',
required: true,
refreshers: ['auth'],
options: async ({ auth }) => {
if (!auth) {
return {
disabled: true,
options: [],
placeholder: 'Please connect your account first',
};
}
try {
const documents = await makeRequest(
auth.secret_text,
HttpMethod.GET,
`/documents`,
{}
);
return {
disabled: false,
options: documents.records.map((document: any) => ({
label: document.name,
value: document.identifier,
})),
};
} catch (error) {
return {
disabled: true,
options: [],
placeholder: 'Error loading documents',
};
}
},
});
export const scheduleIdDropdown = Property.Dropdown({
auth: omniAuth,
displayName: 'Schedule',
description: 'Select the schedule',
required: true,
refreshers: ['auth'],
options: async ({ auth }) => {
if (!auth) {
return {
disabled: true,
options: [],
placeholder: 'Please connect your account first',
};
}
try {
const schedules = await makeRequest(
auth.secret_text,
HttpMethod.GET,
`/schedules`,
{}
);
return {
disabled: false,
options: schedules.records.map((schedule: any) => ({
label: schedule.name,
value: schedule.identifier,
})),
};
} catch (error) {
return {
disabled: true,
options: [],
placeholder: 'Error loading schedules',
};
}
},
});

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"]
}