Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce a new feature flag for contact creation #5570

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ export const seedFeatureFlags = async (
workspaceId: workspaceId,
value: true,
},
{
key: FeatureFlagKeys.IsContactCreationForSentAndReceivedEmailsEnabled,
workspaceId: workspaceId,
value: true,
},
])
.execute();
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export enum FeatureFlagKeys {
IsStripeIntegrationEnabled = 'IS_STRIPE_INTEGRATION_ENABLED',
IsGmailSyncV2Enabled = 'IS_GMAIL_SYNC_V2_ENABLED',
IsLinksFieldEnabled = 'IS_LINKS_FIELD_ENABLED',
IsContactCreationForSentAndReceivedEmailsEnabled = 'IS_CONTACT_CREATION_FOR_SENT_AND_RECEIVED_EMAILS_ENABLED',
}

@Entity({ name: 'featureFlag', schema: 'core' })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export class AddStandardIdCommand extends CommandRunner {
IS_STRIPE_INTEGRATION_ENABLED: false,
IS_GMAIL_SYNC_V2_ENABLED: true,
IS_LINKS_FIELD_ENABLED: true,
IS_CONTACT_CREATION_FOR_SENT_AND_RECEIVED_EMAILS_ENABLED: true,
},
);
const standardFieldMetadataCollection = this.standardFieldFactory.create(
Expand All @@ -76,6 +77,7 @@ export class AddStandardIdCommand extends CommandRunner {
IS_STRIPE_INTEGRATION_ENABLED: false,
IS_GMAIL_SYNC_V2_ENABLED: true,
IS_LINKS_FIELD_ENABLED: true,
IS_CONTACT_CREATION_FOR_SENT_AND_RECEIVED_EMAILS_ENABLED: true,
},
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';

import { Repository } from 'typeorm';

import { MessageQueueJob } from 'src/engine/integrations/message-queue/interfaces/message-queue-job.interface';

import {
FeatureFlagEntity,
FeatureFlagKeys,
} from 'src/engine/core-modules/feature-flag/feature-flag.entity';
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
import { CreateCompanyAndContactService } from 'src/modules/connected-account/auto-companies-and-contacts-creation/services/create-company-and-contact.service';
import { MessageChannelRepository } from 'src/modules/messaging/repositories/message-channel.repository';
Expand All @@ -27,6 +34,8 @@ export class MessagingCreateCompanyAndContactAfterSyncJob
private readonly messageChannelService: MessageChannelRepository,
@InjectObjectMetadataRepository(MessageParticipantWorkspaceEntity)
private readonly messageParticipantRepository: MessageParticipantRepository,
@InjectRepository(FeatureFlagEntity, 'core')
private readonly featureFlagRepository: Repository<FeatureFlagEntity>,
) {}

async handle(
Expand All @@ -48,11 +57,25 @@ export class MessagingCreateCompanyAndContactAfterSyncJob
return;
}

const contactsToCreate =
await this.messageParticipantRepository.getByMessageChannelIdWithoutPersonIdAndWorkspaceMemberIdAndMessageOutgoing(
messageChannelId,
workspaceId,
);
const isContactCreationForSentAndReceivedEmailsEnabledFeatureFlag =
await this.featureFlagRepository.findOneBy({
workspaceId: workspaceId,
key: FeatureFlagKeys.IsContactCreationForSentAndReceivedEmailsEnabled,
value: true,
});

const isContactCreationForSentAndReceivedEmailsEnabled =
isContactCreationForSentAndReceivedEmailsEnabledFeatureFlag?.value;

const contactsToCreate = isContactCreationForSentAndReceivedEmailsEnabled
? await this.messageParticipantRepository.getByMessageChannelIdWithoutPersonIdAndWorkspaceMemberId(
messageChannelId,
workspaceId,
)
: await this.messageParticipantRepository.getByMessageChannelIdWithoutPersonIdAndWorkspaceMemberIdAndMessageOutgoing(
messageChannelId,
workspaceId,
);

