refactor: extract filter-emails utils into separate files (#15365)
This commit is contained in:
+1
-1
@@ -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()
|
||||
|
||||
+139
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
+10
-67
@@ -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;
|
||||
};
|
||||
|
||||
+23
@@ -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,
|
||||
),
|
||||
);
|
||||
});
|
||||
};
|
||||
+20
@@ -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);
|
||||
});
|
||||
};
|
||||
+15
@@ -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'),
|
||||
);
|
||||
});
|
||||
};
|
||||
+32
@@ -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;
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user