diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsBlocklistSection.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsBlocklistSection.tsx index 4eb49a566..1b0a08de0 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsBlocklistSection.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsBlocklistSection.tsx @@ -44,7 +44,7 @@ export const SettingsAccountsBlocklistSection = () => {
item.handle)} diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-messages-import.service.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-messages-import.service.ts index f0a1810e2..6cdb47aca 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-messages-import.service.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-messages-import.service.ts @@ -140,7 +140,8 @@ export class MessagingMessagesImportService { ); const messagesToSave = filterEmails( - [messageChannel.handle, ...connectedAccount.handleAliases.split(',')], + messageChannel.handle, + [...connectedAccount.handleAliases.split(',')], allMessages, blocklist.map((blocklistItem) => blocklistItem.handle), ); diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/utils/__mocks__/messages.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/utils/__mocks__/messages.ts new file mode 100644 index 000000000..f72aa597e --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/utils/__mocks__/messages.ts @@ -0,0 +1,70 @@ +import { MessageWithParticipants } from 'src/modules/messaging/message-import-manager/types/message'; + +export const messagingGetMessagesServiceGetMessages = [ + { + externalId: 'AA-work-emails-internal', + subject: 'Test email for microsoft', + receivedAt: new Date('2025-01-09T09:54:37.000Z'), + text: 'Just a test', + headerMessageId: '', + messageThreadExternalId: 'AAQkAGZlMDQ1NjU5Lk=', + direction: 'OUTGOING', + participants: [ + { + role: 'from', + handle: 'from@acme.com', + displayName: 'From', + }, + { + role: 'to', + handle: 'to@acme.com', + displayName: 'To', + }, + ], + attachments: [], + }, + { + externalId: 'AA-work-emails-external', + subject: 'Test email for microsoft', + receivedAt: new Date('2025-01-09T09:54:37.000Z'), + text: 'Just a test', + headerMessageId: '', + messageThreadExternalId: 'AAQkAGZlMDQ1NjU5Lk=', + direction: 'OUTGOING', + participants: [ + { + role: 'from', + handle: 'from@acme.com', + displayName: 'From', + }, + { + role: 'to', + handle: 'to@external.com', + displayName: 'To', + }, + ], + attachments: [], + }, + { + externalId: 'AA-personal-emails', + subject: 'Sign in to your Microsoft Learn account for more features', + receivedAt: new Date('2025-01-28T19:01:21.000Z'), + text: 'Learn with interactive sandboxes, curated collections, and bookmarks', + headerMessageId: '', + messageThreadExternalId: 'AAQkAGZlMDQ1NNc=', + direction: 'INCOMING', + participants: [ + { + role: 'from', + handle: 'learn@mails.microsoft.com', + displayName: 'Microsoft Learn', + }, + { + role: 'to', + handle: 'to@gmail.com', + displayName: 'To', + }, + ], + attachments: [], + }, +] as MessageWithParticipants[]; diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/utils/__tests__/filter-emails.util.spec.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/utils/__tests__/filter-emails.util.spec.ts new file mode 100644 index 000000000..eb80970c6 --- /dev/null +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/utils/__tests__/filter-emails.util.spec.ts @@ -0,0 +1,51 @@ +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'; + +describe('filterEmails', () => { + it('Should not filter at all if primary handle is a personal email', () => { + const primaryHandle = 'guillim@gmail.com'; + const messages = messagingGetMessagesServiceGetMessages; + + const filteredMessages = filterEmails(primaryHandle, [], messages, []); + + expect(filteredMessages).toEqual(messages); + }); + + it('Should not filter out if at least one email is from a different domain', () => { + const primaryHandle = 'guillim@acme.com'; + const messages = messagingGetMessagesServiceGetMessages.filter( + (message) => message.externalId === 'AA-work-emails-external', + ); + + const filteredMessages = filterEmails(primaryHandle, [], messages, []); + + expect(filteredMessages).toEqual(messages); + }); + + it('Should filter out same domain emails', () => { + const primaryHandle = 'guillim@acme.com'; + const messages = messagingGetMessagesServiceGetMessages.filter( + (message) => message.externalId === 'AA-work-emails-internal', + ); + + const filteredMessages = filterEmails(primaryHandle, [], messages, []); + + expect(filteredMessages).toEqual([]); + }); + + it('Should filter messages with participant from the blocklist', () => { + const primaryHandle = 'guillim@acme.com'; + const messages = messagingGetMessagesServiceGetMessages.filter( + (message) => message.externalId === 'AA-work-emails-internal', + ); + const blocklist = ['to@acme.com']; + const filteredMessages = filterEmails( + primaryHandle, + [], + messages, + blocklist, + ); + + expect(filteredMessages).toEqual([]); + }); +}); diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/utils/filter-emails.util.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/utils/filter-emails.util.ts index 4278fab5c..17dacb92c 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/utils/filter-emails.util.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/utils/filter-emails.util.ts @@ -1,17 +1,26 @@ import { isEmailBlocklisted } from 'src/modules/blocklist/utils/is-email-blocklisted.util'; import { MessageWithParticipants } from 'src/modules/messaging/message-import-manager/types/message'; +import { getDomainNameByEmail } from 'src/utils/get-domain-name-by-email'; +import { isWorkEmail } from 'src/utils/is-work-email'; // Todo: refactor this into several utils export const filterEmails = ( - messageChannelHandles: string[], + primaryHandle: string, + handleAliases: string[], messages: MessageWithParticipants[], blocklist: string[], ) => { - return filterOutBlocklistedMessages( - messageChannelHandles, + const messagesWithoutBlocklisted = filterOutBlocklistedMessages( + [primaryHandle, ...handleAliases], filterOutIcsAttachments(messages), blocklist, ); + + if (isWorkEmail(primaryHandle)) { + return filterOutInternals(primaryHandle, messagesWithoutBlocklisted); + } + + return messagesWithoutBlocklisted; }; const filterOutBlocklistedMessages = ( @@ -46,3 +55,26 @@ const filterOutIcsAttachments = (messages: MessageWithParticipants[]) => { ); }); }; + +const filterOutInternals = ( + primaryHandle: string, + messages: MessageWithParticipants[], +) => { + return messages.filter((message) => { + if (!message.participants) { + return true; + } + + const primaryHandleDomain = getDomainNameByEmail(primaryHandle); + const isAllHandlesFromSameDomain = message.participants.every( + (participant) => + getDomainNameByEmail(participant.handle) === primaryHandleDomain, + ); + + if (isAllHandlesFromSameDomain) { + return false; + } + + return true; + }); +};