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
This commit is contained in:
@ -214,8 +214,7 @@ export class TimelineCalendarEventService {
|
|||||||
event.description = '';
|
event.description = '';
|
||||||
event.location = '';
|
event.location = '';
|
||||||
event.conferenceSolution = '';
|
event.conferenceSolution = '';
|
||||||
event.conferenceLink.label = '';
|
event.conferenceLink = { label: '', url: '' };
|
||||||
event.conferenceLink.url = '';
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import { MessageQueueDriver } from './interfaces/message-queue-driver.interface'
|
|||||||
|
|
||||||
export type PgBossDriverOptions = PgBoss.ConstructorOptions;
|
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 {
|
export class PgBossDriver implements MessageQueueDriver {
|
||||||
private pgBoss: PgBoss;
|
private pgBoss: PgBoss;
|
||||||
|
|||||||
@ -78,38 +78,6 @@ export class CalendarEventAttendeeRepository {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async saveCalendarEventAttendees(
|
|
||||||
calendarEventAttendees: CalendarEventAttendee[],
|
|
||||||
workspaceId: string,
|
|
||||||
transactionManager?: EntityManager,
|
|
||||||
): Promise<void> {
|
|
||||||
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(
|
public async updateCalendarEventAttendees(
|
||||||
calendarEventAttendees: CalendarEventAttendee[],
|
calendarEventAttendees: CalendarEventAttendee[],
|
||||||
iCalUIDCalendarEventIdMap: Map<string, string>,
|
iCalUIDCalendarEventIdMap: Map<string, string>,
|
||||||
|
|||||||
@ -3,12 +3,14 @@ import { Module } from '@nestjs/common';
|
|||||||
import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module';
|
import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module';
|
||||||
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.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 { 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';
|
import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
WorkspaceDataSourceModule,
|
WorkspaceDataSourceModule,
|
||||||
ObjectMetadataRepositoryModule.forFeature([PersonObjectMetadata]),
|
ObjectMetadataRepositoryModule.forFeature([PersonObjectMetadata]),
|
||||||
|
AddPersonIdAndWorkspaceMemberIdModule,
|
||||||
],
|
],
|
||||||
providers: [CalendarEventAttendeeService],
|
providers: [CalendarEventAttendeeService],
|
||||||
exports: [CalendarEventAttendeeService],
|
exports: [CalendarEventAttendeeService],
|
||||||
|
|||||||
@ -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 { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata';
|
||||||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||||
import { getFlattenedValuesAndValuesStringForBatchRawQuery } from 'src/modules/calendar/utils/getFlattenedValuesAndValuesStringForBatchRawQuery.util';
|
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()
|
@Injectable()
|
||||||
export class CalendarEventAttendeeService {
|
export class CalendarEventAttendeeService {
|
||||||
@ -15,6 +19,7 @@ export class CalendarEventAttendeeService {
|
|||||||
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
||||||
@InjectObjectMetadataRepository(PersonObjectMetadata)
|
@InjectObjectMetadataRepository(PersonObjectMetadata)
|
||||||
private readonly personRepository: PersonRepository,
|
private readonly personRepository: PersonRepository,
|
||||||
|
private readonly addPersonIdAndWorkspaceMemberIdService: AddPersonIdAndWorkspaceMemberIdService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public async updateCalendarEventAttendeesAfterContactCreation(
|
public async updateCalendarEventAttendeesAfterContactCreation(
|
||||||
@ -62,4 +67,45 @@ export class CalendarEventAttendeeService {
|
|||||||
transactionManager,
|
transactionManager,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async saveCalendarEventAttendees(
|
||||||
|
calendarEventAttendees: CalendarEventAttendee[],
|
||||||
|
workspaceId: string,
|
||||||
|
transactionManager?: EntityManager,
|
||||||
|
): Promise<void> {
|
||||||
|
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,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { TypeOrmModule } from '@nestjs/typeorm';
|
|||||||
import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
|
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 { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module';
|
||||||
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.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 { GoogleCalendarFullSyncService } from 'src/modules/calendar/services/google-calendar-full-sync.service';
|
||||||
import { CalendarProvidersModule } from 'src/modules/calendar/services/providers/calendar-providers.module';
|
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';
|
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,
|
PersonObjectMetadata,
|
||||||
WorkspaceMemberObjectMetadata,
|
WorkspaceMemberObjectMetadata,
|
||||||
]),
|
]),
|
||||||
|
CalendarEventAttendeeModule,
|
||||||
TypeOrmModule.forFeature([FeatureFlagEntity], 'core'),
|
TypeOrmModule.forFeature([FeatureFlagEntity], 'core'),
|
||||||
WorkspaceDataSourceModule,
|
WorkspaceDataSourceModule,
|
||||||
],
|
],
|
||||||
|
|||||||
@ -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 { 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 { 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 { 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()
|
@Injectable()
|
||||||
export class GoogleCalendarFullSyncService {
|
export class GoogleCalendarFullSyncService {
|
||||||
@ -55,6 +56,7 @@ export class GoogleCalendarFullSyncService {
|
|||||||
private readonly featureFlagRepository: Repository<FeatureFlagEntity>,
|
private readonly featureFlagRepository: Repository<FeatureFlagEntity>,
|
||||||
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
||||||
private readonly eventEmitter: EventEmitter2,
|
private readonly eventEmitter: EventEmitter2,
|
||||||
|
private readonly calendarEventAttendeesService: CalendarEventAttendeeService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public async startGoogleCalendarFullSync(
|
public async startGoogleCalendarFullSync(
|
||||||
@ -265,7 +267,7 @@ export class GoogleCalendarFullSyncService {
|
|||||||
|
|
||||||
startTime = Date.now();
|
startTime = Date.now();
|
||||||
|
|
||||||
await this.calendarEventAttendeesRepository.saveCalendarEventAttendees(
|
await this.calendarEventAttendeesService.saveCalendarEventAttendees(
|
||||||
attendeesToSave,
|
attendeesToSave,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
transactionManager,
|
transactionManager,
|
||||||
|
|||||||
@ -65,6 +65,7 @@ export class CalendarEventAttendeeObjectMetadata extends BaseObjectMetadata {
|
|||||||
label: 'Is Organizer',
|
label: 'Is Organizer',
|
||||||
description: 'Is Organizer',
|
description: 'Is Organizer',
|
||||||
icon: 'IconUser',
|
icon: 'IconUser',
|
||||||
|
defaultValue: false,
|
||||||
})
|
})
|
||||||
isOrganizer: boolean;
|
isOrganizer: boolean;
|
||||||
|
|
||||||
|
|||||||
@ -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 {}
|
||||||
@ -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<Map<string, string>> {
|
||||||
|
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<Map<string, string>> {
|
||||||
|
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<T extends { handle: string }>(
|
||||||
|
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,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,10 +5,7 @@ import { EntityManager } from 'typeorm';
|
|||||||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||||
import { MessageParticipantObjectMetadata } from 'src/modules/messaging/standard-objects/message-participant.object-metadata';
|
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 { ObjectRecord } from 'src/engine/workspace-manager/workspace-sync-metadata/types/object-record';
|
||||||
import {
|
import { ParticipantWithId } from 'src/modules/messaging/types/gmail-message';
|
||||||
ParticipantWithId,
|
|
||||||
ParticipantWithMessageId,
|
|
||||||
} from 'src/modules/messaging/types/gmail-message';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MessageParticipantRepository {
|
export class MessageParticipantRepository {
|
||||||
@ -126,63 +123,4 @@ export class MessageParticipantRepository {
|
|||||||
|
|
||||||
return messageParticipants;
|
return messageParticipants;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async saveMessageParticipants(
|
|
||||||
participants: ParticipantWithMessageId[],
|
|
||||||
workspaceId: string,
|
|
||||||
transactionManager?: EntityManager,
|
|
||||||
): Promise<void> {
|
|
||||||
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,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { Module } from '@nestjs/common';
|
|||||||
|
|
||||||
import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module';
|
import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module';
|
||||||
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.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 { MessageParticipantService } from 'src/modules/messaging/services/message-participant/message-participant.service';
|
||||||
import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata';
|
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: [
|
imports: [
|
||||||
WorkspaceDataSourceModule,
|
WorkspaceDataSourceModule,
|
||||||
ObjectMetadataRepositoryModule.forFeature([PersonObjectMetadata]),
|
ObjectMetadataRepositoryModule.forFeature([PersonObjectMetadata]),
|
||||||
|
AddPersonIdAndWorkspaceMemberIdModule,
|
||||||
],
|
],
|
||||||
providers: [MessageParticipantService],
|
providers: [MessageParticipantService],
|
||||||
exports: [MessageParticipantService],
|
exports: [MessageParticipantService],
|
||||||
|
|||||||
@ -3,11 +3,15 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { EntityManager } from 'typeorm';
|
import { EntityManager } from 'typeorm';
|
||||||
|
|
||||||
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
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 { PersonRepository } from 'src/modules/person/repositories/person.repository';
|
||||||
import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata';
|
import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata';
|
||||||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||||
import { getFlattenedValuesAndValuesStringForBatchRawQuery } from 'src/modules/calendar/utils/getFlattenedValuesAndValuesStringForBatchRawQuery.util';
|
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()
|
@Injectable()
|
||||||
export class MessageParticipantService {
|
export class MessageParticipantService {
|
||||||
@ -15,6 +19,7 @@ export class MessageParticipantService {
|
|||||||
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
||||||
@InjectObjectMetadataRepository(PersonObjectMetadata)
|
@InjectObjectMetadataRepository(PersonObjectMetadata)
|
||||||
private readonly personRepository: PersonRepository,
|
private readonly personRepository: PersonRepository,
|
||||||
|
private readonly addPersonIdAndWorkspaceMemberIdService: AddPersonIdAndWorkspaceMemberIdService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public async updateMessageParticipantsAfterPeopleCreation(
|
public async updateMessageParticipantsAfterPeopleCreation(
|
||||||
@ -62,4 +67,44 @@ export class MessageParticipantService {
|
|||||||
transactionManager,
|
transactionManager,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async saveMessageParticipants(
|
||||||
|
participants: ParticipantWithMessageId[],
|
||||||
|
workspaceId: string,
|
||||||
|
transactionManager?: EntityManager,
|
||||||
|
): Promise<void> {
|
||||||
|
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,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,15 +7,11 @@ import { MessageParticipantModule } from 'src/modules/messaging/services/message
|
|||||||
import { MessageModule } from 'src/modules/messaging/services/message/message.module';
|
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 { 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 { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata';
|
||||||
import { MessageParticipantObjectMetadata } from 'src/modules/messaging/standard-objects/message-participant.object-metadata';
|
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
MessageModule,
|
MessageModule,
|
||||||
ObjectMetadataRepositoryModule.forFeature([
|
ObjectMetadataRepositoryModule.forFeature([MessageChannelObjectMetadata]),
|
||||||
MessageChannelObjectMetadata,
|
|
||||||
MessageParticipantObjectMetadata,
|
|
||||||
]),
|
|
||||||
AutoCompaniesAndContactsCreationModule,
|
AutoCompaniesAndContactsCreationModule,
|
||||||
MessageParticipantModule,
|
MessageParticipantModule,
|
||||||
WorkspaceDataSourceModule,
|
WorkspaceDataSourceModule,
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import { EventEmitter2 } from '@nestjs/event-emitter';
|
|||||||
import { EntityManager } from 'typeorm';
|
import { EntityManager } from 'typeorm';
|
||||||
|
|
||||||
import { MessageChannelRepository } from 'src/modules/messaging/repositories/message-channel.repository';
|
import { MessageChannelRepository } from 'src/modules/messaging/repositories/message-channel.repository';
|
||||||
import { MessageParticipantRepository } from 'src/modules/messaging/repositories/message-participant.repository';
|
|
||||||
import {
|
import {
|
||||||
GmailMessage,
|
GmailMessage,
|
||||||
ParticipantWithMessageId,
|
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 { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
||||||
import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata';
|
import { MessageChannelObjectMetadata } from 'src/modules/messaging/standard-objects/message-channel.object-metadata';
|
||||||
import { MessageService } from 'src/modules/messaging/services/message/message.service';
|
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()
|
@Injectable()
|
||||||
export class SaveMessageAndEmitContactCreationEventService {
|
export class SaveMessageAndEmitContactCreationEventService {
|
||||||
@ -27,10 +26,9 @@ export class SaveMessageAndEmitContactCreationEventService {
|
|||||||
private readonly messageService: MessageService,
|
private readonly messageService: MessageService,
|
||||||
@InjectObjectMetadataRepository(MessageChannelObjectMetadata)
|
@InjectObjectMetadataRepository(MessageChannelObjectMetadata)
|
||||||
private readonly messageChannelRepository: MessageChannelRepository,
|
private readonly messageChannelRepository: MessageChannelRepository,
|
||||||
@InjectObjectMetadataRepository(MessageParticipantObjectMetadata)
|
|
||||||
private readonly messageParticipantRepository: MessageParticipantRepository,
|
|
||||||
private readonly eventEmitter: EventEmitter2,
|
private readonly eventEmitter: EventEmitter2,
|
||||||
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
||||||
|
private readonly messageParticipantService: MessageParticipantService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public async saveMessagesAndEmitContactCreationEventWithinTransaction(
|
public async saveMessagesAndEmitContactCreationEventWithinTransaction(
|
||||||
@ -66,7 +64,7 @@ export class SaveMessageAndEmitContactCreationEventService {
|
|||||||
: [];
|
: [];
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.messageParticipantRepository.saveMessageParticipants(
|
await this.messageParticipantService.saveMessageParticipants(
|
||||||
participantsWithMessageId,
|
participantsWithMessageId,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
transactionManager,
|
transactionManager,
|
||||||
@ -172,7 +170,7 @@ export class SaveMessageAndEmitContactCreationEventService {
|
|||||||
connectedAccount: ObjectRecord<ConnectedAccountObjectMetadata>,
|
connectedAccount: ObjectRecord<ConnectedAccountObjectMetadata>,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
await this.messageParticipantRepository.saveMessageParticipants(
|
await this.messageParticipantService.saveMessageParticipants(
|
||||||
participantsWithMessageId,
|
participantsWithMessageId,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user