feat(messaging): add workspace toggle to sync internal emails (#20457)
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
This commit is contained in:
+9
@@ -26,6 +26,7 @@ import { getRepositoryToken } from '@nestjs/typeorm';
|
||||
import { MessagingMonitoringService } from 'src/modules/messaging/monitoring/services/messaging-monitoring.service';
|
||||
import { MessageChannelEntity } from 'src/engine/metadata-modules/message-channel/entities/message-channel.entity';
|
||||
import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
|
||||
describe('MessagingMessagesImportService', () => {
|
||||
let service: MessagingMessagesImportService;
|
||||
@@ -183,6 +184,14 @@ describe('MessagingMessagesImportService', () => {
|
||||
findOne: jest.fn().mockResolvedValue({ userId: 'user-id' }),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(WorkspaceEntity),
|
||||
useValue: {
|
||||
findOne: jest
|
||||
.fn()
|
||||
.mockResolvedValue({ isInternalMessagesImportEnabled: false }),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: TwentyConfigService,
|
||||
useValue: {
|
||||
|
||||
+9
@@ -9,6 +9,7 @@ import { CacheStorageService } from 'src/engine/core-modules/cache-storage/servi
|
||||
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
|
||||
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
|
||||
import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { type ConnectedAccountEntity } from 'src/engine/metadata-modules/connected-account/entities/connected-account.entity';
|
||||
import { MessageChannelEntity } from 'src/engine/metadata-modules/message-channel/entities/message-channel.entity';
|
||||
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
||||
@@ -55,6 +56,8 @@ export class MessagingMessagesImportService {
|
||||
private readonly messagingAccountAuthenticationService: MessagingAccountAuthenticationService,
|
||||
@InjectRepository(UserWorkspaceEntity)
|
||||
private readonly userWorkspaceRepository: Repository<UserWorkspaceEntity>,
|
||||
@InjectRepository(WorkspaceEntity)
|
||||
private readonly workspaceRepository: Repository<WorkspaceEntity>,
|
||||
private readonly twentyConfigService: TwentyConfigService,
|
||||
) {}
|
||||
|
||||
@@ -197,6 +200,11 @@ export class MessagingMessagesImportService {
|
||||
);
|
||||
}
|
||||
|
||||
const workspace = await this.workspaceRepository.findOne({
|
||||
where: { id: workspaceId },
|
||||
select: ['id', 'isInternalMessagesImportEnabled'],
|
||||
});
|
||||
|
||||
const messagesToSave = filterEmails(
|
||||
messageChannel.handle,
|
||||
[...connectedAccountWithFreshTokens.handleAliases],
|
||||
@@ -205,6 +213,7 @@ export class MessagingMessagesImportService {
|
||||
.map((blocklistItem) => blocklistItem.handle)
|
||||
.filter(isDefined),
|
||||
messageChannel.excludeGroupEmails,
|
||||
workspace?.isInternalMessagesImportEnabled ?? false,
|
||||
);
|
||||
|
||||
if (messagesToSave.length > 0) {
|
||||
|
||||
+21
@@ -37,6 +37,27 @@ describe('filterEmails', () => {
|
||||
expect(filteredMessages).toEqual([]);
|
||||
});
|
||||
|
||||
it('Should keep same-domain emails when isInternalMessagesImportEnabled is true', () => {
|
||||
// Workspace opted into syncing internal emails (e.g. university or
|
||||
// shared-domain institution). Same-domain participants must not be
|
||||
// dropped — the toggle bypasses filterOutInternals.
|
||||
const primaryHandle = 'guillim@acme.com';
|
||||
const messages = messagingGetMessagesServiceGetMessages.filter(
|
||||
(message) => message.externalId === 'AA-work-emails-internal',
|
||||
);
|
||||
|
||||
const filteredMessages = filterEmails(
|
||||
primaryHandle,
|
||||
[],
|
||||
messages,
|
||||
[],
|
||||
true,
|
||||
true,
|
||||
);
|
||||
|
||||
expect(filteredMessages).toEqual(messages);
|
||||
});
|
||||
|
||||
it('Should filter messages with participant from the blocklist', () => {
|
||||
const primaryHandle = 'guillim@acme.com';
|
||||
const messages = messagingGetMessagesServiceGetMessages.filter(
|
||||
|
||||
+5
-1
@@ -15,6 +15,7 @@ export const filterEmails = (
|
||||
messages: MessageWithParticipants[],
|
||||
blocklist: string[],
|
||||
excludeGroupEmails: boolean = true,
|
||||
isInternalMessagesImportEnabled: boolean = false,
|
||||
) => {
|
||||
const messagesWithoutIcsAttachments = filterOutIcsAttachments(messages);
|
||||
|
||||
@@ -24,7 +25,10 @@ export const filterEmails = (
|
||||
blocklist,
|
||||
);
|
||||
|
||||
const messagesWithoutInternals = isWorkEmail(primaryHandle)
|
||||
const shouldFilterOutInternals =
|
||||
isWorkEmail(primaryHandle) && !isInternalMessagesImportEnabled;
|
||||
|
||||
const messagesWithoutInternals = shouldFilterOutInternals
|
||||
? filterOutInternals(primaryHandle, messagesWithoutBlocklisted)
|
||||
: messagesWithoutBlocklisted;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user