From 0970db32959e631892a564111b89c55b29f9c971 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Wed, 14 Dec 2022 20:00:08 +0100 Subject: [PATCH 1/5] feat: add remoteWebhookId in Flow --- .../20221214184855_add_remote_webhook_id_in_flow.ts | 13 +++++++++++++ packages/backend/src/models/flow.ts | 2 ++ packages/types/index.d.ts | 3 +++ 3 files changed, 18 insertions(+) create mode 100644 packages/backend/src/db/migrations/20221214184855_add_remote_webhook_id_in_flow.ts diff --git a/packages/backend/src/db/migrations/20221214184855_add_remote_webhook_id_in_flow.ts b/packages/backend/src/db/migrations/20221214184855_add_remote_webhook_id_in_flow.ts new file mode 100644 index 00000000..67a086a9 --- /dev/null +++ b/packages/backend/src/db/migrations/20221214184855_add_remote_webhook_id_in_flow.ts @@ -0,0 +1,13 @@ +import { Knex } from 'knex'; + +export async function up(knex: Knex): Promise { + return knex.schema.table('flows', (table) => { + table.string('remote_webhook_id'); + }); +} + +export async function down(knex: Knex): Promise { + return knex.schema.table('flows', (table) => { + table.dropColumn('remote_webhook_id'); + }); +} diff --git a/packages/backend/src/models/flow.ts b/packages/backend/src/models/flow.ts index bb4015e0..5577dd35 100644 --- a/packages/backend/src/models/flow.ts +++ b/packages/backend/src/models/flow.ts @@ -13,6 +13,7 @@ class Flow extends Base { active: boolean; steps: Step[]; published_at: string; + remoteWebhookId: string; executions?: Execution[]; static tableName = 'flows'; @@ -25,6 +26,7 @@ class Flow extends Base { id: { type: 'string', format: 'uuid' }, name: { type: 'string', minLength: 1 }, userId: { type: 'string', format: 'uuid' }, + remoteWebhookId: { type: 'string' }, active: { type: 'boolean' }, }, }; diff --git a/packages/types/index.d.ts b/packages/types/index.d.ts index 1386f962..7f56d0e7 100644 --- a/packages/types/index.d.ts +++ b/packages/types/index.d.ts @@ -76,6 +76,7 @@ export interface IFlow { steps: IStep[]; createdAt: string; updatedAt: string; + remoteWebhookId: string; lastInternalId: () => Promise; } @@ -279,6 +280,8 @@ export type IGlobalVariable = { id: string; lastInternalId: string; isAlreadyProcessed?: (internalId: string) => boolean; + remoteWebhookId?: string; + setRemoteWebhookId?: (remoteWebhookId: string) => Promise; }; step?: { id: string; From f30ac466723a7411c90cf64a03ada48bc5816ae7 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Wed, 14 Dec 2022 20:50:33 +0100 Subject: [PATCH 2/5] feat($): add flow.setRemoteWebhookId --- packages/backend/src/helpers/global-variable.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/backend/src/helpers/global-variable.ts b/packages/backend/src/helpers/global-variable.ts index 6834b081..ed4dd968 100644 --- a/packages/backend/src/helpers/global-variable.ts +++ b/packages/backend/src/helpers/global-variable.ts @@ -37,6 +37,7 @@ const globalVariable = async ( testRun = false, } = options; + const isTrigger = step?.isTrigger; const lastInternalId = testRun ? undefined : await flow?.lastInternalId(); const nextStep = await step?.getNextStep(); @@ -123,6 +124,18 @@ const globalVariable = async ( $.webhookUrl = webhookUrl; } + if (isTrigger && (await step.getTriggerCommand()).type === 'webhook') { + $.flow.setRemoteWebhookId = async (remoteWebhookId) => { + await flow.$query().patchAndFetch({ + remoteWebhookId, + }); + + $.flow.remoteWebhookId = remoteWebhookId; + }; + + $.flow.remoteWebhookId = flow.remoteWebhookId; + } + const lastInternalIds = testRun || (flow && step.isAction) ? [] : await flow?.lastInternalIds(2000); From 7175d92eaf9a45fb7b7eaf0108147780129afacd Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Thu, 15 Dec 2022 00:46:42 +0100 Subject: [PATCH 3/5] feat(flowers-software): add app with authentication --- .../apps/flowers-software/assets/favicon.svg | 12 ++++++ .../src/apps/flowers-software/auth/index.ts | 43 +++++++++++++++++++ .../auth/is-still-verified.ts | 10 +++++ .../auth/verify-credentials.ts | 20 +++++++++ .../common/add-auth-header.ts | 18 ++++++++ .../flowers-software/common/get-webhooks.ts | 5 +++ .../src/apps/flowers-software/index.d.ts | 0 .../src/apps/flowers-software/index.ts | 16 +++++++ 8 files changed, 124 insertions(+) create mode 100644 packages/backend/src/apps/flowers-software/assets/favicon.svg create mode 100644 packages/backend/src/apps/flowers-software/auth/index.ts create mode 100644 packages/backend/src/apps/flowers-software/auth/is-still-verified.ts create mode 100644 packages/backend/src/apps/flowers-software/auth/verify-credentials.ts create mode 100644 packages/backend/src/apps/flowers-software/common/add-auth-header.ts create mode 100644 packages/backend/src/apps/flowers-software/common/get-webhooks.ts create mode 100644 packages/backend/src/apps/flowers-software/index.d.ts create mode 100644 packages/backend/src/apps/flowers-software/index.ts diff --git a/packages/backend/src/apps/flowers-software/assets/favicon.svg b/packages/backend/src/apps/flowers-software/assets/favicon.svg new file mode 100644 index 00000000..55b8ed60 --- /dev/null +++ b/packages/backend/src/apps/flowers-software/assets/favicon.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/backend/src/apps/flowers-software/auth/index.ts b/packages/backend/src/apps/flowers-software/auth/index.ts new file mode 100644 index 00000000..6dd40712 --- /dev/null +++ b/packages/backend/src/apps/flowers-software/auth/index.ts @@ -0,0 +1,43 @@ +import verifyCredentials from './verify-credentials'; +import isStillVerified from './is-still-verified'; + +export default { + fields: [ + { + key: 'username', + label: 'Username', + type: 'string' as const, + required: true, + readOnly: false, + value: null, + placeholder: null, + description: null, + clickToCopy: false, + }, + { + key: 'password', + label: 'Password', + type: 'string' as const, + required: true, + readOnly: false, + value: null, + placeholder: null, + description: null, + clickToCopy: false, + }, + { + key: 'apiKey', + label: 'API Key', + type: 'string' as const, + required: true, + readOnly: false, + value: null, + placeholder: null, + description: null, + clickToCopy: false, + }, + ], + + verifyCredentials, + isStillVerified, +}; diff --git a/packages/backend/src/apps/flowers-software/auth/is-still-verified.ts b/packages/backend/src/apps/flowers-software/auth/is-still-verified.ts new file mode 100644 index 00000000..5a2fe2ae --- /dev/null +++ b/packages/backend/src/apps/flowers-software/auth/is-still-verified.ts @@ -0,0 +1,10 @@ +import { IGlobalVariable } from '@automatisch/types'; +import verifyCredentials from './verify-credentials'; + +const isStillVerified = async ($: IGlobalVariable) => { + await verifyCredentials($); + + return true; +}; + +export default isStillVerified; diff --git a/packages/backend/src/apps/flowers-software/auth/verify-credentials.ts b/packages/backend/src/apps/flowers-software/auth/verify-credentials.ts new file mode 100644 index 00000000..4e7a4f69 --- /dev/null +++ b/packages/backend/src/apps/flowers-software/auth/verify-credentials.ts @@ -0,0 +1,20 @@ +import { IGlobalVariable } from '@automatisch/types'; +import getWebhooks from '../common/get-webhooks'; + +const verifyCredentials = async ($: IGlobalVariable) => { + const response = await getWebhooks($); + const successful = Array.isArray(response.data); + + if (!successful) { + throw new Error('Failed while authorizing!'); + } + + await $.auth.set({ + screenName: $.auth.data.username, + username: $.auth.data.username, + password: $.auth.data.password, + apiKey: $.auth.data.apiKey, + }); +}; + +export default verifyCredentials; diff --git a/packages/backend/src/apps/flowers-software/common/add-auth-header.ts b/packages/backend/src/apps/flowers-software/common/add-auth-header.ts new file mode 100644 index 00000000..02f524fd --- /dev/null +++ b/packages/backend/src/apps/flowers-software/common/add-auth-header.ts @@ -0,0 +1,18 @@ +import { TBeforeRequest } from '@automatisch/types'; + +const addAuthHeader: TBeforeRequest = ($, requestConfig) => { + const { data } = $.auth; + + if (data?.username && data.password && data.apiKey) { + requestConfig.headers['x-api-key'] = data.apiKey as string; + + requestConfig.auth = { + username: data.username as string, + password: data.password as string, + }; + } + + return requestConfig; +}; + +export default addAuthHeader; diff --git a/packages/backend/src/apps/flowers-software/common/get-webhooks.ts b/packages/backend/src/apps/flowers-software/common/get-webhooks.ts new file mode 100644 index 00000000..bb529c26 --- /dev/null +++ b/packages/backend/src/apps/flowers-software/common/get-webhooks.ts @@ -0,0 +1,5 @@ +import type { IGlobalVariable } from "@automatisch/types"; + +export default async function getWebhooks($: IGlobalVariable) { + return await $.http.get('/v2/public/api/webhooks'); +} diff --git a/packages/backend/src/apps/flowers-software/index.d.ts b/packages/backend/src/apps/flowers-software/index.d.ts new file mode 100644 index 00000000..e69de29b diff --git a/packages/backend/src/apps/flowers-software/index.ts b/packages/backend/src/apps/flowers-software/index.ts new file mode 100644 index 00000000..52065785 --- /dev/null +++ b/packages/backend/src/apps/flowers-software/index.ts @@ -0,0 +1,16 @@ +import defineApp from '../../helpers/define-app'; +import addAuthHeader from './common/add-auth-header'; +import auth from './auth'; + +export default defineApp({ + name: 'Flowers Software', + key: 'flowers-software', + iconUrl: '{BASE_URL}/apps/flowers-software/assets/favicon.svg', + authDocUrl: 'https://automatisch.io/docs/apps/flowers-software/connection', + supportsConnections: true, + baseUrl: 'https://flowers-software.com', + apiBaseUrl: 'https://webapp.flowers-software.com/api', + primaryColor: '02AFC7', + beforeRequest: [addAuthHeader], + auth, +}); From bf1076b7d2cb64aebf9a4d447c372ae297662a3e Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Thu, 15 Dec 2022 00:48:21 +0100 Subject: [PATCH 4/5] fix(AddAppConnection): don't render empty error details --- packages/web/src/components/AddAppConnection/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/src/components/AddAppConnection/index.tsx b/packages/web/src/components/AddAppConnection/index.tsx index 38ba620b..e1581b3b 100644 --- a/packages/web/src/components/AddAppConnection/index.tsx +++ b/packages/web/src/components/AddAppConnection/index.tsx @@ -116,7 +116,7 @@ export default function AddAppConnection( sx={{ mt: 1, fontWeight: 500, wordBreak: 'break-all' }} > {error.message} -
{JSON.stringify(error.details, null, 2)}
+ {error.details &&
{JSON.stringify(error.details, null, 2)}
} )} From 6d74f7c64d16f7769ccdd2d2dc385168c4a5a3e9 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Fri, 16 Dec 2022 16:27:49 +0100 Subject: [PATCH 5/5] feat(flowers-software): add new activity trigger --- .../common/webhook-filters.ts | 488 ++++++++++++++++++ .../src/apps/flowers-software/index.ts | 2 + .../apps/flowers-software/triggers/index.ts | 3 + .../triggers/new-activity/index.ts | 54 ++ 4 files changed, 547 insertions(+) create mode 100644 packages/backend/src/apps/flowers-software/common/webhook-filters.ts create mode 100644 packages/backend/src/apps/flowers-software/triggers/index.ts create mode 100644 packages/backend/src/apps/flowers-software/triggers/new-activity/index.ts diff --git a/packages/backend/src/apps/flowers-software/common/webhook-filters.ts b/packages/backend/src/apps/flowers-software/common/webhook-filters.ts new file mode 100644 index 00000000..d8a22d13 --- /dev/null +++ b/packages/backend/src/apps/flowers-software/common/webhook-filters.ts @@ -0,0 +1,488 @@ +const webhookFilters = [ + { + label: "Contact Company Created", + value: "CONTACT_COMPANY_CREATED" + }, + { + label: "Contact Company Deleted", + value: "CONTACT_COMPANY_DELETED" + }, + { + label: "Contact Company Updated", + value: "CONTACT_COMPANY_UPDATED" + }, + { + label: "Contact Created", + value: "CONTACT_CREATED" + }, + { + label: "Contact Deleted", + value: "CONTACT_DELETED" + }, + { + label: "Contact Updated", + value: "CONTACT_UPDATED" + }, + { + label: "Customer Created", + value: "CUSTOMER_CREATED" + }, + { + label: "Customer Updated", + value: "CUSTOMER_UPDATED" + }, + { + label: "Document Deleted", + value: "DOCUMENT_DELETED" + }, + { + label: "Document Downloaded", + value: "DOCUMENT_DOWNLOADED" + }, + { + label: "Document Saved", + value: "DOCUMENT_SAVED" + }, + { + label: "Document Updated", + value: "DOCUMENT_UPDATED" + }, + { + label: "Flow Archived", + value: "FLOW_ARCHIVED" + }, + { + label: "Flow Created", + value: "FLOW_CREATED" + }, + { + label: "Flow Object Automation Action Created", + value: "FLOW_OBJECT_AUTOMATION_ACTION_CREATED" + }, + { + label: "Flow Object Automation Action Deleted", + value: "FLOW_OBJECT_AUTOMATION_ACTION_DELETED" + }, + { + label: "Flow Object Automation Created", + value: "FLOW_OBJECT_AUTOMATION_CREATED" + }, + { + label: "Flow Object Automation Deleted", + value: "FLOW_OBJECT_AUTOMATION_DELETED" + }, + { + label: "Flow Object Automation Updated", + value: "FLOW_OBJECT_AUTOMATION_UPDATED" + }, + { + label: "Flow Object Automation Webdav Created", + value: "FLOW_OBJECT_AUTOMATION_WEBDAV_CREATED" + }, + { + label: "Flow Object Automation Webdav Deleted", + value: "FLOW_OBJECT_AUTOMATION_WEBDAV_DELETED" + }, + { + label: "Flow Object Automation Webdav Updated", + value: "FLOW_OBJECT_AUTOMATION_WEBDAV_UPDATED" + }, + { + label: "Flow Object Created", + value: "FLOW_OBJECT_CREATED" + }, + { + label: "Flow Object Deleted", + value: "FLOW_OBJECT_DELETED" + }, + { + label: "Flow Object Document Added", + value: "FLOW_OBJECT_DOCUMENT_ADDED" + }, + { + label: "Flow Object Document Removed", + value: "FLOW_OBJECT_DOCUMENT_REMOVED" + }, + { + label: "Flow Object Resource Created", + value: "FLOW_OBJECT_RESOURCE_CREATED" + }, + { + label: "Flow Object Resource Deleted", + value: "FLOW_OBJECT_RESOURCE_DELETED" + }, + { + label: "Flow Object Resource Updated", + value: "FLOW_OBJECT_RESOURCE_UPDATED" + }, + { + label: "Flow Object Task Condition Created", + value: "FLOW_OBJECT_TASK_CONDITION_CREATED" + }, + { + label: "Flow Object Task Condition Deleted", + value: "FLOW_OBJECT_TASK_CONDITION_DELETED" + }, + { + label: "Flow Object Task Condition Updated", + value: "FLOW_OBJECT_TASK_CONDITION_UPDATED" + }, + { + label: "Flow Object Task Created", + value: "FLOW_OBJECT_TASK_CREATED" + }, + { + label: "Flow Object Task Deleted", + value: "FLOW_OBJECT_TASK_DELETED" + }, + { + label: "Flow Object Task Updated", + value: "FLOW_OBJECT_TASK_UPDATED" + }, + { + label: "Flow Object Updated", + value: "FLOW_OBJECT_UPDATED" + }, + { + label: "Flow Objects Connection Created", + value: "FLOW_OBJECTS_CONNECTION_CREATED" + }, + { + label: "Flow Objects Connection Deleted", + value: "FLOW_OBJECTS_CONNECTION_DELETED" + }, + { + label: "Flow Objects Connection Updated", + value: "FLOW_OBJECTS_CONNECTION_UPDATED" + }, + { + label: "Flow Objects External Connection Created", + value: "FLOW_OBJECTS_EXTERNAL_CONNECTION_CREATED" + }, + { + label: "Flow Objects External Connection Deleted", + value: "FLOW_OBJECTS_EXTERNAL_CONNECTION_DELETED" + }, + { + label: "Flow Objects External Connection Updated", + value: "FLOW_OBJECTS_EXTERNAL_CONNECTION_UPDATED" + }, + { + label: "Flow Objects External Connections Group Created", + value: "FLOW_OBJECTS_EXTERNAL_CONNECTIONS_GROUP_CREATED" + }, + { + label: "Flow Objects External Connections Group Deleted", + value: "FLOW_OBJECTS_EXTERNAL_CONNECTIONS_GROUP_DELETED" + }, + { + label: "Flow Objects External Connections Group Updated", + value: "FLOW_OBJECTS_EXTERNAL_CONNECTIONS_GROUP_UPDATED" + }, + { + label: "Flow Unarchived", + value: "FLOW_UNARCHIVED" + }, + { + label: "Flow Updated", + value: "FLOW_UPDATED" + }, + { + label: "Note Created", + value: "NOTE_CREATED" + }, + { + label: "Note Deleted", + value: "NOTE_DELETED" + }, + { + label: "Note Updated", + value: "NOTE_UPDATED" + }, + { + label: "Team Created", + value: "TEAM_CREATED" + }, + { + label: "Team Deleted", + value: "TEAM_DELETED" + }, + { + label: "Team Updated", + value: "TEAM_UPDATED" + }, + { + label: "User Added To Team", + value: "USER_ADDED_TO_TEAM" + }, + { + label: "User Added To Teamleads", + value: "USER_ADDED_TO_TEAMLEADS" + }, + { + label: "User Archived", + value: "USER_ARCHIVED" + }, + { + label: "User Changed Password", + value: "USER_CHANGED_PASSWORD" + }, + { + label: "User Created", + value: "USER_CREATED" + }, + { + label: "User Forgot Password", + value: "USER_FORGOT_PASSWORD" + }, + { + label: "User Invited", + value: "USER_INVITED" + }, + { + label: "User Logged In", + value: "USER_LOGGED_IN" + }, + { + label: "User Notification Settings Changed", + value: "USER_NOTIFICATION_SETTINGS_CHANGED" + }, + { + label: "User Profile Updated", + value: "USER_PROFILE_UPDATED" + }, + { + label: "User Removed From Team", + value: "USER_REMOVED_FROM_TEAM" + }, + { + label: "User Removed From Teamleads", + value: "USER_REMOVED_FROM_TEAMLEADS" + }, + { + label: "User Unarchived", + value: "USER_UNARCHIVED" + }, + { + label: "Workflow Archived", + value: "WORKFLOW_ARCHIVED" + }, + { + label: "Workflow Completed", + value: "WORKFLOW_COMPLETED" + }, + { + label: "Workflow Created", + value: "WORKFLOW_CREATED" + }, + { + label: "Workflow Creation Failed", + value: "WORKFLOW_CREATION_FAILED" + }, + { + label: "Workflow Object Automation Api Get Completed", + value: "WORKFLOW_OBJECT_AUTOMATION_API_GET_COMPLETED" + }, + { + label: "Workflow Object Automation Api Get Failed", + value: "WORKFLOW_OBJECT_AUTOMATION_API_GET_FAILED" + }, + { + label: "Workflow Object Automation Api Post Completed", + value: "WORKFLOW_OBJECT_AUTOMATION_API_POST_COMPLETED" + }, + { + label: "Workflow Object Automation Api Post Failed", + value: "WORKFLOW_OBJECT_AUTOMATION_API_POST_FAILED" + }, + { + label: "Workflow Object Automation Datev Completed", + value: "WORKFLOW_OBJECT_AUTOMATION_DATEV_COMPLETED" + }, + { + label: "Workflow Object Automation Datev Failed", + value: "WORKFLOW_OBJECT_AUTOMATION_DATEV_FAILED" + }, + { + label: "Workflow Object Automation Email Completed", + value: "WORKFLOW_OBJECT_AUTOMATION_EMAIL_COMPLETED" + }, + { + label: "Workflow Object Automation Email Failed", + value: "WORKFLOW_OBJECT_AUTOMATION_EMAIL_FAILED" + }, + { + label: "Workflow Object Automation Lexoffice Completed", + value: "WORKFLOW_OBJECT_AUTOMATION_LEXOFFICE_COMPLETED" + }, + { + label: "Workflow Object Automation Lexoffice Failed", + value: "WORKFLOW_OBJECT_AUTOMATION_LEXOFFICE_FAILED" + }, + { + label: "Workflow Object Automation Rejected", + value: "WORKFLOW_OBJECT_AUTOMATION_REJECTED" + }, + { + label: "Workflow Object Automation Retried", + value: "WORKFLOW_OBJECT_AUTOMATION_RETRIED" + }, + { + label: "Workflow Object Automation Sevdesk Completed", + value: "WORKFLOW_OBJECT_AUTOMATION_SEVDESK_COMPLETED" + }, + { + label: "Workflow Object Automation Sevdesk Failed", + value: "WORKFLOW_OBJECT_AUTOMATION_SEVDESK_FAILED" + }, + { + label: "Workflow Object Automation Stamp Completed", + value: "WORKFLOW_OBJECT_AUTOMATION_STAMP_COMPLETED" + }, + { + label: "Workflow Object Automation Stamp Failed", + value: "WORKFLOW_OBJECT_AUTOMATION_STAMP_FAILED" + }, + { + label: "Workflow Object Automation Task Completed", + value: "WORKFLOW_OBJECT_AUTOMATION_TASK_COMPLETED" + }, + { + label: "Workflow Object Automation Task Failed", + value: "WORKFLOW_OBJECT_AUTOMATION_TASK_FAILED" + }, + { + label: "Workflow Object Automation Template Completed", + value: "WORKFLOW_OBJECT_AUTOMATION_TEMPLATE_COMPLETED" + }, + { + label: "Workflow Object Automation Template Failed", + value: "WORKFLOW_OBJECT_AUTOMATION_TEMPLATE_FAILED" + }, + { + label: "Workflow Object Automation Webdav Document Uploaded", + value: "WORKFLOW_OBJECT_AUTOMATION_WEBDAV_DOCUMENT_UPLOADED" + }, + { + label: "Workflow Object Automation Zapier Completed", + value: "WORKFLOW_OBJECT_AUTOMATION_ZAPIER_COMPLETED" + }, + { + label: "Workflow Object Automation Zapier Failed", + value: "WORKFLOW_OBJECT_AUTOMATION_ZAPIER_FAILED" + }, + { + label: "Workflow Object Combination Task Group Created", + value: "WORKFLOW_OBJECT_COMBINATION_TASK_GROUP_CREATED" + }, + { + label: "Workflow Object Combination Task Group Deleted", + value: "WORKFLOW_OBJECT_COMBINATION_TASK_GROUP_DELETED" + }, + { + label: "Workflow Object Completed Automations Finished", + value: "WORKFLOW_OBJECT_COMPLETED_AUTOMATIONS_FINISHED" + }, + { + label: "Workflow Object Completed", + value: "WORKFLOW_OBJECT_COMPLETED" + }, + { + label: "Workflow Object Created", + value: "WORKFLOW_OBJECT_CREATED" + }, + { + label: "Workflow Object Document Added", + value: "WORKFLOW_OBJECT_DOCUMENT_ADDED" + }, + { + label: "Workflow Object Document Lock Added", + value: "WORKFLOW_OBJECT_DOCUMENT_LOCK_ADDED" + }, + { + label: "Workflow Object Document Lock Deleted", + value: "WORKFLOW_OBJECT_DOCUMENT_LOCK_DELETED" + }, + { + label: "Workflow Object Document Removed", + value: "WORKFLOW_OBJECT_DOCUMENT_REMOVED" + }, + { + label: "Workflow Object Email Added", + value: "WORKFLOW_OBJECT_EMAIL_ADDED" + }, + { + label: "Workflow Object Email Removed", + value: "WORKFLOW_OBJECT_EMAIL_REMOVED" + }, + { + label: "Workflow Object External User Created", + value: "WORKFLOW_OBJECT_EXTERNAL_USER_CREATED" + }, + { + label: "Workflow Object External User Deleted", + value: "WORKFLOW_OBJECT_EXTERNAL_USER_DELETED" + }, + { + label: "Workflow Object Note Added", + value: "WORKFLOW_OBJECT_NOTE_ADDED" + }, + { + label: "Workflow Object Note Removed", + value: "WORKFLOW_OBJECT_NOTE_REMOVED" + }, + { + label: "Workflow Object Resource Created", + value: "WORKFLOW_OBJECT_RESOURCE_CREATED" + }, + { + label: "Workflow Object Snapshot Created", + value: "WORKFLOW_OBJECT_SNAPSHOT_CREATED" + }, + { + label: "Workflow Object Task Condition Created", + value: "WORKFLOW_OBJECT_TASK_CONDITION_CREATED" + }, + { + label: "Workflow Object Task Created", + value: "WORKFLOW_OBJECT_TASK_CREATED" + }, + { + label: "Workflow Object Task Deleted", + value: "WORKFLOW_OBJECT_TASK_DELETED" + }, + { + label: "Workflow Object Task Snapshot Created", + value: "WORKFLOW_OBJECT_TASK_SNAPSHOT_CREATED" + }, + { + label: "Workflow Object Task Updated", + value: "WORKFLOW_OBJECT_TASK_UPDATED" + }, + { + label: "Workflow Object Updated", + value: "WORKFLOW_OBJECT_UPDATED" + }, + { + label: "Workflow Objects Connection Created", + value: "WORKFLOW_OBJECTS_CONNECTION_CREATED" + }, + { + label: "Workflow Objects External Connection Created", + value: "WORKFLOW_OBJECTS_EXTERNAL_CONNECTION_CREATED" + }, + { + label: "Workflow Objects External Connection Group Created", + value: "WORKFLOW_OBJECTS_EXTERNAL_CONNECTION_GROUP_CREATED" + }, + { + label: "Workflow Unarchived", + value: "WORKFLOW_UNARCHIVED" + }, + { + label: "Workflow Updated", + value: "WORKFLOW_UPDATED" + } +]; + +export default webhookFilters; \ No newline at end of file diff --git a/packages/backend/src/apps/flowers-software/index.ts b/packages/backend/src/apps/flowers-software/index.ts index 52065785..a0234867 100644 --- a/packages/backend/src/apps/flowers-software/index.ts +++ b/packages/backend/src/apps/flowers-software/index.ts @@ -1,6 +1,7 @@ import defineApp from '../../helpers/define-app'; import addAuthHeader from './common/add-auth-header'; import auth from './auth'; +import triggers from './triggers'; export default defineApp({ name: 'Flowers Software', @@ -13,4 +14,5 @@ export default defineApp({ primaryColor: '02AFC7', beforeRequest: [addAuthHeader], auth, + triggers, }); diff --git a/packages/backend/src/apps/flowers-software/triggers/index.ts b/packages/backend/src/apps/flowers-software/triggers/index.ts new file mode 100644 index 00000000..5599f298 --- /dev/null +++ b/packages/backend/src/apps/flowers-software/triggers/index.ts @@ -0,0 +1,3 @@ +import newActivity from './new-activity'; + +export default [newActivity]; diff --git a/packages/backend/src/apps/flowers-software/triggers/new-activity/index.ts b/packages/backend/src/apps/flowers-software/triggers/new-activity/index.ts new file mode 100644 index 00000000..3cd2997d --- /dev/null +++ b/packages/backend/src/apps/flowers-software/triggers/new-activity/index.ts @@ -0,0 +1,54 @@ +import isEmpty from 'lodash/isEmpty'; +import defineTrigger from '../../../../helpers/define-trigger'; +import webhookFilters from '../../common/webhook-filters'; + +export default defineTrigger({ + name: 'New activity', + key: 'newActivity', + type: 'webhook', + description: 'Triggers when a new activity occurs.', + arguments: [ + { + label: 'Activity type', + key: 'filters', + type: 'dropdown' as const, + required: true, + description: 'Pick an activity type to receive events for.', + variables: false, + options: webhookFilters, + }, + ], + + async testRun($) { + if (!isEmpty($.lastExecutionStep?.dataOut)) { + $.pushTriggerItem({ + raw: $.lastExecutionStep.dataOut, + meta: { + internalId: '', + } + }); + } + }, + + async registerHook($) { + const payload = { + name: $.flow.id, + type: 'POST', + url: $.webhookUrl, + filters: [$.step.parameters.filters] + }; + + const { data } = await $.http.post( + `/v2/public/api/webhooks`, + payload + ); + + await $.flow.setRemoteWebhookId(data.id); + }, + + async unregisterHook($) { + await $.http.delete( + `/v2/public/api/webhooks/${$.flow.remoteWebhookId}` + ); + }, +});