diff --git a/packages/backend/src/apps/salesforce/data/index.ts b/packages/backend/src/apps/salesforce/data/index.ts new file mode 100644 index 00000000..018c88f6 --- /dev/null +++ b/packages/backend/src/apps/salesforce/data/index.ts @@ -0,0 +1,7 @@ +import listObjects from './list-objects'; +import listFields from './list-fields'; + +export default [ + listObjects, + listFields, +]; diff --git a/packages/backend/src/apps/salesforce/data/list-fields/index.ts b/packages/backend/src/apps/salesforce/data/list-fields/index.ts new file mode 100644 index 00000000..00a61889 --- /dev/null +++ b/packages/backend/src/apps/salesforce/data/list-fields/index.ts @@ -0,0 +1,34 @@ +import { IGlobalVariable } from '@automatisch/types'; + +type TResponse = { + fields: TField[]; +}; + +type TField = { + name: string; + label: string; +}; + +export default { + name: 'List fields', + key: 'listFields', + + async run($: IGlobalVariable) { + const { object } = $.step.parameters; + + if (!object) return { data: [] }; + + const response = await $.http.get( + `/services/data/v56.0/sobjects/${object}/describe` + ); + + const fields = response.data.fields.map((field) => { + return { + value: field.name, + name: field.label, + }; + }); + + return { data: fields }; + }, +}; diff --git a/packages/backend/src/apps/salesforce/data/list-objects/index.ts b/packages/backend/src/apps/salesforce/data/list-objects/index.ts new file mode 100644 index 00000000..143dab0f --- /dev/null +++ b/packages/backend/src/apps/salesforce/data/list-objects/index.ts @@ -0,0 +1,28 @@ +import { IGlobalVariable } from '@automatisch/types'; + +type TResponse = { + sobjects: TObject[]; +} + +type TObject = { + name: string; + label: string; +} + +export default { + name: 'List objects', + key: 'listObjects', + + async run($: IGlobalVariable) { + const response = await $.http.get('/services/data/v56.0/sobjects'); + + const objects = response.data.sobjects.map((object) => { + return { + value: object.name, + name: object.label, + }; + }); + + return { data: objects }; + }, +}; diff --git a/packages/backend/src/apps/salesforce/index.ts b/packages/backend/src/apps/salesforce/index.ts index 2a89e164..079f743e 100644 --- a/packages/backend/src/apps/salesforce/index.ts +++ b/packages/backend/src/apps/salesforce/index.ts @@ -1,6 +1,8 @@ import defineApp from '../../helpers/define-app'; import addAuthHeader from './common/add-auth-header'; import auth from './auth'; +import triggers from './triggers'; +import data from './data'; export default defineApp({ name: 'Salesforce', @@ -13,4 +15,6 @@ export default defineApp({ primaryColor: '00A1E0', beforeRequest: [addAuthHeader], auth, + triggers, + data, }); diff --git a/packages/backend/src/apps/salesforce/triggers/index.ts b/packages/backend/src/apps/salesforce/triggers/index.ts new file mode 100644 index 00000000..eeb8681d --- /dev/null +++ b/packages/backend/src/apps/salesforce/triggers/index.ts @@ -0,0 +1,5 @@ +import updatedFieldInObjects from "./updated-field-in-objects"; + +export default [ + updatedFieldInObjects +]; diff --git a/packages/backend/src/apps/salesforce/triggers/updated-field-in-objects/index.ts b/packages/backend/src/apps/salesforce/triggers/updated-field-in-objects/index.ts new file mode 100644 index 00000000..96c0e0a4 --- /dev/null +++ b/packages/backend/src/apps/salesforce/triggers/updated-field-in-objects/index.ts @@ -0,0 +1,55 @@ +import defineTrigger from '../../../../helpers/define-trigger'; +import updatedFieldInObjects from './updated-field-in-objects'; + +export default defineTrigger({ + name: 'Updated field in objects', + key: 'updatedFieldInObjects', + pollInterval: 15, + description: 'Triggers when a field is updated in an object.', + arguments: [ + { + label: 'Object', + key: 'object', + type: 'dropdown' as const, + required: true, + variables: false, + source: { + type: 'query', + name: 'getData', + arguments: [ + { + name: 'key', + value: 'listObjects', + }, + ], + }, + }, + { + label: 'Field', + key: 'field', + type: 'dropdown' as const, + description: 'Track updates by this field', + required: true, + variables: false, + dependsOn: ['parameters.object'], + source: { + type: 'query', + name: 'getData', + arguments: [ + { + name: 'key', + value: 'listFields', + }, + { + name: 'parameters.object', + value: '{parameters.object}', + }, + ], + }, + }, + ], + + async run($) { + await updatedFieldInObjects($); + }, +}); diff --git a/packages/backend/src/apps/salesforce/triggers/updated-field-in-objects/updated-field-in-objects.ts b/packages/backend/src/apps/salesforce/triggers/updated-field-in-objects/updated-field-in-objects.ts new file mode 100644 index 00000000..d7f1d97c --- /dev/null +++ b/packages/backend/src/apps/salesforce/triggers/updated-field-in-objects/updated-field-in-objects.ts @@ -0,0 +1,45 @@ +import { IGlobalVariable } from '@automatisch/types'; + +function getQuery(object: string, limit: number, offset: number) { + return ` + SELECT + FIELDS(ALL) + FROM + ${object} + ORDER BY LastModifiedDate DESC + LIMIT ${limit} + OFFSET ${offset} + `; +} + +const updatedFieldInObjects = async ($: IGlobalVariable): Promise => { + const limit = 200; + const field = $.step.parameters.field as string; + const object = $.step.parameters.object as string; + + let response; + let offset = 0; + do { + const options = { + params: { + q: getQuery(object, limit, offset), + } + }; + + response = await $.http.get('/services/data/v56.0/query', options); + const records = response.data.records; + + for (const record of records) { + $.pushTriggerItem({ + raw: record, + meta: { + internalId: `${record.Id}-${record[field]}`, + } + }); + } + + offset = offset + limit; + } while (response.data.records?.length === limit); +}; + +export default updatedFieldInObjects; diff --git a/packages/web/src/components/TestSubstep/index.tsx b/packages/web/src/components/TestSubstep/index.tsx index d4d46920..4169d668 100644 --- a/packages/web/src/components/TestSubstep/index.tsx +++ b/packages/web/src/components/TestSubstep/index.tsx @@ -93,7 +93,7 @@ function TestSubstep(props: TestSubstepProps): React.ReactElement { /> - {error?.graphQLErrors?.length && + {!!error?.graphQLErrors?.length && {serializeErrors(error.graphQLErrors).map((error: any) => (
{error.message}
))}
} diff --git a/packages/web/src/graphql/queries/get-apps.ts b/packages/web/src/graphql/queries/get-apps.ts index 59cf4c79..2995dcfc 100644 --- a/packages/web/src/graphql/queries/get-apps.ts +++ b/packages/web/src/graphql/queries/get-apps.ts @@ -22,6 +22,10 @@ export const GET_APPS = gql` description docUrl clickToCopy + options { + label + value + } } authenticationSteps { type