4008 dont create a contact company if it matches the persons domain (#4057)

* Add SettingsAccountsEmailsBlocklistInput story

* prevent contact creation from the same company

* add todo

* improvements

* Delete packages/twenty-front/src/modules/settings/accounts/components/__stories__/SettingsAccountsEmailsBlocklistInput.stories.tsx

* refactor

* modify after review

* improve code
This commit is contained in:
bosiraphael
2024-02-19 18:46:49 +01:00
committed by GitHub
parent e34e341ddc
commit 09783912f3
5 changed files with 32 additions and 35 deletions

View File

@ -32,11 +32,12 @@ export class CreateCompaniesAndContactsAfterSyncJob
);
const { workspaceId, messageChannelId } = data;
const isContactAutoCreationEnabled =
await this.messageChannelService.getIsContactAutoCreationEnabledByMessageChannelId(
messageChannelId,
workspaceId,
);
const messageChannel = await this.messageChannelService.getByIds(
[messageChannelId],
workspaceId,
);
const { handle, isContactAutoCreationEnabled } = messageChannel[0];
if (!isContactAutoCreationEnabled) {
return;
@ -49,6 +50,7 @@ export class CreateCompaniesAndContactsAfterSyncJob
);
await this.createCompaniesAndContactsService.createCompaniesAndContacts(
handle,
messageParticipantsWithoutPersonIdAndWorkspaceMemberId,
workspaceId,
);

View File

@ -56,23 +56,6 @@ export class MessageChannelService {
return messageChannel.isContactAutoCreationEnabled;
}
public async getIsContactAutoCreationEnabledByMessageChannelId(
messageChannelId: string,
workspaceId: string,
): Promise<boolean> {
const dataSourceSchema =
this.workspaceDataSourceService.getSchemaName(workspaceId);
const messageChannels =
await this.workspaceDataSourceService.executeRawQuery(
`SELECT * FROM ${dataSourceSchema}."messageChannel" WHERE "id" = $1 LIMIT 1`,
[messageChannelId],
workspaceId,
);
return messageChannels[0]?.isContactAutoCreationEnabled;
}
public async getByIds(
ids: string[],
workspaceId: string,

View File

@ -205,6 +205,7 @@ export class MessageService {
if (isContactAutoCreationEnabled && messageDirection === 'outgoing') {
await this.createCompaniesAndContactsService.createCompaniesAndContacts(
connectedAccount.handle,
message.participants,
workspaceId,
manager,

View File

@ -1,5 +1,6 @@
import { Module } from '@nestjs/common';
import { PersonModule } from 'src/workspace/messaging/repositories/person/person.module';
import { CreateCompaniesAndContactsService } from 'src/workspace/messaging/services/create-companies-and-contacts/create-companies-and-contacts.service';
import { CreateCompanyModule } from 'src/workspace/messaging/services/create-company/create-company.module';
import { CreateContactModule } from 'src/workspace/messaging/services/create-contact/create-contact.module';
@ -10,6 +11,7 @@ import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/wo
WorkspaceDataSourceModule,
CreateContactModule,
CreateCompanyModule,
PersonModule,
],
providers: [CreateCompaniesAndContactsService],
exports: [CreateCompaniesAndContactsService],

View File

@ -2,47 +2,56 @@ import { Injectable } from '@nestjs/common';
import { EntityManager } from 'typeorm';
import { WorkspaceDataSourceService } from 'src/workspace/workspace-datasource/workspace-datasource.service';
import { Participant } from 'src/workspace/messaging/types/gmail-message';
import { getDomainNameFromHandle } from 'src/workspace/messaging/utils/get-domain-name-from-handle.util';
import { CreateCompanyService } from 'src/workspace/messaging/services/create-company/create-company.service';
import { CreateContactService } from 'src/workspace/messaging/services/create-contact/create-contact.service';
import { PersonService } from 'src/workspace/messaging/repositories/person/person.service';
@Injectable()
export class CreateCompaniesAndContactsService {
constructor(
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
private readonly personService: PersonService,
private readonly createContactService: CreateContactService,
private readonly createCompaniesService: CreateCompanyService,
) {}
async createCompaniesAndContacts(
selfHandle: string,
participants: Participant[],
workspaceId: string,
transactionManager?: EntityManager,
) {
const dataSourceSchema =
this.workspaceDataSourceService.getSchemaName(workspaceId);
const selfDomainName = getDomainNameFromHandle(selfHandle);
// TODO: use isWorkEmail so we can create a contact even if the email is a personal email
const participantsFromOtherCompanies = participants.filter(
(participant) =>
getDomainNameFromHandle(participant.handle) !== selfDomainName,
);
if (!participantsFromOtherCompanies.length) {
return;
}
const uniqueHandles = Array.from(
new Set(participants.map((participant) => participant.handle)),
new Set(
participantsFromOtherCompanies.map((participant) => participant.handle),
),
);
const uniqueParticipants = uniqueHandles.map((handle) => {
const participant = participants.find(
const participant = participantsFromOtherCompanies.find(
(participant) => participant.handle === handle,
);
return participant;
}) as Participant[];
const alreadyCreatedContacts =
await this.workspaceDataSourceService.executeRawQuery(
`SELECT email FROM ${dataSourceSchema}."person" WHERE "email" = ANY($1)`,
[uniqueParticipants.map((participant) => participant.handle)],
workspaceId,
transactionManager,
);
const alreadyCreatedContacts = await this.personService.getByEmails(
uniqueHandles,
workspaceId,
);
const alreadyCreatedContactEmails: string[] = alreadyCreatedContacts?.map(
({ email }) => email,