internal-messages-backend-and-frontend (#10291)
fixes https://github.com/twentyhq/twenty/issues/10263 fixes https://github.com/twentyhq/twenty/issues/10262 also
This commit is contained in:
@ -44,7 +44,7 @@ export const SettingsAccountsBlocklistSection = () => {
|
|||||||
<Section>
|
<Section>
|
||||||
<H2Title
|
<H2Title
|
||||||
title={t`Blocklist`}
|
title={t`Blocklist`}
|
||||||
description={t`Exclude the following people and domains from my email sync`}
|
description={t`Exclude the following people and domains from my email sync. Internal conversations will not be imported`}
|
||||||
/>
|
/>
|
||||||
<SettingsAccountsBlocklistInput
|
<SettingsAccountsBlocklistInput
|
||||||
blockedEmailOrDomainList={blocklist.map((item) => item.handle)}
|
blockedEmailOrDomainList={blocklist.map((item) => item.handle)}
|
||||||
|
|||||||
@ -140,7 +140,8 @@ export class MessagingMessagesImportService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const messagesToSave = filterEmails(
|
const messagesToSave = filterEmails(
|
||||||
[messageChannel.handle, ...connectedAccount.handleAliases.split(',')],
|
messageChannel.handle,
|
||||||
|
[...connectedAccount.handleAliases.split(',')],
|
||||||
allMessages,
|
allMessages,
|
||||||
blocklist.map((blocklistItem) => blocklistItem.handle),
|
blocklist.map((blocklistItem) => blocklistItem.handle),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -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: '<d45b9f1c@PR0P264MB2911.FRAP264.PROD.OUTLOOK.COM>',
|
||||||
|
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: '<d45b9f1c@PR0P264MB2911.FRAP264.PROD.OUTLOOK.COM>',
|
||||||
|
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: '<AC70000@mails.microsoft.com>',
|
||||||
|
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[];
|
||||||
@ -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([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -1,17 +1,26 @@
|
|||||||
import { isEmailBlocklisted } from 'src/modules/blocklist/utils/is-email-blocklisted.util';
|
import { isEmailBlocklisted } from 'src/modules/blocklist/utils/is-email-blocklisted.util';
|
||||||
import { MessageWithParticipants } from 'src/modules/messaging/message-import-manager/types/message';
|
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
|
// Todo: refactor this into several utils
|
||||||
export const filterEmails = (
|
export const filterEmails = (
|
||||||
messageChannelHandles: string[],
|
primaryHandle: string,
|
||||||
|
handleAliases: string[],
|
||||||
messages: MessageWithParticipants[],
|
messages: MessageWithParticipants[],
|
||||||
blocklist: string[],
|
blocklist: string[],
|
||||||
) => {
|
) => {
|
||||||
return filterOutBlocklistedMessages(
|
const messagesWithoutBlocklisted = filterOutBlocklistedMessages(
|
||||||
messageChannelHandles,
|
[primaryHandle, ...handleAliases],
|
||||||
filterOutIcsAttachments(messages),
|
filterOutIcsAttachments(messages),
|
||||||
blocklist,
|
blocklist,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (isWorkEmail(primaryHandle)) {
|
||||||
|
return filterOutInternals(primaryHandle, messagesWithoutBlocklisted);
|
||||||
|
}
|
||||||
|
|
||||||
|
return messagesWithoutBlocklisted;
|
||||||
};
|
};
|
||||||
|
|
||||||
const filterOutBlocklistedMessages = (
|
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;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user