mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-24 20:42:05 +03:00
Trigger workflow on database event (#6480)
- Add global listener on database event - Fetch event listener associated - Trigger associated workflow Also updated the runner so it expects the input to be in the payload rather than the trigger
This commit is contained in:
parent
ae423f5e75
commit
8c8f192765
@ -11,7 +11,7 @@ import { TimelineMessagingModule } from 'src/engine/core-modules/messaging/timel
|
|||||||
import { OpenApiModule } from 'src/engine/core-modules/open-api/open-api.module';
|
import { OpenApiModule } from 'src/engine/core-modules/open-api/open-api.module';
|
||||||
import { PostgresCredentialsModule } from 'src/engine/core-modules/postgres-credentials/postgres-credentials.module';
|
import { PostgresCredentialsModule } from 'src/engine/core-modules/postgres-credentials/postgres-credentials.module';
|
||||||
import { UserModule } from 'src/engine/core-modules/user/user.module';
|
import { UserModule } from 'src/engine/core-modules/user/user.module';
|
||||||
import { WorkflowTriggerModule } from 'src/engine/core-modules/workflow/workflow-trigger.module';
|
import { WorkflowTriggerCoreModule } from 'src/engine/core-modules/workflow/core-workflow-trigger.module';
|
||||||
import { WorkspaceModule } from 'src/engine/core-modules/workspace/workspace.module';
|
import { WorkspaceModule } from 'src/engine/core-modules/workspace/workspace.module';
|
||||||
|
|
||||||
import { AnalyticsModule } from './analytics/analytics.module';
|
import { AnalyticsModule } from './analytics/analytics.module';
|
||||||
@ -35,7 +35,7 @@ import { FileModule } from './file/file.module';
|
|||||||
WorkspaceModule,
|
WorkspaceModule,
|
||||||
AISQLQueryModule,
|
AISQLQueryModule,
|
||||||
PostgresCredentialsModule,
|
PostgresCredentialsModule,
|
||||||
WorkflowTriggerModule,
|
WorkflowTriggerCoreModule,
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
AnalyticsModule,
|
AnalyticsModule,
|
||||||
|
@ -2,11 +2,11 @@ import { Module } from '@nestjs/common';
|
|||||||
|
|
||||||
import { WorkflowTriggerResolver } from 'src/engine/core-modules/workflow/workflow-trigger.resolver';
|
import { WorkflowTriggerResolver } from 'src/engine/core-modules/workflow/workflow-trigger.resolver';
|
||||||
import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-common.module';
|
import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-common.module';
|
||||||
import { WorkflowTriggerService } from 'src/modules/workflow/workflow-trigger/workflow-trigger.service';
|
|
||||||
import { WorkflowRunnerModule } from 'src/modules/workflow/workflow-runner/workflow-runner.module';
|
import { WorkflowRunnerModule } from 'src/modules/workflow/workflow-runner/workflow-runner.module';
|
||||||
|
import { WorkflowTriggerService } from 'src/modules/workflow/workflow-trigger/workflow-trigger.service';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [WorkflowCommonModule, WorkflowRunnerModule],
|
imports: [WorkflowCommonModule, WorkflowRunnerModule],
|
||||||
providers: [WorkflowTriggerService, WorkflowTriggerResolver],
|
providers: [WorkflowTriggerService, WorkflowTriggerResolver],
|
||||||
})
|
})
|
||||||
export class WorkflowTriggerModule {}
|
export class WorkflowTriggerCoreModule {}
|
@ -0,0 +1,18 @@
|
|||||||
|
import { Field, InputType } from '@nestjs/graphql';
|
||||||
|
|
||||||
|
import graphqlTypeJson from 'graphql-type-json';
|
||||||
|
|
||||||
|
@InputType()
|
||||||
|
export class RunWorkflowVersionInput {
|
||||||
|
@Field(() => String, {
|
||||||
|
description: 'Workflow version ID',
|
||||||
|
nullable: false,
|
||||||
|
})
|
||||||
|
workflowVersionId: string;
|
||||||
|
|
||||||
|
@Field(() => graphqlTypeJson, {
|
||||||
|
description: 'Execution result in JSON format',
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
payload?: JSON;
|
||||||
|
}
|
@ -1,12 +1,13 @@
|
|||||||
import { UseGuards } from '@nestjs/common';
|
import { UseGuards } from '@nestjs/common';
|
||||||
import { Args, Mutation, Resolver } from '@nestjs/graphql';
|
import { Args, Mutation, Resolver } from '@nestjs/graphql';
|
||||||
|
|
||||||
|
import { RunWorkflowVersionInput } from 'src/engine/core-modules/workflow/dtos/run-workflow-version-input.dto';
|
||||||
|
import { WorkflowTriggerResultDTO } from 'src/engine/core-modules/workflow/dtos/workflow-trigger-result.dto';
|
||||||
import { workflowTriggerGraphqlApiExceptionHandler } from 'src/engine/core-modules/workflow/utils/workflow-trigger-graphql-api-exception-handler.util';
|
import { workflowTriggerGraphqlApiExceptionHandler } from 'src/engine/core-modules/workflow/utils/workflow-trigger-graphql-api-exception-handler.util';
|
||||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||||
import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard';
|
import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard';
|
||||||
import { WorkflowTriggerService } from 'src/modules/workflow/workflow-trigger/workflow-trigger.service';
|
import { WorkflowTriggerService } from 'src/modules/workflow/workflow-trigger/workflow-trigger.service';
|
||||||
import { WorkflowTriggerResultDTO } from 'src/engine/core-modules/workflow/dtos/workflow-trigger-result.dto';
|
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Resolver()
|
@Resolver()
|
||||||
@ -31,15 +32,16 @@ export class WorkflowTriggerResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Mutation(() => WorkflowTriggerResultDTO)
|
@Mutation(() => WorkflowTriggerResultDTO)
|
||||||
async triggerWorkflow(
|
async runWorkflowVersion(
|
||||||
@AuthWorkspace() { id: workspaceId }: Workspace,
|
@AuthWorkspace() { id: workspaceId }: Workspace,
|
||||||
@Args('workflowVersionId') workflowVersionId: string,
|
@Args('input') { workflowVersionId, payload }: RunWorkflowVersionInput,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
return {
|
return {
|
||||||
result: await this.workflowTriggerService.runWorkflow(
|
result: await this.workflowTriggerService.runWorkflowVersion(
|
||||||
workspaceId,
|
workspaceId,
|
||||||
workflowVersionId,
|
workflowVersionId,
|
||||||
|
payload ?? {},
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -23,6 +23,7 @@ import { AutoCompaniesAndContactsCreationJobModule } from 'src/modules/contact-c
|
|||||||
import { MessagingModule } from 'src/modules/messaging/messaging.module';
|
import { MessagingModule } from 'src/modules/messaging/messaging.module';
|
||||||
import { TimelineJobModule } from 'src/modules/timeline/jobs/timeline-job.module';
|
import { TimelineJobModule } from 'src/modules/timeline/jobs/timeline-job.module';
|
||||||
import { TimelineActivityModule } from 'src/modules/timeline/timeline-activity.module';
|
import { TimelineActivityModule } from 'src/modules/timeline/timeline-activity.module';
|
||||||
|
import { WorkflowModule } from 'src/modules/workflow/workflow.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@ -43,6 +44,7 @@ import { TimelineActivityModule } from 'src/modules/timeline/timeline-activity.m
|
|||||||
WorkspaceQueryRunnerJobModule,
|
WorkspaceQueryRunnerJobModule,
|
||||||
AutoCompaniesAndContactsCreationJobModule,
|
AutoCompaniesAndContactsCreationJobModule,
|
||||||
TimelineJobModule,
|
TimelineJobModule,
|
||||||
|
WorkflowModule,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
CleanInactiveWorkspaceJob,
|
CleanInactiveWorkspaceJob,
|
||||||
|
@ -2,7 +2,6 @@ import { WorkflowAction } from 'src/modules/workflow/common/types/workflow-actio
|
|||||||
|
|
||||||
export enum WorkflowTriggerType {
|
export enum WorkflowTriggerType {
|
||||||
DATABASE_EVENT = 'DATABASE_EVENT',
|
DATABASE_EVENT = 'DATABASE_EVENT',
|
||||||
MANUAL = 'MANUAL',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type BaseTrigger = {
|
type BaseTrigger = {
|
||||||
@ -19,10 +18,4 @@ export type WorkflowDatabaseEventTrigger = BaseTrigger & {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
type WorkflowManualTrigger = BaseTrigger & {
|
export type WorkflowTrigger = WorkflowDatabaseEventTrigger;
|
||||||
type: WorkflowTriggerType.MANUAL;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type WorkflowTrigger =
|
|
||||||
| WorkflowDatabaseEventTrigger
|
|
||||||
| WorkflowManualTrigger;
|
|
||||||
|
@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common';
|
|||||||
|
|
||||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||||
import { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
import { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
||||||
|
import { WorkflowTrigger } from 'src/modules/workflow/common/types/workflow-trigger.type';
|
||||||
import {
|
import {
|
||||||
WorkflowTriggerException,
|
WorkflowTriggerException,
|
||||||
WorkflowTriggerExceptionCode,
|
WorkflowTriggerExceptionCode,
|
||||||
} from 'src/modules/workflow/workflow-trigger/workflow-trigger.exception';
|
} from 'src/modules/workflow/workflow-trigger/workflow-trigger.exception';
|
||||||
import { WorkflowTrigger } from 'src/modules/workflow/common/types/workflow-trigger.type';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WorkflowCommonService {
|
export class WorkflowCommonService {
|
||||||
|
@ -1,32 +1,54 @@
|
|||||||
|
import { Process } from 'src/engine/integrations/message-queue/decorators/process.decorator';
|
||||||
import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator';
|
import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator';
|
||||||
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
||||||
import { Process } from 'src/engine/integrations/message-queue/decorators/process.decorator';
|
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||||
import { WorkflowRunnerService } from 'src/modules/workflow/workflow-runner/workflow-runner.service';
|
import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
|
||||||
import { WorkflowCommonService } from 'src/modules/workflow/common/workflow-common.services';
|
import { WorkflowCommonService } from 'src/modules/workflow/common/workflow-common.services';
|
||||||
|
import { WorkflowRunnerService } from 'src/modules/workflow/workflow-runner/workflow-runner.service';
|
||||||
|
|
||||||
type RunWorkflowJobData = { workspaceId: string; workflowVersionId: string };
|
export type RunWorkflowJobData = {
|
||||||
|
workspaceId: string;
|
||||||
|
workflowId: string;
|
||||||
|
payload: object;
|
||||||
|
};
|
||||||
|
|
||||||
@Processor(MessageQueue.workflowQueue)
|
@Processor(MessageQueue.workflowQueue)
|
||||||
export class WorkflowRunnerJob {
|
export class WorkflowRunnerJob {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly workflowCommonService: WorkflowCommonService,
|
private readonly workflowCommonService: WorkflowCommonService,
|
||||||
private readonly workflowRunnerService: WorkflowRunnerService,
|
private readonly workflowRunnerService: WorkflowRunnerService,
|
||||||
|
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Process(WorkflowRunnerJob.name)
|
@Process(WorkflowRunnerJob.name)
|
||||||
async handle({
|
async handle({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
workflowVersionId,
|
workflowId,
|
||||||
|
payload,
|
||||||
}: RunWorkflowJobData): Promise<void> {
|
}: RunWorkflowJobData): Promise<void> {
|
||||||
|
const workflowRepository =
|
||||||
|
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkflowWorkspaceEntity>(
|
||||||
|
workspaceId,
|
||||||
|
'workflow',
|
||||||
|
);
|
||||||
|
|
||||||
|
const workflow = await workflowRepository.findOneByOrFail({
|
||||||
|
id: workflowId,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!workflow.publishedVersionId) {
|
||||||
|
throw new Error('Workflow has no published version');
|
||||||
|
}
|
||||||
|
|
||||||
const workflowVersion = await this.workflowCommonService.getWorkflowVersion(
|
const workflowVersion = await this.workflowCommonService.getWorkflowVersion(
|
||||||
workspaceId,
|
workspaceId,
|
||||||
workflowVersionId,
|
workflow.publishedVersionId,
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.workflowRunnerService.run({
|
await this.workflowRunnerService.run({
|
||||||
action: workflowVersion.trigger.nextAction,
|
action: workflowVersion.trigger.nextAction,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
payload: workflowVersion.trigger.input,
|
payload,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
import { Logger } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { InjectMessageQueue } from 'src/engine/integrations/message-queue/decorators/message-queue.decorator';
|
||||||
|
import { Process } from 'src/engine/integrations/message-queue/decorators/process.decorator';
|
||||||
|
import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator';
|
||||||
|
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
||||||
|
import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service';
|
||||||
|
import {
|
||||||
|
RunWorkflowJobData,
|
||||||
|
WorkflowRunnerJob,
|
||||||
|
} from 'src/modules/workflow/workflow-runner/workflow-runner.job';
|
||||||
|
|
||||||
|
export type WorkflowEventTriggerJobData = {
|
||||||
|
workspaceId: string;
|
||||||
|
workflowId: string;
|
||||||
|
payload: object;
|
||||||
|
};
|
||||||
|
|
||||||
|
@Processor(MessageQueue.workflowQueue)
|
||||||
|
export class WorkflowEventTriggerJob {
|
||||||
|
private readonly logger = new Logger(WorkflowEventTriggerJob.name);
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@InjectMessageQueue(MessageQueue.workflowQueue)
|
||||||
|
private readonly messageQueueService: MessageQueueService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
@Process(WorkflowEventTriggerJob.name)
|
||||||
|
async handle(data: WorkflowEventTriggerJobData): Promise<void> {
|
||||||
|
this.messageQueueService.add<RunWorkflowJobData>(WorkflowRunnerJob.name, {
|
||||||
|
workspaceId: data.workspaceId,
|
||||||
|
workflowId: data.workflowId,
|
||||||
|
payload: data.payload,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { WorkflowRunnerModule } from 'src/modules/workflow/workflow-runner/workflow-runner.module';
|
||||||
|
import { WorkflowEventTriggerJob } from 'src/modules/workflow/workflow-trigger/jobs/workflow-event-trigger.job';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [WorkflowRunnerModule],
|
||||||
|
providers: [WorkflowEventTriggerJob],
|
||||||
|
})
|
||||||
|
export class WorkflowTriggerJobModule {}
|
@ -0,0 +1,98 @@
|
|||||||
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
|
import { OnEvent } from '@nestjs/event-emitter';
|
||||||
|
|
||||||
|
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||||
|
import { IsFeatureEnabledService } from 'src/engine/core-modules/feature-flag/services/is-feature-enabled.service';
|
||||||
|
import { ObjectRecordCreateEvent } from 'src/engine/integrations/event-emitter/types/object-record-create.event';
|
||||||
|
import { ObjectRecordDeleteEvent } from 'src/engine/integrations/event-emitter/types/object-record-delete.event';
|
||||||
|
import { ObjectRecordUpdateEvent } from 'src/engine/integrations/event-emitter/types/object-record-update.event';
|
||||||
|
import { InjectMessageQueue } from 'src/engine/integrations/message-queue/decorators/message-queue.decorator';
|
||||||
|
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
|
||||||
|
import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service';
|
||||||
|
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||||
|
import { WorkflowEventListenerWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-event-listener.workspace-entity';
|
||||||
|
import {
|
||||||
|
WorkflowEventTriggerJob,
|
||||||
|
WorkflowEventTriggerJobData,
|
||||||
|
} from 'src/modules/workflow/workflow-trigger/jobs/workflow-event-trigger.job';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class DatabaseEventTriggerListener {
|
||||||
|
private readonly logger = new Logger('DatabaseEventTriggerListener');
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||||
|
@InjectMessageQueue(MessageQueue.workflowQueue)
|
||||||
|
private readonly messageQueueService: MessageQueueService,
|
||||||
|
private readonly isFeatureFlagEnabledService: IsFeatureEnabledService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
@OnEvent('*.created')
|
||||||
|
async handleObjectRecordCreateEvent(payload: ObjectRecordCreateEvent<any>) {
|
||||||
|
await this.handleEvent(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnEvent('*.updated')
|
||||||
|
async handleObjectRecordUpdateEvent(payload: ObjectRecordUpdateEvent<any>) {
|
||||||
|
await this.handleEvent(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnEvent('*.deleted')
|
||||||
|
async handleObjectRecordDeleteEvent(payload: ObjectRecordDeleteEvent<any>) {
|
||||||
|
await this.handleEvent(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async handleEvent(
|
||||||
|
payload:
|
||||||
|
| ObjectRecordCreateEvent<any>
|
||||||
|
| ObjectRecordUpdateEvent<any>
|
||||||
|
| ObjectRecordDeleteEvent<any>,
|
||||||
|
) {
|
||||||
|
const workspaceId = payload.workspaceId;
|
||||||
|
const eventName = payload.name;
|
||||||
|
|
||||||
|
if (!workspaceId || !eventName) {
|
||||||
|
this.logger.error(
|
||||||
|
`Missing workspaceId or eventName in payload ${JSON.stringify(
|
||||||
|
payload,
|
||||||
|
)}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isWorkflowEnabled =
|
||||||
|
await this.isFeatureFlagEnabledService.isFeatureEnabled(
|
||||||
|
FeatureFlagKey.IsWorkflowEnabled,
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isWorkflowEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const workflowEventListenerRepository =
|
||||||
|
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkflowEventListenerWorkspaceEntity>(
|
||||||
|
workspaceId,
|
||||||
|
'workflowEventListener',
|
||||||
|
);
|
||||||
|
|
||||||
|
const eventListeners = await workflowEventListenerRepository.find({
|
||||||
|
where: {
|
||||||
|
eventName,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const eventListener of eventListeners) {
|
||||||
|
this.messageQueueService.add<WorkflowEventTriggerJobData>(
|
||||||
|
WorkflowEventTriggerJob.name,
|
||||||
|
{
|
||||||
|
workspaceId,
|
||||||
|
workflowId: eventListener.workflowId,
|
||||||
|
payload,
|
||||||
|
},
|
||||||
|
{ retryLimit: 3 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
|
||||||
|
import { DatabaseEventTriggerListener } from 'src/modules/workflow/workflow-trigger/listeners/database-event-trigger.listener';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [FeatureFlagModule],
|
||||||
|
providers: [DatabaseEventTriggerListener],
|
||||||
|
})
|
||||||
|
export class WorkflowTriggerListenerModule {}
|
@ -0,0 +1,9 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { WorkflowTriggerJobModule } from 'src/modules/workflow/workflow-trigger/jobs/workflow-trigger-job.module';
|
||||||
|
import { WorkflowTriggerListenerModule } from 'src/modules/workflow/workflow-trigger/listeners/workflow-trigger-listener.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [WorkflowTriggerJobModule, WorkflowTriggerListenerModule],
|
||||||
|
})
|
||||||
|
export class WorkflowTriggerModule {}
|
@ -2,16 +2,17 @@ import { Injectable } from '@nestjs/common';
|
|||||||
|
|
||||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||||
import { WorkflowEventListenerWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-event-listener.workspace-entity';
|
import { WorkflowEventListenerWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-event-listener.workspace-entity';
|
||||||
import {
|
import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
|
||||||
WorkflowTriggerException,
|
|
||||||
WorkflowTriggerExceptionCode,
|
|
||||||
} from 'src/modules/workflow/workflow-trigger/workflow-trigger.exception';
|
|
||||||
import {
|
import {
|
||||||
WorkflowDatabaseEventTrigger,
|
WorkflowDatabaseEventTrigger,
|
||||||
WorkflowTriggerType,
|
WorkflowTriggerType,
|
||||||
} from 'src/modules/workflow/common/types/workflow-trigger.type';
|
} from 'src/modules/workflow/common/types/workflow-trigger.type';
|
||||||
import { WorkflowCommonService } from 'src/modules/workflow/common/workflow-common.services';
|
import { WorkflowCommonService } from 'src/modules/workflow/common/workflow-common.services';
|
||||||
import { WorkflowRunnerService } from 'src/modules/workflow/workflow-runner/workflow-runner.service';
|
import { WorkflowRunnerService } from 'src/modules/workflow/workflow-runner/workflow-runner.service';
|
||||||
|
import {
|
||||||
|
WorkflowTriggerException,
|
||||||
|
WorkflowTriggerExceptionCode,
|
||||||
|
} from 'src/modules/workflow/workflow-trigger/workflow-trigger.exception';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WorkflowTriggerService {
|
export class WorkflowTriggerService {
|
||||||
@ -21,7 +22,11 @@ export class WorkflowTriggerService {
|
|||||||
private readonly workflowRunnerService: WorkflowRunnerService,
|
private readonly workflowRunnerService: WorkflowRunnerService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async runWorkflow(workspaceId: string, workflowVersionId: string) {
|
async runWorkflowVersion(
|
||||||
|
workspaceId: string,
|
||||||
|
workflowVersionId: string,
|
||||||
|
payload: object,
|
||||||
|
) {
|
||||||
const workflowVersion = await this.workflowCommonService.getWorkflowVersion(
|
const workflowVersion = await this.workflowCommonService.getWorkflowVersion(
|
||||||
workspaceId,
|
workspaceId,
|
||||||
workflowVersionId,
|
workflowVersionId,
|
||||||
@ -30,7 +35,7 @@ export class WorkflowTriggerService {
|
|||||||
return await this.workflowRunnerService.run({
|
return await this.workflowRunnerService.run({
|
||||||
action: workflowVersion.trigger.nextAction,
|
action: workflowVersion.trigger.nextAction,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
payload: workflowVersion.trigger.input,
|
payload,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,9 +47,10 @@ export class WorkflowTriggerService {
|
|||||||
|
|
||||||
switch (workflowVersion.trigger.type) {
|
switch (workflowVersion.trigger.type) {
|
||||||
case WorkflowTriggerType.DATABASE_EVENT:
|
case WorkflowTriggerType.DATABASE_EVENT:
|
||||||
await this.upsertWorkflowEventListener(
|
await this.upsertEventListenerAndPublishVersion(
|
||||||
workspaceId,
|
workspaceId,
|
||||||
workflowVersion.workflowId,
|
workflowVersion.workflowId,
|
||||||
|
workflowVersionId,
|
||||||
workflowVersion.trigger,
|
workflowVersion.trigger,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
@ -55,9 +61,10 @@ export class WorkflowTriggerService {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async upsertWorkflowEventListener(
|
private async upsertEventListenerAndPublishVersion(
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
workflowId: string,
|
workflowId: string,
|
||||||
|
workflowVersionId: string,
|
||||||
trigger: WorkflowDatabaseEventTrigger,
|
trigger: WorkflowDatabaseEventTrigger,
|
||||||
) {
|
) {
|
||||||
const eventName = trigger?.settings?.eventName;
|
const eventName = trigger?.settings?.eventName;
|
||||||
@ -75,17 +82,41 @@ export class WorkflowTriggerService {
|
|||||||
'workflowEventListener',
|
'workflowEventListener',
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: Use upsert when available for workspace entities
|
|
||||||
await workflowEventListenerRepository.delete({
|
|
||||||
workflowId,
|
|
||||||
eventName,
|
|
||||||
});
|
|
||||||
|
|
||||||
const workflowEventListener = await workflowEventListenerRepository.create({
|
const workflowEventListener = await workflowEventListenerRepository.create({
|
||||||
workflowId,
|
workflowId,
|
||||||
eventName,
|
eventName,
|
||||||
});
|
});
|
||||||
|
|
||||||
await workflowEventListenerRepository.save(workflowEventListener);
|
const workspaceDataSource =
|
||||||
|
await this.twentyORMGlobalManager.getDataSourceForWorkspace(workspaceId);
|
||||||
|
|
||||||
|
const workflowRepository =
|
||||||
|
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkflowWorkspaceEntity>(
|
||||||
|
workspaceId,
|
||||||
|
'workflow',
|
||||||
|
);
|
||||||
|
|
||||||
|
await workspaceDataSource?.transaction(async (transactionManager) => {
|
||||||
|
// TODO: Use upsert when available for workspace entities
|
||||||
|
await workflowEventListenerRepository.delete(
|
||||||
|
{
|
||||||
|
workflowId,
|
||||||
|
eventName,
|
||||||
|
},
|
||||||
|
transactionManager,
|
||||||
|
);
|
||||||
|
|
||||||
|
await workflowEventListenerRepository.save(
|
||||||
|
workflowEventListener,
|
||||||
|
{},
|
||||||
|
transactionManager,
|
||||||
|
);
|
||||||
|
|
||||||
|
await workflowRepository.update(
|
||||||
|
{ id: workflowId },
|
||||||
|
{ publishedVersionId: workflowVersionId },
|
||||||
|
transactionManager,
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { WorkflowRunnerModule } from 'src/modules/workflow/workflow-runner/workflow-runner.module';
|
import { WorkflowRunnerModule } from 'src/modules/workflow/workflow-runner/workflow-runner.module';
|
||||||
|
import { WorkflowTriggerModule } from 'src/modules/workflow/workflow-trigger/workflow-trigger.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [WorkflowRunnerModule],
|
imports: [WorkflowRunnerModule, WorkflowTriggerModule],
|
||||||
})
|
})
|
||||||
export class WorkflowModule {}
|
export class WorkflowModule {}
|
||||||
|
Loading…
Reference in New Issue
Block a user