From d16e292231a924c6ba2a7fa611ec5724ed25257e Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Wed, 8 Feb 2023 23:27:12 +0100 Subject: [PATCH] feat: Add dynamic fields structure to step arguments --- .../send-a-message-to-channel/index.ts | 33 +++++------- .../src/apps/slack/dynamic-fields/index.ts | 3 ++ .../slack/dynamic-fields/send-as-bot/index.ts | 44 +++++++++++++++ packages/backend/src/apps/slack/index.ts | 2 + .../src/graphql/queries/get-dynamic-fields.ts | 53 +++++++++++++++++++ .../backend/src/graphql/query-resolvers.ts | 2 + packages/backend/src/graphql/schema.graphql | 5 ++ packages/backend/src/models/step.ts | 16 ++++++ packages/types/index.d.ts | 5 ++ 9 files changed, 144 insertions(+), 19 deletions(-) create mode 100644 packages/backend/src/apps/slack/dynamic-fields/index.ts create mode 100644 packages/backend/src/apps/slack/dynamic-fields/send-as-bot/index.ts create mode 100644 packages/backend/src/graphql/queries/get-dynamic-fields.ts diff --git a/packages/backend/src/apps/slack/actions/send-a-message-to-channel/index.ts b/packages/backend/src/apps/slack/actions/send-a-message-to-channel/index.ts index 7403527c..39d92f70 100644 --- a/packages/backend/src/apps/slack/actions/send-a-message-to-channel/index.ts +++ b/packages/backend/src/apps/slack/actions/send-a-message-to-channel/index.ts @@ -51,25 +51,20 @@ export default defineAction({ value: false, }, ], - }, - { - label: 'Bot name', - key: 'botName', - type: 'string' as const, - required: true, - value: 'Automatisch', - description: - 'Specify the bot name which appears as a bold username above the message inside Slack. Defaults to Automatisch.', - variables: true, - }, - { - label: 'Bot icon', - key: 'botIcon', - type: 'string' as const, - required: false, - description: - 'Either an image url or an emoji available to your team (surrounded by :). For example, https://example.com/icon_256.png or :robot_face:', - variables: true, + source: { + type: 'query', + name: 'getDynamicFields', + arguments: [ + { + name: 'key', + value: 'listFieldsAfterSendAsBot', + }, + { + name: 'parameters.sendAsBot', + value: '{parameters.sendAsBot}', + }, + ], + }, }, ], diff --git a/packages/backend/src/apps/slack/dynamic-fields/index.ts b/packages/backend/src/apps/slack/dynamic-fields/index.ts new file mode 100644 index 00000000..220e3ef3 --- /dev/null +++ b/packages/backend/src/apps/slack/dynamic-fields/index.ts @@ -0,0 +1,3 @@ +import listFieldsAfterSendAsBot from './send-as-bot'; + +export default [listFieldsAfterSendAsBot]; diff --git a/packages/backend/src/apps/slack/dynamic-fields/send-as-bot/index.ts b/packages/backend/src/apps/slack/dynamic-fields/send-as-bot/index.ts new file mode 100644 index 00000000..82d04794 --- /dev/null +++ b/packages/backend/src/apps/slack/dynamic-fields/send-as-bot/index.ts @@ -0,0 +1,44 @@ +import { IGlobalVariable, IField, IJSONObject } from '@automatisch/types'; + +export default { + name: 'List fields after send as bot', + key: 'listFieldsAfterSendAsBot', + + async run($: IGlobalVariable) { + const sendAsBot = $.step.parameters.sendAsBot as boolean; + + const remainingArguments: { + data: IJSONObject[]; + error: IJSONObject | null; + } = { + data: [], + error: null, + }; + + if (sendAsBot) { + remainingArguments.data = [ + { + label: 'Bot name', + key: 'botName', + type: 'string' as const, + required: true, + value: 'Automatisch', + description: + 'Specify the bot name which appears as a bold username above the message inside Slack. Defaults to Automatisch.', + variables: true, + }, + { + label: 'Bot icon', + key: 'botIcon', + type: 'string' as const, + required: false, + description: + 'Either an image url or an emoji available to your team (surrounded by :). For example, https://example.com/icon_256.png or :robot_face:', + variables: true, + }, + ]; + } + + return remainingArguments; + }, +}; diff --git a/packages/backend/src/apps/slack/index.ts b/packages/backend/src/apps/slack/index.ts index 9869e5ea..1f2570b7 100644 --- a/packages/backend/src/apps/slack/index.ts +++ b/packages/backend/src/apps/slack/index.ts @@ -3,6 +3,7 @@ import addAuthHeader from './common/add-auth-header'; import actions from './actions'; import auth from './auth'; import dynamicData from './dynamic-data'; +import dynamicFields from './dynamic-fields'; export default defineApp({ name: 'Slack', @@ -17,4 +18,5 @@ export default defineApp({ auth, actions, dynamicData, + dynamicFields, }); diff --git a/packages/backend/src/graphql/queries/get-dynamic-fields.ts b/packages/backend/src/graphql/queries/get-dynamic-fields.ts new file mode 100644 index 00000000..755ef842 --- /dev/null +++ b/packages/backend/src/graphql/queries/get-dynamic-fields.ts @@ -0,0 +1,53 @@ +import { IDynamicFields, IJSONObject } from '@automatisch/types'; +import Context from '../../types/express/context'; +import App from '../../models/app'; +import globalVariable from '../../helpers/global-variable'; + +type Params = { + stepId: string; + key: string; + parameters: IJSONObject; +}; + +const getDynamicFields = async ( + _parent: unknown, + params: Params, + context: Context +) => { + const step = await context.currentUser + .$relatedQuery('steps') + .withGraphFetched({ + connection: true, + flow: true, + }) + .findById(params.stepId); + + if (!step) return null; + + const connection = step.connection; + + if (!connection || !step.appKey) return null; + + const app = await App.findOneByKey(step.appKey); + const $ = await globalVariable({ connection, app, flow: step.flow, step }); + + const command = app.dynamicFields.find( + (data: IDynamicFields) => data.key === params.key + ); + + for (const parameterKey in params.parameters) { + const parameterValue = params.parameters[parameterKey]; + $.step.parameters[parameterKey] = parameterValue; + } + + const existingArguments = await step.getSetupFields(); + const remainingArguments = await command.run($); + + if (remainingArguments.error) { + throw new Error(JSON.stringify(remainingArguments.error)); + } + + return [...existingArguments, ...remainingArguments.data]; +}; + +export default getDynamicFields; diff --git a/packages/backend/src/graphql/query-resolvers.ts b/packages/backend/src/graphql/query-resolvers.ts index 35b6280a..48617d99 100644 --- a/packages/backend/src/graphql/query-resolvers.ts +++ b/packages/backend/src/graphql/query-resolvers.ts @@ -9,6 +9,7 @@ import getExecution from './queries/get-execution'; import getExecutions from './queries/get-executions'; import getExecutionSteps from './queries/get-execution-steps'; import getDynamicData from './queries/get-dynamic-data'; +import getDynamicFields from './queries/get-dynamic-fields'; import getCurrentUser from './queries/get-current-user'; import getLicense from './queries/get-license.ee'; import healthcheck from './queries/healthcheck'; @@ -25,6 +26,7 @@ const queryResolvers = { getExecutions, getExecutionSteps, getDynamicData, + getDynamicFields, getCurrentUser, getLicense, healthcheck, diff --git a/packages/backend/src/graphql/schema.graphql b/packages/backend/src/graphql/schema.graphql index e60add0a..be0d2936 100644 --- a/packages/backend/src/graphql/schema.graphql +++ b/packages/backend/src/graphql/schema.graphql @@ -28,6 +28,11 @@ type Query { key: String! parameters: JSONObject ): JSONObject + getDynamicFields( + stepId: String! + key: String! + parameters: JSONObject + ): [Field] getCurrentUser: User getLicense: GetLicense healthcheck: AppHealth diff --git a/packages/backend/src/models/step.ts b/packages/backend/src/models/step.ts index 294671af..2815df7b 100644 --- a/packages/backend/src/models/step.ts +++ b/packages/backend/src/models/step.ts @@ -149,6 +149,22 @@ class Step extends Base { return command; } + + async getSetupFields() { + let setupSupsteps; + + if (this.isTrigger) { + setupSupsteps = (await this.getTriggerCommand()).substeps; + } else { + setupSupsteps = (await this.getActionCommand()).substeps; + } + + const existingArguments = setupSupsteps.find( + (substep) => substep.key === 'chooseTrigger' + ).arguments; + + return existingArguments; + } } export default Step; diff --git a/packages/types/index.d.ts b/packages/types/index.d.ts index e559ca78..842b5798 100644 --- a/packages/types/index.d.ts +++ b/packages/types/index.d.ts @@ -167,6 +167,7 @@ export interface IApp { flowCount?: number; beforeRequest?: TBeforeRequest[]; dynamicData?: IDynamicData; + dynamicFields?: IDynamicFields; triggers?: ITrigger[]; actions?: IAction[]; connections?: IConnection[]; @@ -180,6 +181,10 @@ export interface IDynamicData { [index: string]: any; } +export interface IDynamicFields { + [index: string]: any; +} + export interface IAuth { generateAuthUrl?($: IGlobalVariable): Promise; verifyCredentials?($: IGlobalVariable): Promise;