diff --git a/packages/twenty-server/src/engine/core-modules/tool/tools/send-email-tool/send-email-tool.ts b/packages/twenty-server/src/engine/core-modules/tool/tools/send-email-tool/send-email-tool.ts index 3aa0554ca9126..9733019edefb0 100644 --- a/packages/twenty-server/src/engine/core-modules/tool/tools/send-email-tool/send-email-tool.ts +++ b/packages/twenty-server/src/engine/core-modules/tool/tools/send-email-tool/send-email-tool.ts @@ -50,8 +50,14 @@ export class SendEmailTool implements Tool { workspaceId, 'connectedAccount', ); - const connectedAccount = await connectedAccountRepository.findOneBy({ - id: connectedAccountId, + + const connectedAccount = await connectedAccountRepository.findOne({ + where: { id: connectedAccountId }, + relations: { + messageChannels: { + messageFolders: true, + }, + }, }); if (!isDefined(connectedAccount)) { diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/services/__tests__/messaging-send-message-gmail.spec.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/services/__tests__/messaging-send-message-gmail.spec.ts index 2aef95c90ff74..f0bd62e8fad18 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/services/__tests__/messaging-send-message-gmail.spec.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/services/__tests__/messaging-send-message-gmail.spec.ts @@ -4,6 +4,7 @@ import { ConnectedAccountProvider } from 'twenty-shared/types'; import { GmailClientProvider } from 'src/modules/messaging/message-import-manager/drivers/gmail/providers/gmail-client.provider'; import { OAuth2ClientProvider } from 'src/modules/messaging/message-import-manager/drivers/gmail/providers/oauth2-client.provider'; +import { ImapClientProvider } from 'src/modules/messaging/message-import-manager/drivers/imap/providers/imap-client.provider'; import { MicrosoftClientProvider } from 'src/modules/messaging/message-import-manager/drivers/microsoft/providers/microsoft-client.provider'; import { SmtpClientProvider } from 'src/modules/messaging/message-import-manager/drivers/smtp/providers/smtp-client.provider'; import { MessagingSendMessageService } from 'src/modules/messaging/message-import-manager/services/messaging-send-message.service'; @@ -53,6 +54,10 @@ describe('MessagingSendMessageService - Gmail HTML Support', () => { provide: SmtpClientProvider, useValue: {}, }, + { + provide: ImapClientProvider, + useValue: {}, + }, ], }).compile(); diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-send-message.service.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-send-message.service.ts index 58c5026a6f13b..7c50aeb6ec423 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-send-message.service.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-send-message.service.ts @@ -1,5 +1,6 @@ import { Injectable } from '@nestjs/common'; +import MailComposer from 'nodemailer/lib/mail-composer'; import { ConnectedAccountProvider } from 'twenty-shared/types'; import { assertUnreachable, isDefined } from 'twenty-shared/utils'; import { z } from 'zod'; @@ -11,6 +12,7 @@ import { } from 'src/modules/messaging/message-import-manager/drivers/exceptions/message-import-driver.exception'; import { GmailClientProvider } from 'src/modules/messaging/message-import-manager/drivers/gmail/providers/gmail-client.provider'; import { OAuth2ClientProvider } from 'src/modules/messaging/message-import-manager/drivers/gmail/providers/oauth2-client.provider'; +import { ImapClientProvider } from 'src/modules/messaging/message-import-manager/drivers/imap/providers/imap-client.provider'; import { MicrosoftClientProvider } from 'src/modules/messaging/message-import-manager/drivers/microsoft/providers/microsoft-client.provider'; import { isAccessTokenRefreshingError } from 'src/modules/messaging/message-import-manager/drivers/microsoft/utils/is-access-token-refreshing-error.utils'; import { SmtpClientProvider } from 'src/modules/messaging/message-import-manager/drivers/smtp/providers/smtp-client.provider'; @@ -30,6 +32,7 @@ export class MessagingSendMessageService { private readonly oAuth2ClientProvider: OAuth2ClientProvider, private readonly microsoftClientProvider: MicrosoftClientProvider, private readonly smtpClientProvider: SmtpClientProvider, + private readonly imapClientProvider: ImapClientProvider, ) {} public async sendMessage( @@ -134,16 +137,47 @@ export class MessagingSendMessageService { break; } case ConnectedAccountProvider.IMAP_SMTP_CALDAV: { + const { handle, connectionParameters, messageChannels } = + connectedAccount; + const smtpClient = await this.smtpClientProvider.getSmtpClient(connectedAccount); - await smtpClient.sendMail({ - from: connectedAccount.handle, + const mail = new MailComposer({ + from: handle, to: sendMessageInput.to, subject: sendMessageInput.subject, text: sendMessageInput.body, html: sendMessageInput.html, }); + + const messageBuffer = await mail.compile().build(); + + await smtpClient.sendMail({ + from: handle, + to: sendMessageInput.to, + raw: messageBuffer, + }); + + if (isDefined(connectionParameters?.IMAP)) { + const imapClient = + await this.imapClientProvider.getClient(connectedAccount); + + const messageChannel = messageChannels.find( + (channel) => channel.handle === handle, + ); + + const sentFolder = messageChannel?.messageFolders.find( + (messageFolder) => messageFolder.isSentFolder, + ); + + if (isDefined(sentFolder)) { + await imapClient.append(sentFolder.name, messageBuffer); + } + + await this.imapClientProvider.closeClient(imapClient); + } + break; } default: