diff --git a/packages/backend/src/apps/delay/actions/delay-for/index.ts b/packages/backend/src/apps/delay/actions/delay-for/index.ts new file mode 100644 index 00000000..2b7af613 --- /dev/null +++ b/packages/backend/src/apps/delay/actions/delay-for/index.ts @@ -0,0 +1,56 @@ +import defineAction from '../../../../helpers/define-action'; + +export default defineAction({ + name: 'Delay For', + key: 'delayFor', + description: + 'Delays the execution of the next action by a specified amount of time.', + arguments: [ + { + label: 'Delay for unit', + key: 'delayForUnit', + type: 'dropdown' as const, + required: true, + value: null, + description: 'Delay for unit, e.g. minutes, hours, days, weeks.', + variables: false, + options: [ + { + label: 'Minutes', + value: 'minutes', + }, + { + label: 'Hours', + value: 'hours', + }, + { + label: 'Days', + value: 'days', + }, + { + label: 'Weeks', + value: 'weeks', + }, + ], + }, + { + label: 'Delay for value', + key: 'delayForValue', + type: 'string' as const, + required: true, + description: 'Delay for value, use a number, e.g. 1, 2, 3.', + variables: true, + }, + ], + + async run($) { + const { delayForUnit, delayForValue } = $.step.parameters; + + const dataItem = { + delayForUnit, + delayForValue, + }; + + $.setActionItem({ raw: dataItem }); + }, +}); diff --git a/packages/backend/src/apps/delay/actions/index.ts b/packages/backend/src/apps/delay/actions/index.ts new file mode 100644 index 00000000..f1160de6 --- /dev/null +++ b/packages/backend/src/apps/delay/actions/index.ts @@ -0,0 +1,3 @@ +import delayFor from './delay-for'; + +export default [delayFor]; diff --git a/packages/backend/src/apps/delay/assets/favicon.svg b/packages/backend/src/apps/delay/assets/favicon.svg new file mode 100644 index 00000000..af5da4d3 --- /dev/null +++ b/packages/backend/src/apps/delay/assets/favicon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/packages/backend/src/apps/delay/index.d.ts b/packages/backend/src/apps/delay/index.d.ts new file mode 100644 index 00000000..e69de29b diff --git a/packages/backend/src/apps/delay/index.ts b/packages/backend/src/apps/delay/index.ts new file mode 100644 index 00000000..7f25c1b7 --- /dev/null +++ b/packages/backend/src/apps/delay/index.ts @@ -0,0 +1,14 @@ +import defineApp from '../../helpers/define-app'; +import actions from './actions'; + +export default defineApp({ + name: 'Delay', + key: 'delay', + iconUrl: '{BASE_URL}/apps/delay/assets/favicon.svg', + authDocUrl: 'https://automatisch.io/docs/apps/delay/connection', + supportsConnections: false, + baseUrl: '', + apiBaseUrl: '', + primaryColor: '001F52', + actions, +}); diff --git a/packages/backend/src/helpers/delay-as-milliseconds.ts b/packages/backend/src/helpers/delay-as-milliseconds.ts new file mode 100644 index 00000000..582d1b13 --- /dev/null +++ b/packages/backend/src/helpers/delay-as-milliseconds.ts @@ -0,0 +1,21 @@ +export type TDelayForUnit = 'minutes' | 'hours' | 'days' | 'weeks'; + +const delayAsMilliseconds = ( + delayForUnit: TDelayForUnit, + delayForValue: number +) => { + switch (delayForUnit) { + case 'minutes': + return delayForValue * 60 * 1000; + case 'hours': + return delayForValue * 60 * 60 * 1000; + case 'days': + return delayForValue * 24 * 60 * 60 * 1000; + case 'weeks': + return delayForValue * 7 * 24 * 60 * 60 * 1000; + default: + return 0; + } +}; + +export default delayAsMilliseconds; diff --git a/packages/backend/src/workers/action.ts b/packages/backend/src/workers/action.ts index 80dd2849..26869936 100644 --- a/packages/backend/src/workers/action.ts +++ b/packages/backend/src/workers/action.ts @@ -4,7 +4,13 @@ import logger from '../helpers/logger'; import Step from '../models/step'; import actionQueue from '../queues/action'; import { processAction } from '../services/action'; -import { REMOVE_AFTER_30_DAYS_OR_150_JOBS, REMOVE_AFTER_7_DAYS_OR_50_JOBS } from '../helpers/remove-job-configuration'; +import { + REMOVE_AFTER_30_DAYS_OR_150_JOBS, + REMOVE_AFTER_7_DAYS_OR_50_JOBS, +} from '../helpers/remove-job-configuration'; +import delayAsMilliseconds, { + TDelayForUnit, +} from '../helpers/delay-as-milliseconds'; type JobData = { flowId: string; @@ -12,6 +18,8 @@ type JobData = { stepId: string; }; +const DEFAULT_DELAY_DURATION = 0; + export const worker = new Worker( 'action', async (job) => { @@ -35,6 +43,18 @@ export const worker = new Worker( const jobOptions = { removeOnComplete: REMOVE_AFTER_7_DAYS_OR_50_JOBS, removeOnFail: REMOVE_AFTER_30_DAYS_OR_150_JOBS, + delay: DEFAULT_DELAY_DURATION, + }; + + const stepApp = await step.getApp(); + + if (stepApp.key === 'delay') { + const { delayForUnit, delayForValue } = step.parameters; + + jobOptions.delay = delayAsMilliseconds( + delayForUnit as TDelayForUnit, + Number(delayForValue) + ); } await actionQueue.add(jobName, jobPayload, jobOptions);