await this.createCompanyAndContactService.createCompaniesAndContactsAndUpdateParticipants(
handle,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,41 @@ export class MessageParticipantRepository {
return messageParticipants;
}

public async getByMessageChannelIdWithoutPersonIdAndWorkspaceMemberId(
messageChannelId: string,
workspaceId: string,
transactionManager?: EntityManager,
): Promise<ParticipantWithId[]> {
if (!messageChannelId || !workspaceId) {
return [];
}

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"
LEFT JOIN ${dataSourceSchema}."message" ON "messageParticipant"."messageId" = ${dataSourceSchema}."message"."id"
LEFT JOIN ${dataSourceSchema}."messageChannelMessageAssociation" ON ${dataSourceSchema}."messageChannelMessageAssociation"."messageId" = ${dataSourceSchema}."message"."id"
WHERE ${dataSourceSchema}."messageChannelMessageAssociation"."messageChannelId" = $1
AND "messageParticipant"."personId" IS NULL
AND "messageParticipant"."workspaceMemberId" IS NULL`,
[messageChannelId],
workspaceId,
transactionManager,
);

return messageParticipants;
}

public async getWithoutPersonIdAndWorkspaceMemberId(
workspaceId: string,
transactionManager?: EntityManager,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Module } from '@nestjs/common';
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 { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
Expand All @@ -24,6 +26,7 @@ import { MessageChannelWorkspaceEntity } from 'src/modules/messaging/standard-ob
MessageModule,
MessageParticipantModule,
SetMessageChannelSyncStatusModule,
TypeOrmModule.forFeature([FeatureFlagEntity], 'core'),
],
providers: [
GmailMessagesImportService,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Inject, Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';

import { EntityManager } from 'typeorm';
import { EntityManager, Repository } from 'typeorm';

import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
import { ConnectedAccountRepository } from 'src/modules/connected-account/repositories/connected-account.repository';
Expand Down Expand Up @@ -31,6 +32,10 @@ import {
CreateCompanyAndContactJobData,
CreateCompanyAndContactJob,
} from 'src/modules/connected-account/auto-companies-and-contacts-creation/jobs/create-company-and-contact.job';
import {
FeatureFlagEntity,
FeatureFlagKeys,
} from 'src/engine/core-modules/feature-flag/feature-flag.entity';

@Injectable()
export class GmailMessagesImportService {
Expand All @@ -49,6 +54,8 @@ export class GmailMessagesImportService {
private readonly messageQueueService: MessageQueueService,
private readonly messageService: MessageService,
private readonly messageParticipantService: MessageParticipantService,
@InjectRepository(FeatureFlagEntity, 'core')
private readonly featureFlagRepository: Repository<FeatureFlagEntity>,
) {}

async fetchMessageContentFromCache(
Expand Down Expand Up @@ -171,6 +178,16 @@ export class GmailMessagesImportService {

const messageQueries = createQueriesFromMessageIds(messageIdsToFetch);

const isContactCreationForSentAndReceivedEmailsEnabledFeatureFlag =
await this.featureFlagRepository.findOneBy({
workspaceId: workspaceId,
key: FeatureFlagKeys.IsContactCreationForSentAndReceivedEmailsEnabled,
value: true,
});

const isContactCreationForSentAndReceivedEmailsEnabled =
isContactCreationForSentAndReceivedEmailsEnabledFeatureFlag?.value;

try {
const messagesToSave =
await this.fetchMessagesByBatchesService.fetchAllMessages(
Expand Down Expand Up @@ -214,8 +231,9 @@ export class GmailMessagesImportService {
messageId,
shouldCreateContact:
gmailMessageChannel.isContactAutoCreationEnabled &&
message.participants.find((p) => p.role === 'from')
?.handle === connectedAccount.handle,
(isContactCreationForSentAndReceivedEmailsEnabled ||
message.participants.find((p) => p.role === 'from')
?.handle === connectedAccount.handle),
}))
: [];
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Injectable, Inject } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';

import { EntityManager } from 'typeorm';
import { EntityManager, Repository } from 'typeorm';

import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service';
Expand All @@ -18,6 +19,10 @@ import {
CreateCompanyAndContactJobData,
CreateCompanyAndContactJob,
} from 'src/modules/connected-account/auto-companies-and-contacts-creation/jobs/create-company-and-contact.job';
import {
FeatureFlagEntity,
FeatureFlagKeys,
} from 'src/engine/core-modules/feature-flag/feature-flag.entity';

@Injectable()
export class SaveMessagesAndEnqueueContactCreationService {
Expand All @@ -27,6 +32,8 @@ export class SaveMessagesAndEnqueueContactCreationService {
private readonly messageQueueService: MessageQueueService,
private readonly messageService: MessageService,
private readonly messageParticipantService: MessageParticipantService,
@InjectRepository(FeatureFlagEntity, 'core')
private readonly featureFlagRepository: Repository<FeatureFlagEntity>,
) {}

async saveMessagesAndEnqueueContactCreationJob(
Expand All @@ -40,6 +47,16 @@ export class SaveMessagesAndEnqueueContactCreationService {
workspaceId,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable name isContactCreationForSentAndReceivedEmailsEnabledFeatureFlag is quite long. Consider shortening it to improve readability, e.g., contactCreationFlag.

);

const isContactCreationForSentAndReceivedEmailsEnabledFeatureFlag =
await this.featureFlagRepository.findOneBy({
workspaceId: workspaceId,
key: FeatureFlagKeys.IsContactCreationForSentAndReceivedEmailsEnabled,
value: true,
});

const isContactCreationForSentAndReceivedEmailsEnabled =
isContactCreationForSentAndReceivedEmailsEnabledFeatureFlag?.value;

const participantsWithMessageId = await workspaceDataSource?.transaction(
async (transactionManager: EntityManager) => {
const messageExternalIdsAndIdsMap =
Expand All @@ -62,8 +79,9 @@ export class SaveMessagesAndEnqueueContactCreationService {
messageId,
shouldCreateContact:
messageChannel.isContactAutoCreationEnabled &&
message.participants.find((p) => p.role === 'from')
?.handle === connectedAccount.handle,
(isContactCreationForSentAndReceivedEmailsEnabled ||
message.participants.find((p) => p.role === 'from')
?.handle === connectedAccount.handle),
}))
: [];
});
Expand Down
Loading