Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 968bc638a0 | |||
| b0374214a3 | |||
| 836d2b791b |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-e2e-testing",
|
||||
"version": "0.51.0-canary",
|
||||
"version": "0.51.1",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"private": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-emails",
|
||||
"version": "0.51.0-canary",
|
||||
"version": "0.51.1",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"private": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-front",
|
||||
"version": "0.51.0-canary",
|
||||
"version": "0.51.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-server",
|
||||
"version": "0.51.0-canary",
|
||||
"version": "0.51.1",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"private": true,
|
||||
|
||||
+20
-13
@@ -17,7 +17,10 @@ export class MessagingMessageService {
|
||||
messages: MessageWithParticipants[],
|
||||
messageChannelId: string,
|
||||
transactionManager: EntityManager,
|
||||
): Promise<Map<string, string>> {
|
||||
): Promise<{
|
||||
createdMessages: Partial<MessageWorkspaceEntity>[];
|
||||
messageExternalIdsAndIdsMap: Map<string, string>;
|
||||
}> {
|
||||
const messageChannelMessageAssociationRepository =
|
||||
await this.twentyORMManager.getRepository<MessageChannelMessageAssociationWorkspaceEntity>(
|
||||
'messageChannelMessageAssociation',
|
||||
@@ -34,6 +37,7 @@ export class MessagingMessageService {
|
||||
);
|
||||
|
||||
const messageExternalIdsAndIdsMap = new Map<string, string>();
|
||||
const createdMessages: Partial<MessageWorkspaceEntity>[] = [];
|
||||
|
||||
for (const message of messages) {
|
||||
const existingMessageChannelMessageAssociation =
|
||||
@@ -101,18 +105,18 @@ export class MessagingMessageService {
|
||||
}
|
||||
|
||||
const newMessageId = v4();
|
||||
const messageToCreate = {
|
||||
id: newMessageId,
|
||||
headerMessageId: message.headerMessageId,
|
||||
subject: message.subject,
|
||||
receivedAt: message.receivedAt,
|
||||
text: message.text,
|
||||
messageThreadId: newOrExistingMessageThreadId,
|
||||
};
|
||||
|
||||
await messageRepository.insert(
|
||||
{
|
||||
id: newMessageId,
|
||||
headerMessageId: message.headerMessageId,
|
||||
subject: message.subject,
|
||||
receivedAt: message.receivedAt,
|
||||
text: message.text,
|
||||
messageThreadId: newOrExistingMessageThreadId,
|
||||
},
|
||||
transactionManager,
|
||||
);
|
||||
await messageRepository.insert(messageToCreate, transactionManager);
|
||||
|
||||
createdMessages.push(messageToCreate);
|
||||
|
||||
messageExternalIdsAndIdsMap.set(message.externalId, newMessageId);
|
||||
|
||||
@@ -128,6 +132,9 @@ export class MessagingMessageService {
|
||||
);
|
||||
}
|
||||
|
||||
return messageExternalIdsAndIdsMap;
|
||||
return {
|
||||
createdMessages,
|
||||
messageExternalIdsAndIdsMap,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+7
-3
@@ -119,12 +119,16 @@ describe('MessagingSaveMessagesAndEnqueueContactCreationService', () => {
|
||||
{
|
||||
provide: MessagingMessageService,
|
||||
useValue: {
|
||||
saveMessagesWithinTransaction: jest.fn().mockResolvedValue(
|
||||
new Map([
|
||||
saveMessagesWithinTransaction: jest.fn().mockResolvedValue({
|
||||
messageExternalIdsAndIdsMap: new Map([
|
||||
['message-1', 'db-message-id-1'],
|
||||
['message-2', 'db-message-id-2'],
|
||||
]),
|
||||
),
|
||||
createdMessages: [
|
||||
{ id: 'db-message-id-1' },
|
||||
{ id: 'db-message-id-2' },
|
||||
],
|
||||
}),
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
+68
-62
@@ -53,70 +53,76 @@ export class MessagingSaveMessagesAndEnqueueContactCreationService {
|
||||
|
||||
const workspaceDataSource = await this.twentyORMManager.getDatasource();
|
||||
|
||||
const participantsWithMessageId = await workspaceDataSource?.transaction(
|
||||
async (transactionManager: EntityManager) => {
|
||||
const messageExternalIdsAndIdsMap =
|
||||
await this.messageService.saveMessagesWithinTransaction(
|
||||
messagesToSave,
|
||||
messageChannel.id,
|
||||
const createdMessagesWithParticipants =
|
||||
await workspaceDataSource?.transaction(
|
||||
async (transactionManager: EntityManager) => {
|
||||
const { messageExternalIdsAndIdsMap, createdMessages } =
|
||||
await this.messageService.saveMessagesWithinTransaction(
|
||||
messagesToSave,
|
||||
messageChannel.id,
|
||||
transactionManager,
|
||||
);
|
||||
|
||||
const participantsWithMessageId: (ParticipantWithMessageId & {
|
||||
shouldCreateContact: boolean;
|
||||
})[] = messagesToSave.flatMap((message) => {
|
||||
const messageId = messageExternalIdsAndIdsMap.get(
|
||||
message.externalId,
|
||||
);
|
||||
|
||||
return messageId
|
||||
? message.participants.map((participant: Participant) => {
|
||||
const fromHandle =
|
||||
message.participants.find((p) => p.role === 'from')
|
||||
?.handle || '';
|
||||
|
||||
const isMessageSentByConnectedAccount =
|
||||
handleAliases.includes(fromHandle) ||
|
||||
fromHandle === connectedAccount.handle;
|
||||
|
||||
const isParticipantConnectedAccount =
|
||||
handleAliases.includes(participant.handle) ||
|
||||
participant.handle === connectedAccount.handle;
|
||||
|
||||
const isExcludedByNonProfessionalEmails =
|
||||
messageChannel.excludeNonProfessionalEmails &&
|
||||
!isWorkEmail(participant.handle);
|
||||
|
||||
const isExcludedByGroupEmails =
|
||||
messageChannel.excludeGroupEmails &&
|
||||
isGroupEmail(participant.handle);
|
||||
|
||||
const shouldCreateContact =
|
||||
!!participant.handle &&
|
||||
!isParticipantConnectedAccount &&
|
||||
!isExcludedByNonProfessionalEmails &&
|
||||
!isExcludedByGroupEmails &&
|
||||
(messageChannel.contactAutoCreationPolicy ===
|
||||
MessageChannelContactAutoCreationPolicy.SENT_AND_RECEIVED ||
|
||||
(messageChannel.contactAutoCreationPolicy ===
|
||||
MessageChannelContactAutoCreationPolicy.SENT &&
|
||||
isMessageSentByConnectedAccount));
|
||||
|
||||
return {
|
||||
...participant,
|
||||
messageId,
|
||||
shouldCreateContact,
|
||||
};
|
||||
})
|
||||
: [];
|
||||
});
|
||||
|
||||
await this.messageParticipantService.saveMessageParticipants(
|
||||
participantsWithMessageId,
|
||||
transactionManager,
|
||||
);
|
||||
|
||||
const participantsWithMessageId: (ParticipantWithMessageId & {
|
||||
shouldCreateContact: boolean;
|
||||
})[] = messagesToSave.flatMap((message) => {
|
||||
const messageId = messageExternalIdsAndIdsMap.get(message.externalId);
|
||||
return { participantsWithMessageId, createdMessages };
|
||||
},
|
||||
);
|
||||
|
||||
return messageId
|
||||
? message.participants.map((participant: Participant) => {
|
||||
const fromHandle =
|
||||
message.participants.find((p) => p.role === 'from')?.handle ||
|
||||
'';
|
||||
|
||||
const isMessageSentByConnectedAccount =
|
||||
handleAliases.includes(fromHandle) ||
|
||||
fromHandle === connectedAccount.handle;
|
||||
|
||||
const isParticipantConnectedAccount =
|
||||
handleAliases.includes(participant.handle) ||
|
||||
participant.handle === connectedAccount.handle;
|
||||
|
||||
const isExcludedByNonProfessionalEmails =
|
||||
messageChannel.excludeNonProfessionalEmails &&
|
||||
!isWorkEmail(participant.handle);
|
||||
|
||||
const isExcludedByGroupEmails =
|
||||
messageChannel.excludeGroupEmails &&
|
||||
isGroupEmail(participant.handle);
|
||||
|
||||
const shouldCreateContact =
|
||||
!!participant.handle &&
|
||||
!isParticipantConnectedAccount &&
|
||||
!isExcludedByNonProfessionalEmails &&
|
||||
!isExcludedByGroupEmails &&
|
||||
(messageChannel.contactAutoCreationPolicy ===
|
||||
MessageChannelContactAutoCreationPolicy.SENT_AND_RECEIVED ||
|
||||
(messageChannel.contactAutoCreationPolicy ===
|
||||
MessageChannelContactAutoCreationPolicy.SENT &&
|
||||
isMessageSentByConnectedAccount));
|
||||
|
||||
return {
|
||||
...participant,
|
||||
messageId,
|
||||
shouldCreateContact,
|
||||
};
|
||||
})
|
||||
: [];
|
||||
});
|
||||
|
||||
await this.messageParticipantService.saveMessageParticipants(
|
||||
participantsWithMessageId,
|
||||
transactionManager,
|
||||
);
|
||||
|
||||
return participantsWithMessageId;
|
||||
},
|
||||
);
|
||||
const { participantsWithMessageId, createdMessages } =
|
||||
createdMessagesWithParticipants;
|
||||
|
||||
const messageMetadata = await this.objectMetadataRepository.findOneOrFail({
|
||||
where: { nameSingular: 'message', workspaceId },
|
||||
@@ -125,9 +131,9 @@ export class MessagingSaveMessagesAndEnqueueContactCreationService {
|
||||
this.workspaceEventEmitter.emitDatabaseBatchEvent({
|
||||
objectMetadataNameSingular: 'message',
|
||||
action: DatabaseEventAction.CREATED,
|
||||
events: messagesToSave.map((message) => {
|
||||
events: createdMessages.map((message) => {
|
||||
return {
|
||||
recordId: message.headerMessageId,
|
||||
recordId: message.id ?? '',
|
||||
objectMetadata: messageMetadata,
|
||||
properties: {
|
||||
after: message,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-shared",
|
||||
"version": "0.51.0-canary",
|
||||
"version": "0.51.1",
|
||||
"main": "dist/twenty-shared.cjs.js",
|
||||
"module": "dist/twenty-shared.esm.js",
|
||||
"license": "AGPL-3.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-ui",
|
||||
"version": "0.51.0-canary",
|
||||
"version": "0.51.1",
|
||||
"main": "dist/index.cjs",
|
||||
"module": "dist/index.mjs",
|
||||
"style": "./dist/style.css",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-website",
|
||||
"version": "0.51.0-canary",
|
||||
"version": "0.51.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"nx": "NX_DEFAULT_PROJECT=twenty-website node ../../node_modules/nx/bin/nx.js",
|
||||
|
||||
Reference in New Issue
Block a user