From 68977dc6753097b969d2807d16c56fe32607eea8 Mon Sep 17 00:00:00 2001 From: bosiraphael <71827178+bosiraphael@users.noreply.github.com> Date: Fri, 29 Mar 2024 10:03:00 +0100 Subject: [PATCH] Calendar event fixes and improvements (#4690) * fixes * saving workspaceMemberId and personId when saving attendees * add typing * use Map * improve saveMessageParticipants * fix role type * move logic in a service * create new service * use new service in calendar-event-attendee.service * modify service to include more common logic * add defaumt value to isOrganizer in calendar-event-attendee.object-metadata * rename folder * renaming --- .../timeline-calendar-event.service.ts | 3 +- .../message-queue/drivers/pg-boss.driver.ts | 2 +- .../calendar-event-attendee.repository.ts | 32 ------- .../calendar-event-attendee.module.ts | 2 + .../calendar-event-attendee.service.ts | 48 +++++++++- .../google-calendar-full-sync.module.ts | 2 + .../google-calendar-full-sync.service.ts | 4 +- ...calendar-event-attendee.object-metadata.ts | 1 + ...erson-id-and-workspace-member-id.module.ts | 16 ++++ ...rson-id-and-workspace-member-id.service.ts | 90 +++++++++++++++++++ .../message-participant.repository.ts | 64 +------------ .../message-participant.module.ts | 2 + .../message-participant.service.ts | 47 +++++++++- ...-and-emit-contact-creation-event.module.ts | 6 +- ...and-emit-contact-creation-event.service.ts | 10 +-- 15 files changed, 217 insertions(+), 112 deletions(-) create mode 100644 packages/twenty-server/src/modules/connected-account/services/add-person-id-and-workspace-member-id/add-person-id-and-workspace-member-id.module.ts create mode 100644 packages/twenty-server/src/modules/connected-account/services/add-person-id-and-workspace-member-id/add-person-id-and-workspace-member-id.service.ts diff --git a/packages/twenty-server/src/engine/core-modules/calendar/timeline-calendar-event.service.ts b/packages/twenty-server/src/engine/core-modules/calendar/timeline-calendar-event.service.ts index 7a96577cd..63e725e3c 100644 --- a/packages/twenty-server/src/engine/core-modules/calendar/timeline-calendar-event.service.ts +++ b/packages/twenty-server/src/engine/core-modules/calendar/timeline-calendar-event.service.ts @@ -214,8 +214,7 @@ export class TimelineCalendarEventService { event.description = ''; event.location = ''; event.conferenceSolution = ''; - event.conferenceLink.label = ''; - event.conferenceLink.url = ''; + event.conferenceLink = { label: '', url: '' }; } }); diff --git a/packages/twenty-server/src/engine/integrations/message-queue/drivers/pg-boss.driver.ts b/packages/twenty-server/src/engine/integrations/message-queue/drivers/pg-boss.driver.ts index eba836b75..5210593c3 100644 --- a/packages/twenty-server/src/engine/integrations/message-queue/drivers/pg-boss.driver.ts +++ b/packages/twenty-server/src/engine/integrations/message-queue/drivers/pg-boss.driver.ts @@ -11,7 +11,7 @@ import { MessageQueueDriver } from './interfaces/message-queue-driver.interface' export type PgBossDriverOptions = PgBoss.ConstructorOptions; -const DEFAULT_PG_BOSS_CRON_PATTERN_WHEN_NOT_PROVIDED = '*/10 * * * *'; +const DEFAULT_PG_BOSS_CRON_PATTERN_WHEN_NOT_PROVIDED = '*/1 * * * *'; export class PgBossDriver implements MessageQueueDriver { private pgBoss: PgBoss; diff --git a/packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee.repository.ts b/packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee.repository.ts index 2a05e5e64..60fabbdea 100644 --- a/packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee.repository.ts +++ b/packages/twenty-server/src/modules/calendar/repositories/calendar-event-attendee.repository.ts @@ -78,38 +78,6 @@ export class CalendarEventAttendeeRepository { ); } - public async saveCalendarEventAttendees( - calendarEventAttendees: CalendarEventAttendee[], - workspaceId: string, - transactionManager?: EntityManager, - ): Promise { - if (calendarEventAttendees.length === 0) { - return; - } - - const dataSourceSchema = - this.workspaceDataSourceService.getSchemaName(workspaceId); - - const { flattenedValues, valuesString } = - getFlattenedValuesAndValuesStringForBatchRawQuery( - calendarEventAttendees, - { - calendarEventId: 'uuid', - handle: 'text', - displayName: 'text', - isOrganizer: 'boolean', - responseStatus: `${dataSourceSchema}."calendarEventAttendee_responsestatus_enum"`, - }, - ); - - await this.workspaceDataSourceService.executeRawQuery( - `INSERT INTO ${dataSourceSchema}."calendarEventAttendee" ("calendarEventId", "handle", "displayName", "isOrganizer", "responseStatus") VALUES ${valuesString}`, - flattenedValues, - workspaceId, - transactionManager, - ); - } - public async updateCalendarEventAttendees( calendarEventAttendees: CalendarEventAttendee[], iCalUIDCalendarEventIdMap: Map, diff --git a/packages/twenty-server/src/modules/calendar/services/calendar-event-attendee/calendar-event-attendee.module.ts b/packages/twenty-server/src/modules/calendar/services/calendar-event-attendee/calendar-event-attendee.module.ts index 27b5ccb84..64385028f 100644 --- a/packages/twenty-server/src/modules/calendar/services/calendar-event-attendee/calendar-event-attendee.module.ts +++ b/packages/twenty-server/src/modules/calendar/services/calendar-event-attendee/calendar-event-attendee.module.ts @@ -3,12 +3,14 @@ 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 { CalendarEventAttendeeService } from 'src/modules/calendar/services/calendar-event-attendee/calendar-event-attendee.service'; +import { AddPersonIdAndWorkspaceMemberIdModule } from 'src/modules/connected-account/services/add-person-id-and-workspace-member-id/add-person-id-and-workspace-member-id.module'; import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; @Module({ imports: [ WorkspaceDataSourceModule, ObjectMetadataRepositoryModule.forFeature([PersonObjectMetadata]), + AddPersonIdAndWorkspaceMemberIdModule, ], providers: [CalendarEventAttendeeService], exports: [CalendarEventAttendeeService], diff --git a/packages/twenty-server/src/modules/calendar/services/calendar-event-attendee/calendar-event-attendee.service.ts b/packages/twenty-server/src/modules/calendar/services/calendar-event-attendee/calendar-event-attendee.service.ts index 6ffbedbd7..6a5c0f3e2 100644 --- a/packages/twenty-server/src/modules/calendar/services/calendar-event-attendee/calendar-event-attendee.service.ts +++ b/packages/twenty-server/src/modules/calendar/services/calendar-event-attendee/calendar-event-attendee.service.ts @@ -7,7 +7,11 @@ import { PersonRepository } from 'src/modules/person/repositories/person.reposit import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; import { getFlattenedValuesAndValuesStringForBatchRawQuery } from 'src/modules/calendar/utils/getFlattenedValuesAndValuesStringForBatchRawQuery.util'; -import { CalendarEventAttendeeWithId } from 'src/modules/calendar/types/calendar-event'; +import { + CalendarEventAttendee, + CalendarEventAttendeeWithId, +} from 'src/modules/calendar/types/calendar-event'; +import { AddPersonIdAndWorkspaceMemberIdService } from 'src/modules/connected-account/services/add-person-id-and-workspace-member-id/add-person-id-and-workspace-member-id.service'; @Injectable() export class CalendarEventAttendeeService { @@ -15,6 +19,7 @@ export class CalendarEventAttendeeService { private readonly workspaceDataSourceService: WorkspaceDataSourceService, @InjectObjectMetadataRepository(PersonObjectMetadata) private readonly personRepository: PersonRepository, + private readonly addPersonIdAndWorkspaceMemberIdService: AddPersonIdAndWorkspaceMemberIdService, ) {} public async updateCalendarEventAttendeesAfterContactCreation( @@ -62,4 +67,45 @@ export class CalendarEventAttendeeService { transactionManager, ); } + + public async saveCalendarEventAttendees( + calendarEventAttendees: CalendarEventAttendee[], + workspaceId: string, + transactionManager?: EntityManager, + ): Promise { + if (calendarEventAttendees.length === 0) { + return; + } + + const dataSourceSchema = + this.workspaceDataSourceService.getSchemaName(workspaceId); + + const calendarEventAttendeesToSave = + await this.addPersonIdAndWorkspaceMemberIdService.addPersonIdAndWorkspaceMemberId( + calendarEventAttendees, + workspaceId, + transactionManager, + ); + + const { flattenedValues, valuesString } = + getFlattenedValuesAndValuesStringForBatchRawQuery( + calendarEventAttendeesToSave, + { + calendarEventId: 'uuid', + handle: 'text', + displayName: 'text', + isOrganizer: 'boolean', + responseStatus: `${dataSourceSchema}."calendarEventAttendee_responsestatus_enum"`, + personId: 'uuid', + workspaceMemberId: 'uuid', + }, + ); + + await this.workspaceDataSourceService.executeRawQuery( + `INSERT INTO ${dataSourceSchema}."calendarEventAttendee" ("calendarEventId", "handle", "displayName", "isOrganizer", "responseStatus", "personId", "workspaceMemberId") VALUES ${valuesString}`, + flattenedValues, + workspaceId, + transactionManager, + ); + } } diff --git a/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.module.ts b/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.module.ts index c8e5ce076..6b65263ed 100644 --- a/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.module.ts +++ b/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.module.ts @@ -4,6 +4,7 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; +import { CalendarEventAttendeeModule } from 'src/modules/calendar/services/calendar-event-attendee/calendar-event-attendee.module'; import { GoogleCalendarFullSyncService } from 'src/modules/calendar/services/google-calendar-full-sync.service'; import { CalendarProvidersModule } from 'src/modules/calendar/services/providers/calendar-providers.module'; import { CalendarChannelEventAssociationObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-channel-event-association.object-metadata'; @@ -28,6 +29,7 @@ import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/stan PersonObjectMetadata, WorkspaceMemberObjectMetadata, ]), + CalendarEventAttendeeModule, TypeOrmModule.forFeature([FeatureFlagEntity], 'core'), WorkspaceDataSourceModule, ], diff --git a/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.service.ts b/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.service.ts index f0ad984ce..1d7313726 100644 --- a/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.service.ts +++ b/packages/twenty-server/src/modules/calendar/services/google-calendar-full-sync.service.ts @@ -28,6 +28,7 @@ import { CalendarChannelObjectMetadata } from 'src/modules/calendar/standard-obj import { CalendarChannelEventAssociationObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-channel-event-association.object-metadata'; import { CalendarEventAttendeeObjectMetadata } from 'src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata'; import { BlocklistObjectMetadata } from 'src/modules/connected-account/standard-objects/blocklist.object-metadata'; +import { CalendarEventAttendeeService } from 'src/modules/calendar/services/calendar-event-attendee/calendar-event-attendee.service'; @Injectable() export class GoogleCalendarFullSyncService { @@ -55,6 +56,7 @@ export class GoogleCalendarFullSyncService { private readonly featureFlagRepository: Repository, private readonly workspaceDataSourceService: WorkspaceDataSourceService, private readonly eventEmitter: EventEmitter2, + private readonly calendarEventAttendeesService: CalendarEventAttendeeService, ) {} public async startGoogleCalendarFullSync( @@ -265,7 +267,7 @@ export class GoogleCalendarFullSyncService { startTime = Date.now(); - await this.calendarEventAttendeesRepository.saveCalendarEventAttendees( + await this.calendarEventAttendeesService.saveCalendarEventAttendees( attendeesToSave, workspaceId, transactionManager, diff --git a/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata.ts b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata.ts index d36ef72e5..bc9ed11a3 100644 --- a/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata.ts +++ b/packages/twenty-server/src/modules/calendar/standard-objects/calendar-event-attendee.object-metadata.ts @@ -65,6 +65,7 @@ export class CalendarEventAttendeeObjectMetadata extends BaseObjectMetadata { label: 'Is Organizer', description: 'Is Organizer', icon: 'IconUser', + defaultValue: false, }) isOrganizer: boolean; diff --git a/packages/twenty-server/src/modules/connected-account/services/add-person-id-and-workspace-member-id/add-person-id-and-workspace-member-id.module.ts b/packages/twenty-server/src/modules/connected-account/services/add-person-id-and-workspace-member-id/add-person-id-and-workspace-member-id.module.ts new file mode 100644 index 000000000..288f0c797 --- /dev/null +++ b/packages/twenty-server/src/modules/connected-account/services/add-person-id-and-workspace-member-id/add-person-id-and-workspace-member-id.module.ts @@ -0,0 +1,16 @@ +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 { AddPersonIdAndWorkspaceMemberIdService } from 'src/modules/connected-account/services/add-person-id-and-workspace-member-id/add-person-id-and-workspace-member-id.service'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; + +@Module({ + imports: [ + WorkspaceDataSourceModule, + ObjectMetadataRepositoryModule.forFeature([PersonObjectMetadata]), + ], + providers: [AddPersonIdAndWorkspaceMemberIdService], + exports: [AddPersonIdAndWorkspaceMemberIdService], +}) +export class AddPersonIdAndWorkspaceMemberIdModule {} diff --git a/packages/twenty-server/src/modules/connected-account/services/add-person-id-and-workspace-member-id/add-person-id-and-workspace-member-id.service.ts b/packages/twenty-server/src/modules/connected-account/services/add-person-id-and-workspace-member-id/add-person-id-and-workspace-member-id.service.ts new file mode 100644 index 000000000..8aa9a6d95 --- /dev/null +++ b/packages/twenty-server/src/modules/connected-account/services/add-person-id-and-workspace-member-id/add-person-id-and-workspace-member-id.service.ts @@ -0,0 +1,90 @@ +import { Injectable } from '@nestjs/common'; + +import { EntityManager } from 'typeorm'; + +import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator'; +import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; +import { PersonRepository } from 'src/modules/person/repositories/person.repository'; +import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; + +@Injectable() +export class AddPersonIdAndWorkspaceMemberIdService { + constructor( + private readonly workspaceDataSourceService: WorkspaceDataSourceService, + @InjectObjectMetadataRepository(PersonObjectMetadata) + private readonly personRepository: PersonRepository, + ) {} + + private async getEmailPersonIdMap( + handles: string[], + workspaceId: string, + transactionManager?: EntityManager, + ): Promise> { + const personIds = await this.personRepository.getByEmails( + handles, + workspaceId, + transactionManager, + ); + + return new Map(personIds.map((person) => [person.email, person.id])); + } + + private async getEmailWorkspaceMemberIdMap( + handles: string[], + workspaceId: string, + transactionManager?: EntityManager, + ): Promise> { + const dataSourceSchema = + this.workspaceDataSourceService.getSchemaName(workspaceId); + + const workspaceMemberIds: { + id: string; + email: string; + }[] = await this.workspaceDataSourceService.executeRawQuery( + `SELECT "workspaceMember"."id", "connectedAccount"."handle" AS email FROM ${dataSourceSchema}."workspaceMember" + JOIN ${dataSourceSchema}."connectedAccount" ON ${dataSourceSchema}."workspaceMember"."id" = ${dataSourceSchema}."connectedAccount"."accountOwnerId" + WHERE ${dataSourceSchema}."connectedAccount"."handle" = ANY($1)`, + [handles], + workspaceId, + transactionManager, + ); + + return new Map( + workspaceMemberIds.map((workspaceMember) => [ + workspaceMember.email, + workspaceMember.id, + ]), + ); + } + + public async addPersonIdAndWorkspaceMemberId( + objects: T[], + workspaceId: string, + transactionManager?: EntityManager, + ): Promise< + (T & { + personId: string | null; + workspaceMemberId: string | null; + })[] + > { + const handles = objects.map((object) => object.handle); + + const personIdMap = await this.getEmailPersonIdMap( + handles, + workspaceId, + transactionManager, + ); + + const workspaceMemberIdMap = await this.getEmailWorkspaceMemberIdMap( + handles, + workspaceId, + transactionManager, + ); + + return objects.map((object) => ({ + ...object, + personId: personIdMap.get(object.handle) || null, + workspaceMemberId: workspaceMemberIdMap.get(object.handle) || null, + })); + } +} diff --git a/packages/twenty-server/src/modules/messaging/repositories/message-participant.repository.ts b/packages/twenty-server/src/modules/messaging/repositories/message-participant.repository.ts index ae176db29..db7a8fce8 100644 --- a/packages/twenty-server/src/modules/messaging/repositories/message-participant.repository.ts +++ b/packages/twenty-server/src/modules/messaging/repositories/message-participant.repository.ts @@ -5,10 +5,7 @@ import { EntityManager } from 'typeorm'; import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; import { MessageParticipantObjectMetadata } from 'src/modules/messaging/standard-objects/message-participant.object-metadata'; import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record'; -import { - ParticipantWithId, - ParticipantWithMessageId, -} from 'src/modules/messaging/types/gmail-message'; +import { ParticipantWithId } from 'src/modules/messaging/types/gmail-message'; @Injectable() export class MessageParticipantRepository { @@ -126,63 +123,4 @@ export class MessageParticipantRepository { return messageParticipants; } - - public async saveMessageParticipants( - participants: ParticipantWithMessageId[], - workspaceId: string, - transactionManager?: EntityManager, - ): Promise { - if (!participants) return; - - const dataSourceSchema = - this.workspaceDataSourceService.getSchemaName(workspaceId); - - const handles = participants.map((participant) => participant.handle); - - const participantPersonIds = - await this.workspaceDataSourceService.executeRawQuery( - `SELECT id, email FROM ${dataSourceSchema}."person" WHERE "email" = ANY($1)`, - [handles], - workspaceId, - transactionManager, - ); - - const participantWorkspaceMemberIds = - await this.workspaceDataSourceService.executeRawQuery( - `SELECT "workspaceMember"."id", "connectedAccount"."handle" AS email FROM ${dataSourceSchema}."workspaceMember" - JOIN ${dataSourceSchema}."connectedAccount" ON ${dataSourceSchema}."workspaceMember"."id" = ${dataSourceSchema}."connectedAccount"."accountOwnerId" - WHERE ${dataSourceSchema}."connectedAccount"."handle" = ANY($1)`, - [handles], - workspaceId, - transactionManager, - ); - - const messageParticipantsToSave = participants.map((participant) => [ - participant.messageId, - participant.role, - participant.handle, - participant.displayName, - participantPersonIds.find((e) => e.email === participant.handle)?.id, - participantWorkspaceMemberIds.find((e) => e.email === participant.handle) - ?.id, - ]); - - const valuesString = messageParticipantsToSave - .map( - (_, index) => - `($${index * 6 + 1}, $${index * 6 + 2}, $${index * 6 + 3}, $${ - index * 6 + 4 - }, $${index * 6 + 5}, $${index * 6 + 6})`, - ) - .join(', '); - - if (messageParticipantsToSave.length === 0) return; - - await this.workspaceDataSourceService.executeRawQuery( - `INSERT INTO ${dataSourceSchema}."messageParticipant" ("messageId", "role", "handle", "displayName", "personId", "workspaceMemberId") VALUES ${valuesString}`, - messageParticipantsToSave.flat(), - workspaceId, - transactionManager, - ); - } } diff --git a/packages/twenty-server/src/modules/messaging/services/message-participant/message-participant.module.ts b/packages/twenty-server/src/modules/messaging/services/message-participant/message-participant.module.ts index 9491cb305..218dd2912 100644 --- a/packages/twenty-server/src/modules/messaging/services/message-participant/message-participant.module.ts +++ b/packages/twenty-server/src/modules/messaging/services/message-participant/message-participant.module.ts @@ -2,6 +2,7 @@ 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 { AddPersonIdAndWorkspaceMemberIdModule } from 'src/modules/connected-account/services/add-person-id-and-workspace-member-id/add-person-id-and-workspace-member-id.module'; import { MessageParticipantService } from 'src/modules/messaging/services/message-participant/message-participant.service'; import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata'; @@ -9,6 +10,7 @@ import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person imports: [ WorkspaceDataSourceModule, ObjectMetadataRepositoryModule.forFeature([PersonObjectMetadata]), + AddPersonIdAndWorkspaceMemberIdModule, ], providers: [MessageParticipantService], exports: [MessageParticipantService], 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 980fad697..4e09a7e62 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 @@ -3,11 +3,15 @@ import { Injectable } from '@nestjs/common'; 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 { getFlattenedValuesAndValuesStringForBatchRawQuery } from 'src/modules/calendar/utils/getFlattenedValuesAndValuesStringForBatchRawQuery.util'; +import { AddPersonIdAndWorkspaceMemberIdService } from 'src/modules/connected-account/services/add-person-id-and-workspace-member-id/add-person-id-and-workspace-member-id.service'; @Injectable() export class MessageParticipantService { @@ -15,6 +19,7 @@ export class MessageParticipantService { private readonly workspaceDataSourceService: WorkspaceDataSourceService, @InjectObjectMetadataRepository(PersonObjectMetadata) private readonly personRepository: PersonRepository, + private readonly addPersonIdAndWorkspaceMemberIdService: AddPersonIdAndWorkspaceMemberIdService, ) {} public async updateMessageParticipantsAfterPeopleCreation( @@ -62,4 +67,44 @@ export class MessageParticipantService { transactionManager, ); } + + public async saveMessageParticipants( + participants: ParticipantWithMessageId[], + workspaceId: string, + transactionManager?: EntityManager, + ): Promise { + if (!participants) return; + + const dataSourceSchema = + this.workspaceDataSourceService.getSchemaName(workspaceId); + + const messageParticipantsToSave = + await this.addPersonIdAndWorkspaceMemberIdService.addPersonIdAndWorkspaceMemberId( + participants, + workspaceId, + transactionManager, + ); + + const { flattenedValues, valuesString } = + getFlattenedValuesAndValuesStringForBatchRawQuery( + messageParticipantsToSave, + { + messageId: 'uuid', + role: `${dataSourceSchema}."messageParticipant_role_enum"`, + handle: 'text', + displayName: 'text', + personId: 'uuid', + workspaceMemberId: 'uuid', + }, + ); + + if (messageParticipantsToSave.length === 0) return; + + await this.workspaceDataSourceService.executeRawQuery( + `INSERT INTO ${dataSourceSchema}."messageParticipant" ("messageId", "role", "handle", "displayName", "personId", "workspaceMemberId") VALUES ${valuesString}`, + flattenedValues, + workspaceId, + transactionManager, + ); + } } diff --git a/packages/twenty-server/src/modules/messaging/services/save-message-and-emit-contact-creation-event/save-message-and-emit-contact-creation-event.module.ts b/packages/twenty-server/src/modules/messaging/services/save-message-and-emit-contact-creation-event/save-message-and-emit-contact-creation-event.module.ts index 647009a4c..22740ba9c 100644 --- a/packages/twenty-server/src/modules/messaging/services/save-message-and-emit-contact-creation-event/save-message-and-emit-contact-creation-event.module.ts +++ b/packages/twenty-server/src/modules/messaging/services/save-message-and-emit-contact-creation-event/save-message-and-emit-contact-creation-event.module.ts @@ -7,15 +7,11 @@ import { MessageParticipantModule } from 'src/modules/messaging/services/message import { MessageModule } from 'src/modules/messaging/services/message/message.module'; import { SaveMessageAndEmitContactCreationEventService } from 'src/modules/messaging/services/save-message-and-emit-contact-creation-event/save-message-and-emit-contact-creation-event.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, - ]), + ObjectMetadataRepositoryModule.forFeature([MessageChannelObjectMetadata]), AutoCompaniesAndContactsCreationModule, MessageParticipantModule, WorkspaceDataSourceModule, diff --git a/packages/twenty-server/src/modules/messaging/services/save-message-and-emit-contact-creation-event/save-message-and-emit-contact-creation-event.service.ts b/packages/twenty-server/src/modules/messaging/services/save-message-and-emit-contact-creation-event/save-message-and-emit-contact-creation-event.service.ts index 0576fce71..8a609b108 100644 --- a/packages/twenty-server/src/modules/messaging/services/save-message-and-emit-contact-creation-event/save-message-and-emit-contact-creation-event.service.ts +++ b/packages/twenty-server/src/modules/messaging/services/save-message-and-emit-contact-creation-event/save-message-and-emit-contact-creation-event.service.ts @@ -4,7 +4,6 @@ import { EventEmitter2 } from '@nestjs/event-emitter'; import { EntityManager } from 'typeorm'; import { MessageChannelRepository } from 'src/modules/messaging/repositories/message-channel.repository'; -import { MessageParticipantRepository } from 'src/modules/messaging/repositories/message-participant.repository'; import { GmailMessage, ParticipantWithMessageId, @@ -15,7 +14,7 @@ import { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metada 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'; +import { MessageParticipantService } from 'src/modules/messaging/services/message-participant/message-participant.service'; @Injectable() export class SaveMessageAndEmitContactCreationEventService { @@ -27,10 +26,9 @@ export class SaveMessageAndEmitContactCreationEventService { private readonly messageService: MessageService, @InjectObjectMetadataRepository(MessageChannelObjectMetadata) private readonly messageChannelRepository: MessageChannelRepository, - @InjectObjectMetadataRepository(MessageParticipantObjectMetadata) - private readonly messageParticipantRepository: MessageParticipantRepository, private readonly eventEmitter: EventEmitter2, private readonly workspaceDataSourceService: WorkspaceDataSourceService, + private readonly messageParticipantService: MessageParticipantService, ) {} public async saveMessagesAndEmitContactCreationEventWithinTransaction( @@ -66,7 +64,7 @@ export class SaveMessageAndEmitContactCreationEventService { : []; }); - await this.messageParticipantRepository.saveMessageParticipants( + await this.messageParticipantService.saveMessageParticipants( participantsWithMessageId, workspaceId, transactionManager, @@ -172,7 +170,7 @@ export class SaveMessageAndEmitContactCreationEventService { connectedAccount: ObjectRecord, ) { try { - await this.messageParticipantRepository.saveMessageParticipants( + await this.messageParticipantService.saveMessageParticipants( participantsWithMessageId, workspaceId, );