From e5434f0b871e45447227aa8d55ba5af381c3ff1c Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Wed, 20 Mar 2024 15:25:27 +0100 Subject: [PATCH] refactoring --- .../gmail-full-sync/gmail-full-sync.module.ts | 2 - .../gmail-partial-sync.module.ts | 2 - .../message-participant.service.ts | 60 ++++++- .../services/message/message.service.ts | 83 +++++++++- ...save-message-and-create-contacts.module.ts | 26 --- ...ve-messages-and-create-contacts.service.ts | 150 ------------------ 6 files changed, 140 insertions(+), 183 deletions(-) delete mode 100644 packages/twenty-server/src/modules/messaging/services/save-message-and-create-contact/save-message-and-create-contacts.module.ts delete mode 100644 packages/twenty-server/src/modules/messaging/services/save-message-and-create-contact/save-messages-and-create-contacts.service.ts diff --git a/packages/twenty-server/src/modules/messaging/services/gmail-full-sync/gmail-full-sync.module.ts b/packages/twenty-server/src/modules/messaging/services/gmail-full-sync/gmail-full-sync.module.ts index b9a12f9c29..0078cc42db 100644 --- a/packages/twenty-server/src/modules/messaging/services/gmail-full-sync/gmail-full-sync.module.ts +++ b/packages/twenty-server/src/modules/messaging/services/gmail-full-sync/gmail-full-sync.module.ts @@ -8,7 +8,6 @@ import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/st import { FetchMessagesByBatchesModule } from 'src/modules/messaging/services/fetch-messages-by-batches/fetch-messages-by-batches.module'; import { GmailFullSyncService } from 'src/modules/messaging/services/gmail-full-sync/gmail-full-sync.service'; import { MessagingProvidersModule } from 'src/modules/messaging/services/providers/messaging-providers.module'; -import { SaveMessagesAndCreateContactsModule } from 'src/modules/messaging/services/save-message-and-create-contact/save-message-and-create-contacts.module'; import { MessageChannelMessageAssociationObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel-message-association.object-metadata'; import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; @@ -22,7 +21,6 @@ import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-obj MessageChannelMessageAssociationObjectMetadata, BlocklistObjectMetadata, ]), - SaveMessagesAndCreateContactsModule, TypeOrmModule.forFeature([FeatureFlagEntity], 'core'), ], providers: [GmailFullSyncService], diff --git a/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.module.ts b/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.module.ts index 744e70295b..f92e12e67e 100644 --- a/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.module.ts +++ b/packages/twenty-server/src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.module.ts @@ -9,7 +9,6 @@ import { FetchMessagesByBatchesModule } from 'src/modules/messaging/services/fet import { GmailPartialSyncService } from 'src/modules/messaging/services/gmail-partial-sync/gmail-partial-sync.service'; import { MessageModule } from 'src/modules/messaging/services/message/message.module'; import { MessagingProvidersModule } from 'src/modules/messaging/services/providers/messaging-providers.module'; -import { SaveMessagesAndCreateContactsModule } from 'src/modules/messaging/services/save-message-and-create-contact/save-message-and-create-contacts.module'; import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; @Module({ @@ -22,7 +21,6 @@ import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-obj BlocklistObjectMetadata, ]), MessageModule, - SaveMessagesAndCreateContactsModule, TypeOrmModule.forFeature([FeatureFlagEntity], 'core'), ], providers: [GmailPartialSyncService], diff --git a/packages/twenty-server/src/modules/messaging/services/message-participant/message-participant.service.ts b/packages/twenty-server/src/modules/messaging/services/message-participant/message-participant.service.ts index 7219051817..aede57e90d 100644 --- a/packages/twenty-server/src/modules/messaging/services/message-participant/message-participant.service.ts +++ b/packages/twenty-server/src/modules/messaging/services/message-participant/message-participant.service.ts @@ -1,19 +1,33 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable, Logger } from '@nestjs/common'; +import { EventEmitter2 } from '@nestjs/event-emitter'; import { EntityManager } from 'typeorm'; import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; -import { ParticipantWithId } from 'src/modules/messaging/types/gmail-message'; +import { + ParticipantWithId, + ParticipantWithMessageId, +} from 'src/modules/messaging/types/gmail-message'; import { PersonRepository } from 'src/modules/person/repositories/person.repository'; import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; +import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; +import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; +import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; +import { MessageParticipantRepository } from 'src/modules/messaging/repositories/message-participant.repository'; +import { MessageService } from 'src/modules/messaging/services/message/message.service'; @Injectable() export class MessageParticipantService { + private readonly logger = new Logger(MessageParticipantService.name); + constructor( private readonly workspaceDataSourceService: WorkspaceDataSourceService, @InjectObjectMetadataRepository(PersonObjectMetadata) private readonly personRepository: PersonRepository, + private readonly messageParticipantRepository: MessageParticipantRepository, + private readonly eventEmitter: EventEmitter2, + private readonly messageService: MessageService, ) {} public async updateMessageParticipantsAfterPeopleCreation( @@ -56,4 +70,46 @@ export class MessageParticipantService { transactionManager, ); } + + public async tryToSaveMessageParticipantsOrDeleteMessagesIfError( + participantsWithMessageId: ParticipantWithMessageId[], + gmailMessageChannel: ObjectRecord, + workspaceId: string, + connectedAccount: ObjectRecord, + jobName?: string, + ) { + try { + await this.messageParticipantRepository.saveMessageParticipants( + participantsWithMessageId, + workspaceId, + ); + + if (gmailMessageChannel.isContactAutoCreationEnabled) { + const contactsToCreate = participantsWithMessageId.filter( + (participant) => participant.role === 'from', + ); + + this.eventEmitter.emit(`createContacts`, { + workspaceId, + connectedAccountHandle: connectedAccount.handle, + contactsToCreate, + }); + } + } catch (error) { + this.logger.error( + `${jobName} error saving message participants for workspace ${workspaceId} and account ${connectedAccount.id}`, + error, + ); + + const messagesToDelete = participantsWithMessageId.map( + (participant) => participant.messageId, + ); + + await this.messageService.deleteMessages( + messagesToDelete, + gmailMessageChannel.id, + workspaceId, + ); + } + } } diff --git a/packages/twenty-server/src/modules/messaging/services/message/message.service.ts b/packages/twenty-server/src/modules/messaging/services/message/message.service.ts index 7832ecefe1..b9d7376593 100644 --- a/packages/twenty-server/src/modules/messaging/services/message/message.service.ts +++ b/packages/twenty-server/src/modules/messaging/services/message/message.service.ts @@ -11,13 +11,17 @@ import { MessageChannelMessageAssociationRepository } from 'src/modules/messagin import { MessageRepository } from 'src/modules/messaging/repositories/message.repository'; import { MessageChannelMessageAssociationObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel-message-association.object-metadata'; import { MessageObjectMetadata } from 'src/modules/messaging/standard-objects/message.object-metadata'; -import { GmailMessage } from 'src/modules/messaging/types/gmail-message'; +import { + GmailMessage, + ParticipantWithMessageId, +} from 'src/modules/messaging/types/gmail-message'; import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; import { MessageChannelRepository } from 'src/modules/messaging/repositories/message-channel.repository'; import { MessageThreadService } from 'src/modules/messaging/services/message-thread/message-thread.service'; import { MessageThreadObjectMetadata } from 'src/modules/messaging/standard-objects/message-thread.object-metadata'; import { MessageThreadRepository } from 'src/modules/messaging/repositories/message-thread.repository'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; +import { MessageParticipantService } from 'src/modules/messaging/services/message-participant/message-participant.service'; @Injectable() export class MessageService { @@ -36,6 +40,7 @@ export class MessageService { @InjectObjectMetadataRepository(MessageThreadObjectMetadata) private readonly messageThreadRepository: MessageThreadRepository, private readonly messageThreadService: MessageThreadService, + private readonly messageParticipantService: MessageParticipantService, ) {} public async saveMessages( @@ -265,4 +270,80 @@ export class MessageService { ); }); } + + async saveMessagesAndEmitContactCreationEvent( + messagesToSave: GmailMessage[], + connectedAccount: ObjectRecord, + workspaceId: string, + gmailMessageChannelId: string, + jobName?: string, + ) { + const { dataSource: workspaceDataSource, dataSourceMetadata } = + await this.workspaceDataSourceService.connectedToWorkspaceDataSourceAndReturnMetadata( + workspaceId, + ); + + let startTime = Date.now(); + + const messageExternalIdsAndIdsMap = await this.saveMessages( + messagesToSave, + dataSourceMetadata, + workspaceDataSource, + connectedAccount, + gmailMessageChannelId, + workspaceId, + ); + + let endTime = Date.now(); + + this.logger.log( + `${jobName} saving messages for workspace ${workspaceId} and account ${ + connectedAccount.id + } in ${endTime - startTime}ms`, + ); + + const gmailMessageChannel = + await this.messageChannelRepository.getFirstByConnectedAccountId( + connectedAccount.id, + workspaceId, + ); + + if (!gmailMessageChannel) { + this.logger.error( + `No message channel found for connected account ${connectedAccount.id} in workspace ${workspaceId} in saveMessagesAndCreateContacts`, + ); + + return; + } + + const participantsWithMessageId: ParticipantWithMessageId[] = + messagesToSave.flatMap((message) => { + const messageId = messageExternalIdsAndIdsMap.get(message.externalId); + + return messageId + ? message.participants.map((participant) => ({ + ...participant, + messageId, + })) + : []; + }); + + startTime = Date.now(); + + await this.messageParticipantService.tryToSaveMessageParticipantsOrDeleteMessagesIfError( + participantsWithMessageId, + gmailMessageChannel, + workspaceId, + connectedAccount, + jobName, + ); + + endTime = Date.now(); + + this.logger.log( + `${jobName} saving message participants for workspace ${workspaceId} and account in ${ + connectedAccount.id + } ${endTime - startTime}ms`, + ); + } } diff --git a/packages/twenty-server/src/modules/messaging/services/save-message-and-create-contact/save-message-and-create-contacts.module.ts b/packages/twenty-server/src/modules/messaging/services/save-message-and-create-contact/save-message-and-create-contacts.module.ts deleted file mode 100644 index d38a8cb182..0000000000 --- a/packages/twenty-server/src/modules/messaging/services/save-message-and-create-contact/save-message-and-create-contacts.module.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; -import { AutoCompaniesAndContactsCreationModule } from 'src/modules/connected-account/auto-companies-and-contacts-creation/auto-companies-and-contacts-creation.module'; -import { MessageParticipantModule } from 'src/modules/messaging/services/message-participant/message-participant.module'; -import { MessageModule } from 'src/modules/messaging/services/message/message.module'; -import { SaveMessagesAndCreateContactsService } from 'src/modules/messaging/services/save-message-and-create-contact/save-messages-and-create-contacts.service'; -import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; -import { MessageParticipantObjectMetadata } from 'src/modules/messaging/standard-objects/message-participant.object-metadata'; - -@Module({ - imports: [ - MessageModule, - ObjectMetadataRepositoryModule.forFeature([ - MessageChannelObjectMetadata, - MessageParticipantObjectMetadata, - ]), - AutoCompaniesAndContactsCreationModule, - MessageParticipantModule, - WorkspaceDataSourceModule, - ], - providers: [SaveMessagesAndCreateContactsService], - exports: [SaveMessagesAndCreateContactsService], -}) -export class SaveMessagesAndCreateContactsModule {} diff --git a/packages/twenty-server/src/modules/messaging/services/save-message-and-create-contact/save-messages-and-create-contacts.service.ts b/packages/twenty-server/src/modules/messaging/services/save-message-and-create-contact/save-messages-and-create-contacts.service.ts deleted file mode 100644 index da93d738cc..0000000000 --- a/packages/twenty-server/src/modules/messaging/services/save-message-and-create-contact/save-messages-and-create-contacts.service.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { Injectable, Logger } from '@nestjs/common'; -import { EventEmitter2 } from '@nestjs/event-emitter'; - -import { MessageChannelRepository } from 'src/modules/messaging/repositories/message-channel.repository'; -import { MessageParticipantRepository } from 'src/modules/messaging/repositories/message-participant.repository'; -import { - GmailMessage, - ParticipantWithMessageId, -} from 'src/modules/messaging/types/gmail-message'; -import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; -import { ConnectedAccountObjectMetadata } from 'src/modules/connected-account/standard-objects/connected-account.object-metadata'; -import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; -import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; -import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata'; -import { MessageService } from 'src/modules/messaging/services/message/message.service'; -import { MessageParticipantObjectMetadata } from 'src/modules/messaging/standard-objects/message-participant.object-metadata'; - -@Injectable() -export class SaveMessagesAndCreateContactsService { - private readonly logger = new Logger( - SaveMessagesAndCreateContactsService.name, - ); - - constructor( - private readonly messageService: MessageService, - @InjectObjectMetadataRepository(MessageChannelObjectMetadata) - private readonly messageChannelRepository: MessageChannelRepository, - @InjectObjectMetadataRepository(MessageParticipantObjectMetadata) - private readonly messageParticipantRepository: MessageParticipantRepository, - private readonly eventEmitter: EventEmitter2, - private readonly workspaceDataSourceService: WorkspaceDataSourceService, - ) {} - - async saveMessagesAndCreateContacts( - messagesToSave: GmailMessage[], - connectedAccount: ObjectRecord, - workspaceId: string, - gmailMessageChannelId: string, - jobName?: string, - ) { - const { dataSource: workspaceDataSource, dataSourceMetadata } = - await this.workspaceDataSourceService.connectedToWorkspaceDataSourceAndReturnMetadata( - workspaceId, - ); - - let startTime = Date.now(); - - const messageExternalIdsAndIdsMap = await this.messageService.saveMessages( - messagesToSave, - dataSourceMetadata, - workspaceDataSource, - connectedAccount, - gmailMessageChannelId, - workspaceId, - ); - - let endTime = Date.now(); - - this.logger.log( - `${jobName} saving messages for workspace ${workspaceId} and account ${ - connectedAccount.id - } in ${endTime - startTime}ms`, - ); - - const gmailMessageChannel = - await this.messageChannelRepository.getFirstByConnectedAccountId( - connectedAccount.id, - workspaceId, - ); - - if (!gmailMessageChannel) { - this.logger.error( - `No message channel found for connected account ${connectedAccount.id} in workspace ${workspaceId} in saveMessagesAndCreateContacts`, - ); - - return; - } - - const participantsWithMessageId: ParticipantWithMessageId[] = - messagesToSave.flatMap((message) => { - const messageId = messageExternalIdsAndIdsMap.get(message.externalId); - - return messageId - ? message.participants.map((participant) => ({ - ...participant, - messageId, - })) - : []; - }); - - startTime = Date.now(); - - await this.tryToSaveMessageParticipantsOrDeleteMessagesIfError( - participantsWithMessageId, - gmailMessageChannel, - workspaceId, - connectedAccount, - jobName, - ); - - endTime = Date.now(); - - this.logger.log( - `${jobName} saving message participants for workspace ${workspaceId} and account in ${ - connectedAccount.id - } ${endTime - startTime}ms`, - ); - } - - private async tryToSaveMessageParticipantsOrDeleteMessagesIfError( - participantsWithMessageId: ParticipantWithMessageId[], - gmailMessageChannel: ObjectRecord, - workspaceId: string, - connectedAccount: ObjectRecord, - jobName?: string, - ) { - try { - await this.messageParticipantRepository.saveMessageParticipants( - participantsWithMessageId, - workspaceId, - ); - - if (gmailMessageChannel.isContactAutoCreationEnabled) { - const contactsToCreate = participantsWithMessageId.filter( - (participant) => participant.role === 'from', - ); - - this.eventEmitter.emit(`createContacts`, { - workspaceId, - contactsToCreate, - }); - } - } catch (error) { - this.logger.error( - `${jobName} error saving message participants for workspace ${workspaceId} and account ${connectedAccount.id}`, - error, - ); - - const messagesToDelete = participantsWithMessageId.map( - (participant) => participant.messageId, - ); - - await this.messageService.deleteMessages( - messagesToDelete, - gmailMessageChannel.id, - workspaceId, - ); - } - } -}