3938 change email auto import to contact ive sent email to (#3995)
* done * working * wip * merge main * almost done * improvement
This commit is contained in:
@ -43,7 +43,7 @@ export class CreateCompaniesAndContactsAfterSyncJob
|
|||||||
}
|
}
|
||||||
|
|
||||||
const messageParticipantsWithoutPersonIdAndWorkspaceMemberId =
|
const messageParticipantsWithoutPersonIdAndWorkspaceMemberId =
|
||||||
await this.messageParticipantService.getByMessageChannelIdWithoutPersonIdAndWorkspaceMemberId(
|
await this.messageParticipantService.getByMessageChannelIdWithoutPersonIdAndWorkspaceMemberIdAndMessageOutgoing(
|
||||||
messageChannelId,
|
messageChannelId,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { CreateCompaniesAndContactsModule } from 'src/workspace/messaging/services/create-companies-and-contacts/create-companies-and-contacts.module';
|
|
||||||
import { MessageParticipantService } from 'src/workspace/messaging/repositories/message-participant/message-participant.service';
|
import { MessageParticipantService } from 'src/workspace/messaging/repositories/message-participant/message-participant.service';
|
||||||
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
||||||
|
import { PersonModule } from 'src/workspace/messaging/repositories/person/person.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [WorkspaceDataSourceModule, CreateCompaniesAndContactsModule],
|
imports: [WorkspaceDataSourceModule, PersonModule],
|
||||||
providers: [MessageParticipantService],
|
providers: [MessageParticipantService],
|
||||||
exports: [MessageParticipantService],
|
exports: [MessageParticipantService],
|
||||||
})
|
})
|
||||||
|
|||||||
@ -9,11 +9,13 @@ import {
|
|||||||
ParticipantWithId,
|
ParticipantWithId,
|
||||||
Participant,
|
Participant,
|
||||||
} from 'src/workspace/messaging/types/gmail-message';
|
} from 'src/workspace/messaging/types/gmail-message';
|
||||||
|
import { PersonService } from 'src/workspace/messaging/repositories/person/person.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MessageParticipantService {
|
export class MessageParticipantService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
||||||
|
private readonly personService: PersonService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public async getByHandles(
|
public async getByHandles(
|
||||||
@ -66,7 +68,7 @@ export class MessageParticipantService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getByMessageChannelIdWithoutPersonIdAndWorkspaceMemberId(
|
public async getByMessageChannelIdWithoutPersonIdAndWorkspaceMemberIdAndMessageOutgoing(
|
||||||
messageChannelId: string,
|
messageChannelId: string,
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
transactionManager?: EntityManager,
|
transactionManager?: EntityManager,
|
||||||
@ -88,11 +90,12 @@ export class MessageParticipantService {
|
|||||||
"messageParticipant"."workspaceMemberId",
|
"messageParticipant"."workspaceMemberId",
|
||||||
"messageParticipant"."messageId"
|
"messageParticipant"."messageId"
|
||||||
FROM ${dataSourceSchema}."messageParticipant" "messageParticipant"
|
FROM ${dataSourceSchema}."messageParticipant" "messageParticipant"
|
||||||
LEFT JOIN ${dataSourceSchema}."message" ON "messageParticipant"."messageId" = ${dataSourceSchema}."message"."id"
|
LEFT JOIN ${dataSourceSchema}."message" ON "messageParticipant"."messageId" = ${dataSourceSchema}."message"."id"
|
||||||
LEFT JOIN ${dataSourceSchema}."messageChannelMessageAssociation" ON ${dataSourceSchema}."messageChannelMessageAssociation"."messageId" = ${dataSourceSchema}."message"."id"
|
LEFT JOIN ${dataSourceSchema}."messageChannelMessageAssociation" ON ${dataSourceSchema}."messageChannelMessageAssociation"."messageId" = ${dataSourceSchema}."message"."id"
|
||||||
WHERE ${dataSourceSchema}."messageChannelMessageAssociation"."messageChannelId" = $1
|
WHERE ${dataSourceSchema}."messageChannelMessageAssociation"."messageChannelId" = $1
|
||||||
AND "messageParticipant"."personId" IS NULL
|
AND "messageParticipant"."personId" IS NULL
|
||||||
AND "messageParticipant"."workspaceMemberId" IS NULL`,
|
AND "messageParticipant"."workspaceMemberId" IS NULL
|
||||||
|
AND ${dataSourceSchema}."message"."direction" = 'outgoing'`,
|
||||||
[messageChannelId],
|
[messageChannelId],
|
||||||
workspaceId,
|
workspaceId,
|
||||||
transactionManager,
|
transactionManager,
|
||||||
@ -101,6 +104,39 @@ export class MessageParticipantService {
|
|||||||
return messageParticipants;
|
return messageParticipants;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getByHandlesWithoutPersonIdAndWorkspaceMemberId(
|
||||||
|
handles: string[],
|
||||||
|
workspaceId: string,
|
||||||
|
transactionManager?: EntityManager,
|
||||||
|
): Promise<ParticipantWithId[]> {
|
||||||
|
if (!workspaceId) {
|
||||||
|
throw new Error('WorkspaceId is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
const dataSourceSchema =
|
||||||
|
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||||
|
|
||||||
|
const messageParticipants: ParticipantWithId[] =
|
||||||
|
await this.workspaceDataSourceService.executeRawQuery(
|
||||||
|
`SELECT "messageParticipant".id,
|
||||||
|
"messageParticipant"."role",
|
||||||
|
"messageParticipant"."handle",
|
||||||
|
"messageParticipant"."displayName",
|
||||||
|
"messageParticipant"."personId",
|
||||||
|
"messageParticipant"."workspaceMemberId",
|
||||||
|
"messageParticipant"."messageId"
|
||||||
|
FROM ${dataSourceSchema}."messageParticipant" "messageParticipant"
|
||||||
|
WHERE "messageParticipant"."personId" IS NULL
|
||||||
|
AND "messageParticipant"."workspaceMemberId" IS NULL
|
||||||
|
AND "messageParticipant"."handle" = ANY($1)`,
|
||||||
|
[handles],
|
||||||
|
workspaceId,
|
||||||
|
transactionManager,
|
||||||
|
);
|
||||||
|
|
||||||
|
return messageParticipants;
|
||||||
|
}
|
||||||
|
|
||||||
public async saveMessageParticipants(
|
public async saveMessageParticipants(
|
||||||
participants: Participant[],
|
participants: Participant[],
|
||||||
messageId: string,
|
messageId: string,
|
||||||
@ -173,13 +209,11 @@ export class MessageParticipantService {
|
|||||||
|
|
||||||
const handles = participants.map((participant) => participant.handle);
|
const handles = participants.map((participant) => participant.handle);
|
||||||
|
|
||||||
const participantPersonIds =
|
const participantPersonIds = await this.personService.getByEmails(
|
||||||
await this.workspaceDataSourceService.executeRawQuery(
|
handles,
|
||||||
`SELECT id, email FROM ${dataSourceSchema}."person" WHERE "email" = ANY($1)`,
|
workspaceId,
|
||||||
[handles],
|
transactionManager,
|
||||||
workspaceId,
|
);
|
||||||
transactionManager,
|
|
||||||
);
|
|
||||||
|
|
||||||
const messageParticipantsToUpdate = participants.map((participant) => [
|
const messageParticipantsToUpdate = participants.map((participant) => [
|
||||||
participant.id,
|
participant.id,
|
||||||
|
|||||||
@ -203,12 +203,28 @@ export class MessageService {
|
|||||||
workspaceId,
|
workspaceId,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isContactAutoCreationEnabled) {
|
if (isContactAutoCreationEnabled && messageDirection === 'outgoing') {
|
||||||
await this.createCompaniesAndContactsService.createCompaniesAndContacts(
|
await this.createCompaniesAndContactsService.createCompaniesAndContacts(
|
||||||
message.participants,
|
message.participants,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
manager,
|
manager,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handles = message.participants.map(
|
||||||
|
(participant) => participant.handle,
|
||||||
|
);
|
||||||
|
|
||||||
|
const messageParticipantsWithoutPersonIdAndWorkspaceMemberId =
|
||||||
|
await this.messageParticipantService.getByHandlesWithoutPersonIdAndWorkspaceMemberId(
|
||||||
|
handles,
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.messageParticipantService.updateMessageParticipantsAfterPeopleCreation(
|
||||||
|
messageParticipantsWithoutPersonIdAndWorkspaceMemberId,
|
||||||
|
workspaceId,
|
||||||
|
manager,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.messageParticipantService.saveMessageParticipants(
|
await this.messageParticipantService.saveMessageParticipants(
|
||||||
|
|||||||
@ -3,6 +3,8 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { EntityManager } from 'typeorm';
|
import { EntityManager } from 'typeorm';
|
||||||
|
|
||||||
import { WorkspaceDataSourceService } from 'src/workspace/workspace-datasource/workspace-datasource.service';
|
import { WorkspaceDataSourceService } from 'src/workspace/workspace-datasource/workspace-datasource.service';
|
||||||
|
import { ObjectRecord } from 'src/workspace/workspace-sync-metadata/types/object-record';
|
||||||
|
import { PersonObjectMetadata } from 'src/workspace/workspace-sync-metadata/standard-objects/person.object-metadata';
|
||||||
|
|
||||||
// TODO: Move outside of the messaging module
|
// TODO: Move outside of the messaging module
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -11,6 +13,22 @@ export class PersonService {
|
|||||||
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
async getByEmails(
|
||||||
|
emails: string[],
|
||||||
|
workspaceId: string,
|
||||||
|
transactionManager?: EntityManager,
|
||||||
|
): Promise<ObjectRecord<PersonObjectMetadata>[]> {
|
||||||
|
const dataSourceSchema =
|
||||||
|
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||||
|
|
||||||
|
return await this.workspaceDataSourceService.executeRawQuery(
|
||||||
|
`SELECT * FROM ${dataSourceSchema}.person WHERE email = ANY($1)`,
|
||||||
|
[emails],
|
||||||
|
workspaceId,
|
||||||
|
transactionManager,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
async createPeople(
|
async createPeople(
|
||||||
peopleToCreate: {
|
peopleToCreate: {
|
||||||
id: string;
|
id: string;
|
||||||
|
|||||||
@ -24,10 +24,22 @@ export class CreateCompaniesAndContactsService {
|
|||||||
const dataSourceSchema =
|
const dataSourceSchema =
|
||||||
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||||
|
|
||||||
|
const uniqueHandles = Array.from(
|
||||||
|
new Set(participants.map((participant) => participant.handle)),
|
||||||
|
);
|
||||||
|
|
||||||
|
const uniqueParticipants = uniqueHandles.map((handle) => {
|
||||||
|
const participant = participants.find(
|
||||||
|
(participant) => participant.handle === handle,
|
||||||
|
);
|
||||||
|
|
||||||
|
return participant;
|
||||||
|
}) as Participant[];
|
||||||
|
|
||||||
const alreadyCreatedContacts =
|
const alreadyCreatedContacts =
|
||||||
await this.workspaceDataSourceService.executeRawQuery(
|
await this.workspaceDataSourceService.executeRawQuery(
|
||||||
`SELECT email FROM ${dataSourceSchema}."person" WHERE "email" = ANY($1)`,
|
`SELECT email FROM ${dataSourceSchema}."person" WHERE "email" = ANY($1)`,
|
||||||
[participants.map((participant) => participant.handle)],
|
[uniqueParticipants.map((participant) => participant.handle)],
|
||||||
workspaceId,
|
workspaceId,
|
||||||
transactionManager,
|
transactionManager,
|
||||||
);
|
);
|
||||||
@ -36,7 +48,7 @@ export class CreateCompaniesAndContactsService {
|
|||||||
({ email }) => email,
|
({ email }) => email,
|
||||||
);
|
);
|
||||||
|
|
||||||
const filteredParticipants = participants.filter(
|
const filteredParticipants = uniqueParticipants.filter(
|
||||||
(participant) =>
|
(participant) =>
|
||||||
!alreadyCreatedContactEmails.includes(participant.handle) &&
|
!alreadyCreatedContactEmails.includes(participant.handle) &&
|
||||||
participant.handle.includes('@'),
|
participant.handle.includes('@'),
|
||||||
|
|||||||
Reference in New Issue
Block a user