refactor: extract filter-emails utils into separate files (#15365)

This commit is contained in:
neo773
2025-10-27 19:05:21 +05:30
committed by GitHub
parent a6d6733842
commit dc9d8db770
8 changed files with 240 additions and 68 deletions
@@ -21,8 +21,8 @@ import {
} from 'src/modules/messaging/message-import-manager/drivers/gmail/types/gmail-message.type';
import { MessagingMessageService } from 'src/modules/messaging/message-import-manager/services/messaging-message.service';
import { type MessageWithParticipants } from 'src/modules/messaging/message-import-manager/types/message';
import { isGroupEmail } from 'src/modules/messaging/message-import-manager/utils/is-group-email';
import { MessagingMessageParticipantService } from 'src/modules/messaging/message-participant-manager/services/messaging-message-participant.service';
import { isGroupEmail } from 'src/utils/is-group-email';
import { isWorkEmail } from 'src/utils/is-work-email';
@Injectable()
@@ -1,3 +1,5 @@
import { MessageDirection } from 'src/modules/messaging/common/enums/message-direction.enum';
import { type MessageWithParticipants } from 'src/modules/messaging/message-import-manager/types/message';
import { messagingGetMessagesServiceGetMessages } from 'src/modules/messaging/message-import-manager/utils/__mocks__/messages';
import { filterEmails } from 'src/modules/messaging/message-import-manager/utils/filter-emails.util';
@@ -48,4 +50,141 @@ describe('filterEmails', () => {
expect(filteredMessages).toEqual([]);
});
it('should filter out messages from group email addresses', () => {
const primaryHandle = 'user@example.com';
const messages: MessageWithParticipants[] = [
{
externalId: 'noreply-message',
subject: 'Automated message',
receivedAt: new Date('2025-01-09T09:54:37.000Z'),
text: 'This is an automated message',
headerMessageId: '<noreply@example.com>',
messageThreadExternalId: 'thread-1',
direction: MessageDirection.INCOMING,
participants: [
{
role: 'from',
handle: 'noreply@example.com',
displayName: 'No Reply',
},
],
attachments: [],
},
{
externalId: 'support-message',
subject: 'Support ticket',
receivedAt: new Date('2025-01-09T09:54:37.000Z'),
text: 'Support response',
headerMessageId: '<support@company.com>',
messageThreadExternalId: 'thread-2',
direction: MessageDirection.INCOMING,
participants: [
{
role: 'from',
handle: 'support@company.com',
displayName: 'Support Team',
},
],
attachments: [],
},
{
externalId: 'regular-message',
subject: 'Personal message',
receivedAt: new Date('2025-01-09T10:54:37.000Z'),
text: 'This is a personal message',
headerMessageId: '<john@example.com>',
messageThreadExternalId: 'thread-3',
direction: MessageDirection.INCOMING,
participants: [
{
role: 'from',
handle: 'john@example.com',
displayName: 'John Doe',
},
],
attachments: [],
},
];
const result = filterEmails(primaryHandle, [], messages, []);
expect(result).toHaveLength(1);
expect(result[0].externalId).toBe('regular-message');
});
it('should not filter out group emails when excludeGroupEmails is false', () => {
const primaryHandle = 'user@example.com';
const messages: MessageWithParticipants[] = [
{
externalId: 'noreply-message',
subject: 'Automated message',
receivedAt: new Date('2025-01-09T09:54:37.000Z'),
text: 'This is an automated message',
headerMessageId: '<noreply@example.com>',
messageThreadExternalId: 'thread-1',
direction: MessageDirection.INCOMING,
participants: [
{
role: 'from',
handle: 'noreply@example.com',
displayName: 'No Reply',
},
],
attachments: [],
},
];
const result = filterEmails(primaryHandle, [], messages, [], false);
expect(result).toEqual(messages);
});
it('should keep messages without participants', () => {
const primaryHandle = 'user@example.com';
const messages: MessageWithParticipants[] = [
{
externalId: 'no-participants',
subject: 'Test',
receivedAt: new Date('2025-01-09T09:54:37.000Z'),
text: 'Test content',
headerMessageId: '<test@example.com>',
messageThreadExternalId: 'thread-1',
direction: MessageDirection.INCOMING,
participants: undefined as any,
attachments: [],
},
];
const result = filterEmails(primaryHandle, [], messages, []);
expect(result).toEqual(messages);
});
it('should keep regular personal email addresses', () => {
const primaryHandle = 'user@example.com';
const messages: MessageWithParticipants[] = [
{
externalId: 'personal-1',
subject: 'Personal message',
receivedAt: new Date('2025-01-09T09:54:37.000Z'),
text: 'Content',
headerMessageId: '<john.doe@example.com>',
messageThreadExternalId: 'thread-1',
direction: MessageDirection.INCOMING,
participants: [
{
role: 'from',
handle: 'john.doe@example.com',
displayName: 'John Doe',
},
],
attachments: [],
},
];
const result = filterEmails(primaryHandle, [], messages, []);
expect(result).toEqual(messages);
});
});
@@ -1,14 +1,16 @@
import { isEmailBlocklisted } from 'src/modules/blocklist/utils/is-email-blocklisted.util';
import { type MessageWithParticipants } from 'src/modules/messaging/message-import-manager/types/message';
import { getDomainNameByEmail } from 'src/utils/get-domain-name-by-email';
import { filterOutBlocklistedMessages } from 'src/modules/messaging/message-import-manager/utils/filter-out-blocklisted-messages.util';
import { filterOutGroupEmails } from 'src/modules/messaging/message-import-manager/utils/filter-out-group-emails.util';
import { filterOutIcsAttachments } from 'src/modules/messaging/message-import-manager/utils/filter-out-ics-attachments.util';
import { filterOutInternals } from 'src/modules/messaging/message-import-manager/utils/filter-out-internals.util';
import { isWorkEmail } from 'src/utils/is-work-email';
// Todo: refactor this into several utils
export const filterEmails = (
primaryHandle: string,
handleAliases: string[],
messages: MessageWithParticipants[],
blocklist: string[],
excludeGroupEmails: boolean = true,
) => {
const messagesWithoutIcsAttachments = filterOutIcsAttachments(messages);
@@ -22,68 +24,9 @@ export const filterEmails = (
? filterOutInternals(primaryHandle, messagesWithoutBlocklisted)
: messagesWithoutBlocklisted;
return messagesWithoutInternals;
};
const filterOutBlocklistedMessages = (
messageChannelHandles: string[],
messages: MessageWithParticipants[],
blocklist: string[],
) => {
return messages.filter((message) => {
if (!message.participants) {
return true;
}
return message.participants.every(
(participant) =>
!isEmailBlocklisted(
messageChannelHandles,
participant.handle,
blocklist,
),
);
});
};
const filterOutIcsAttachments = (messages: MessageWithParticipants[]) => {
return messages.filter((message) => {
if (!message.attachments) {
return true;
}
return message.attachments.every(
(attachment) => !attachment.filename.endsWith('.ics'),
);
});
};
const filterOutInternals = (
primaryHandle: string,
messages: MessageWithParticipants[],
) => {
return messages.filter((message) => {
if (!message.participants) {
return true;
}
const primaryHandleDomain = getDomainNameByEmail(primaryHandle);
try {
const isAllHandlesFromSameDomain = message.participants
.filter((participant) => !!participant.handle)
.every(
(participant) =>
getDomainNameByEmail(participant.handle) === primaryHandleDomain,
);
if (isAllHandlesFromSameDomain) {
return false;
}
} catch {
return true;
}
return true;
});
const messagesWithoutInternalsAndGroupEmails = excludeGroupEmails
? filterOutGroupEmails(messagesWithoutInternals)
: messagesWithoutInternals;
return messagesWithoutInternalsAndGroupEmails;
};
@@ -0,0 +1,23 @@
import { isEmailBlocklisted } from 'src/modules/blocklist/utils/is-email-blocklisted.util';
import { type MessageWithParticipants } from 'src/modules/messaging/message-import-manager/types/message';
export const filterOutBlocklistedMessages = (
messageChannelHandles: string[],
messages: MessageWithParticipants[],
blocklist: string[],
) => {
return messages.filter((message) => {
if (!message.participants) {
return true;
}
return message.participants.every(
(participant) =>
!isEmailBlocklisted(
messageChannelHandles,
participant.handle,
blocklist,
),
);
});
};
@@ -0,0 +1,20 @@
import { type MessageWithParticipants } from 'src/modules/messaging/message-import-manager/types/message';
import { isGroupEmail } from 'src/modules/messaging/message-import-manager/utils/is-group-email';
export const filterOutGroupEmails = (messages: MessageWithParticipants[]) => {
return messages.filter((message) => {
if (!message.participants) {
return true;
}
const fromParticipant = message.participants.find(
(participant) => participant.role === 'from',
);
if (!fromParticipant || !fromParticipant.handle) {
return true;
}
return !isGroupEmail(fromParticipant.handle);
});
};
@@ -0,0 +1,15 @@
import { type MessageWithParticipants } from 'src/modules/messaging/message-import-manager/types/message';
export const filterOutIcsAttachments = (
messages: MessageWithParticipants[],
) => {
return messages.filter((message) => {
if (!message.attachments) {
return true;
}
return message.attachments.every(
(attachment) => !attachment.filename.endsWith('.ics'),
);
});
};
@@ -0,0 +1,32 @@
import { type MessageWithParticipants } from 'src/modules/messaging/message-import-manager/types/message';
import { getDomainNameByEmail } from 'src/utils/get-domain-name-by-email';
export const filterOutInternals = (
primaryHandle: string,
messages: MessageWithParticipants[],
) => {
return messages.filter((message) => {
if (!message.participants) {
return true;
}
const primaryHandleDomain = getDomainNameByEmail(primaryHandle);
try {
const isAllHandlesFromSameDomain = message.participants
.filter((participant) => !!participant.handle)
.every(
(participant) =>
getDomainNameByEmail(participant.handle) === primaryHandleDomain,
);
if (isAllHandlesFromSameDomain) {
return false;
}
} catch {
return true;
}
return true;
});
};