From 3865e40967dbc4d3cd7ba7dce248d8281daabf3b Mon Sep 17 00:00:00 2001 From: Mathias Vandaele Date: Sat, 28 Sep 2024 14:44:10 +0200 Subject: [PATCH] other(email-connector): single from address, add fields to readResponse (#3365) * others(email-connector): add last minute feature requested by the team * others(email-connector): add last minute feature requested by the team * others(email-connector): add last minute feature requested by the team 2 * others(email-connector): add last minute feature requested by the team 3 * others(email-connector): add last minute feature requested by the team 3 * feat(email connector): label refinment and fix DoNothing handle feature 4 * chore(email): fix import issues - remove use of wildcard import - remove unnecessary fully qualified class name * chore(email): fix spotless issues --------- Co-authored-by: Ev Bilske --- .../email-outbound-connector.json | 2 +- .../email-outbound-connector-hybrid.json | 2 +- .../connector/email/client/jakarta/Email.java | 3 ++- .../email/client/jakarta/Header.java | 9 +++++++ .../jakarta/JakartaEmailActionExecutor.java | 11 +++++--- .../client/jakarta/JakartaEmailListener.java | 18 +++++++------ .../email/client/jakarta/JakartaUtils.java | 25 ++++++++++++------- .../inbound/model/EmailListenerConfig.java | 4 +-- .../protocols/actions/ImapSearchEmails.java | 4 ++- .../protocols/actions/Pop3SearchEmails.java | 4 ++- .../protocols/actions/SmtpSendEmail.java | 5 ++-- .../email/response/ListEmailsResponse.java | 4 +-- .../email/response/ReadEmailResponse.java | 8 ++++-- .../client/jakarta/JakartaExecutorTest.java | 18 ++++++++----- .../email/client/jakarta/TestMessage.java | 19 ++++++++++++-- 15 files changed, 93 insertions(+), 43 deletions(-) create mode 100644 connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/Header.java diff --git a/connectors/email/element-templates/email-outbound-connector.json b/connectors/email/element-templates/email-outbound-connector.json index a23f2faf47..e3615b0c54 100644 --- a/connectors/email/element-templates/email-outbound-connector.json +++ b/connectors/email/element-templates/email-outbound-connector.json @@ -464,7 +464,7 @@ "type" : "simple" } ] }, - "tooltip" : "Comma-separated list of email, e.g., 'email1@domain.com,email2@domain.com' or '=[ \"email1@domain.com\", \"email2@domain.com\"]'", + "tooltip" : "Address the email will be sent from", "type" : "String" }, { "id" : "smtpTo", diff --git a/connectors/email/element-templates/hybrid/email-outbound-connector-hybrid.json b/connectors/email/element-templates/hybrid/email-outbound-connector-hybrid.json index 1b5f19d9ae..3ec25b9d1c 100644 --- a/connectors/email/element-templates/hybrid/email-outbound-connector-hybrid.json +++ b/connectors/email/element-templates/hybrid/email-outbound-connector-hybrid.json @@ -469,7 +469,7 @@ "type" : "simple" } ] }, - "tooltip" : "Comma-separated list of email, e.g., 'email1@domain.com,email2@domain.com' or '=[ \"email1@domain.com\", \"email2@domain.com\"]'", + "tooltip" : "Address the email will be sent from", "type" : "String" }, { "id" : "smtpTo", diff --git a/connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/Email.java b/connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/Email.java index 6819ca19cc..2691426200 100644 --- a/connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/Email.java +++ b/connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/Email.java @@ -13,7 +13,8 @@ public record Email( EmailBody body, String messageId, String subject, - List from, + List
headers, + String from, List to, List cc, OffsetDateTime sentAt, diff --git a/connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/Header.java b/connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/Header.java new file mode 100644 index 0000000000..1c7cf49787 --- /dev/null +++ b/connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/Header.java @@ -0,0 +1,9 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. Licensed under a proprietary license. + * See the License.txt file for more information. You may not use this file + * except in compliance with the proprietary license. + */ +package io.camunda.connector.email.client.jakarta; + +public record Header(String key, String value) {} diff --git a/connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/JakartaEmailActionExecutor.java b/connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/JakartaEmailActionExecutor.java index 7cdc4e5d10..0caef6f0d0 100644 --- a/connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/JakartaEmailActionExecutor.java +++ b/connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/JakartaEmailActionExecutor.java @@ -90,10 +90,12 @@ private ReadEmailResponse imapReadEmail( new ReadEmailResponse( email.messageId(), email.from(), + email.headers(), email.subject(), email.size(), email.body().bodyAsPlainText(), - email.body().bodyAsHtml())) + email.body().bodyAsHtml(), + email.receivedAt())) .orElseThrow(() -> new MessagingException("Could not find an email ID")); } } catch (MessagingException e) { @@ -204,10 +206,12 @@ private ReadEmailResponse pop3ReadEmail( new ReadEmailResponse( email.messageId(), email.from(), + email.headers(), email.subject(), email.size(), email.body().bodyAsPlainText(), - email.body().bodyAsHtml())) + email.body().bodyAsHtml(), + email.receivedAt())) .orElseThrow(() -> new MessagingException("No emails have been found with this ID")); } } @@ -256,12 +260,11 @@ private List pop3SearchEmails( private SendEmailResponse smtpSendEmail( SmtpSendEmail smtpSendEmail, Authentication authentication, Session session) { try { - Optional from = createParsedInternetAddresses(smtpSendEmail.from()); Optional to = createParsedInternetAddresses(smtpSendEmail.to()); Optional cc = createParsedInternetAddresses(smtpSendEmail.cc()); Optional bcc = createParsedInternetAddresses(smtpSendEmail.bcc()); Message message = new MimeMessage(session); - if (from.isPresent()) message.addFrom(from.get()); + message.setFrom(new InternetAddress(smtpSendEmail.from())); if (to.isPresent()) message.setRecipients(Message.RecipientType.TO, to.get()); if (cc.isPresent()) message.setRecipients(Message.RecipientType.CC, cc.get()); if (bcc.isPresent()) message.setRecipients(Message.RecipientType.BCC, bcc.get()); diff --git a/connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/JakartaEmailListener.java b/connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/JakartaEmailListener.java index b18159c80d..9daed7cbb8 100644 --- a/connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/JakartaEmailListener.java +++ b/connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/JakartaEmailListener.java @@ -25,6 +25,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.eclipse.angus.mail.imap.IMAPFolder; +import org.eclipse.angus.mail.imap.IMAPMessage; import org.eclipse.angus.mail.imap.IdleManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -97,7 +98,7 @@ private void processChangedEvent( InboundConnectorContext connectorContext, EmailListenerConfig emailListenerConfig) { IMAPFolder imapFolder = (IMAPFolder) event.getSource(); - Message message = event.getMessage(); + IMAPMessage message = (IMAPMessage) event.getMessage(); try { if (!message.isSet(Flags.Flag.SEEN)) processMail(message, connectorContext, emailListenerConfig); @@ -112,7 +113,7 @@ private void pollAllAndProcess( try { Message[] messages = folder.getMessages(); Arrays.stream(messages) - .forEach(message -> processMail(message, context, emailListenerConfig)); + .forEach(message -> processMail((IMAPMessage) message, context, emailListenerConfig)); } catch (MessagingException e) { throw new RuntimeException(e); } @@ -124,7 +125,7 @@ private void pollUnseenAndProcess( FlagTerm unseenFlagTerm = new FlagTerm(new Flags(Flags.Flag.SEEN), false); Message[] unseenMessages = folder.search(unseenFlagTerm); Arrays.stream(unseenMessages) - .forEach(message -> processMail(message, context, emailListenerConfig)); + .forEach(message -> processMail((IMAPMessage) message, context, emailListenerConfig)); } catch (MessagingException e) { throw new RuntimeException(e); } @@ -136,7 +137,7 @@ private void processNewEvent( EmailListenerConfig emailListenerConfig) { IMAPFolder imapFolder = (IMAPFolder) event.getSource(); for (Message message : event.getMessages()) { - processMail(message, connectorContext, emailListenerConfig); + processMail((IMAPMessage) message, connectorContext, emailListenerConfig); } try { idleManager.watch(imapFolder); @@ -146,12 +147,13 @@ private void processNewEvent( } private void processMail( - Message message, + IMAPMessage message, InboundConnectorContext connectorContext, EmailListenerConfig emailListenerConfig) { + message.setPeek(true); CorrelationResult correlationResult = this.correlateEmail(message, connectorContext); - + message.setPeek(false); switch (correlationResult) { case CorrelationResult.Failure failure -> { switch (failure.handlingStrategy()) { @@ -181,10 +183,12 @@ private CorrelationResult correlateEmail( new ReadEmailResponse( email.messageId(), email.from(), + email.headers(), email.subject(), email.size(), email.body().bodyAsPlainText(), - email.body().bodyAsHtml())); + email.body().bodyAsHtml(), + email.receivedAt())); } private List createInboxList(Object folderToListen) { diff --git a/connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/JakartaUtils.java b/connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/JakartaUtils.java index d92f40377f..7e2aa286ec 100644 --- a/connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/JakartaUtils.java +++ b/connectors/email/src/main/java/io/camunda/connector/email/client/jakarta/JakartaUtils.java @@ -73,7 +73,7 @@ public void markAsSeen(Message message) { private Properties createProperties(SmtpConfig smtp) { Properties properties = new Properties(); properties.put("mail.transport.protocol", "smtp"); - properties.put("mail.smtp.host", smtp.smtpHost()); + properties.put("mail.smtp.host", smtp.smtpHost().trim()); properties.put("mail.smtp.port", smtp.smtpPort().toString()); properties.put("mail.smtp.auth", true); switch (smtp.smtpCryptographicProtocol()) { @@ -90,20 +90,20 @@ private Properties createProperties(Pop3Config pop3) { switch (pop3.pop3CryptographicProtocol()) { case NONE -> { properties.put("mail.store.protocol", "pop3"); - properties.put("mail.pop3.host", pop3.pop3Host()); + properties.put("mail.pop3.host", pop3.pop3Host().trim()); properties.put("mail.pop3.port", pop3.pop3Port().toString()); properties.put("mail.pop3.auth", true); } case TLS -> { properties.put("mail.store.protocol", "pop3s"); - properties.put("mail.pop3s.host", pop3.pop3Host()); + properties.put("mail.pop3s.host", pop3.pop3Host().trim()); properties.put("mail.pop3s.port", pop3.pop3Port().toString()); properties.put("mail.pop3s.auth", true); properties.put("mail.pop3s.starttls.enable", true); } case SSL -> { properties.put("mail.store.protocol", "pop3s"); - properties.put("mail.pop3s.host", pop3.pop3Host()); + properties.put("mail.pop3s.host", pop3.pop3Host().trim()); properties.put("mail.pop3s.port", pop3.pop3Port().toString()); properties.put("mail.pop3s.auth", true); properties.put("mail.pop3s.ssl.enable", true); @@ -118,13 +118,13 @@ private Properties createProperties(ImapConfig imap) { switch (imap.imapCryptographicProtocol()) { case NONE -> { properties.put("mail.store.protocol", "imap"); - properties.put("mail.imap.host", imap.imapHost()); + properties.put("mail.imap.host", imap.imapHost().trim()); properties.put("mail.imap.port", imap.imapPort().toString()); properties.put("mail.imap.auth", true); } case TLS -> { properties.put("mail.store.protocol", "imaps"); - properties.put("mail.imaps.host", imap.imapHost()); + properties.put("mail.imaps.host", imap.imapHost().trim()); properties.put("mail.imaps.port", imap.imapPort().toString()); properties.put("mail.imaps.auth", true); properties.put("mail.imaps.starttls.enable", true); @@ -132,7 +132,7 @@ private Properties createProperties(ImapConfig imap) { } case SSL -> { properties.put("mail.store.protocol", "imaps"); - properties.put("mail.imaps.host", imap.imapHost()); + properties.put("mail.imaps.host", imap.imapHost().trim()); properties.put("mail.imaps.port", imap.imapPort().toString()); properties.put("mail.imaps.auth", true); properties.put("mail.imaps.ssl.enable", true); @@ -190,11 +190,12 @@ public Folder findImapFolder(Folder rootFolder, String targetFolder) throws Mess public Email createBodylessEmail(Message message) { try { - List from = + String from = Arrays.stream(Optional.ofNullable(message.getFrom()).orElse(new Address[0])) .map(Address::toString) .map(address -> address.replaceAll(".*<|>.*", "")) - .toList(); + .toList() + .getFirst(); List to = Arrays.stream( Optional.ofNullable(message.getRecipients(Message.RecipientType.TO)) @@ -219,11 +220,16 @@ public Email createBodylessEmail(Message message) { .map(Date::toInstant) .map(instant -> instant.atOffset(ZoneOffset.UTC)) .orElse(null); + List
headers = + Collections.list(message.getAllHeaders()).stream() + .map(header -> new Header(header.getName(), header.getValue())) + .toList(); String messageId = stripMessageId(message.getHeader("Message-ID")[0]); return new Email( null, messageId, message.getSubject(), + headers, from, to, cc, @@ -253,6 +259,7 @@ public Email createEmail(Message message) { emailBody, email.messageId(), email.subject(), + email.headers(), email.from(), email.to(), email.cc(), diff --git a/connectors/email/src/main/java/io/camunda/connector/email/inbound/model/EmailListenerConfig.java b/connectors/email/src/main/java/io/camunda/connector/email/inbound/model/EmailListenerConfig.java index 194f9e4301..2144e1cbbf 100644 --- a/connectors/email/src/main/java/io/camunda/connector/email/inbound/model/EmailListenerConfig.java +++ b/connectors/email/src/main/java/io/camunda/connector/email/inbound/model/EmailListenerConfig.java @@ -36,13 +36,13 @@ public record EmailListenerConfig( defaultValue = "UNSEEN", choices = { @TemplateProperty.DropdownPropertyChoice( - label = "Unseen emails will be sync", + label = "Unseen emails will be synced", value = "UNSEEN"), @TemplateProperty.DropdownPropertyChoice( label = "No initial sync. Only new emails", value = "NONE"), @TemplateProperty.DropdownPropertyChoice( - label = "All emails will be sync", + label = "All emails will be synced", value = "ALL") }, binding = @TemplateProperty.PropertyBinding(name = "data.initialPollingConfig")) diff --git a/connectors/email/src/main/java/io/camunda/connector/email/outbound/protocols/actions/ImapSearchEmails.java b/connectors/email/src/main/java/io/camunda/connector/email/outbound/protocols/actions/ImapSearchEmails.java index ab1055532d..9d2c67a5ff 100644 --- a/connectors/email/src/main/java/io/camunda/connector/email/outbound/protocols/actions/ImapSearchEmails.java +++ b/connectors/email/src/main/java/io/camunda/connector/email/outbound/protocols/actions/ImapSearchEmails.java @@ -17,7 +17,9 @@ public record ImapSearchEmails( group = "searchEmailsImap", id = "searchStringEmailImap", tooltip = - "Define the search criteria using supported keywords and syntax to filter emails. Refer to our detailed documentation for full search syntax and examples: [Email Documentation](https://docs.camunda.io/docs/components/connectors/out-of-the-box-connectors/email/).", + "Define the search criteria using supported keywords and syntax to filter emails.", + description = + "Refer to our detailed documentation for full search syntax and examples: [Email Documentation](https://docs.camunda.io/docs/components/connectors/out-of-the-box-connectors/email/).", type = TemplateProperty.PropertyType.Text, feel = Property.FeelMode.required, optional = true, diff --git a/connectors/email/src/main/java/io/camunda/connector/email/outbound/protocols/actions/Pop3SearchEmails.java b/connectors/email/src/main/java/io/camunda/connector/email/outbound/protocols/actions/Pop3SearchEmails.java index d434f30ef8..a4004dbf89 100644 --- a/connectors/email/src/main/java/io/camunda/connector/email/outbound/protocols/actions/Pop3SearchEmails.java +++ b/connectors/email/src/main/java/io/camunda/connector/email/outbound/protocols/actions/Pop3SearchEmails.java @@ -17,7 +17,9 @@ public record Pop3SearchEmails( group = "searchEmailsPop3", id = "searchStringEmailPop3", tooltip = - "Define the search criteria using supported keywords and syntax to filter emails. Refer to our detailed documentation for full search syntax and examples: [Email Documentation](https://docs.camunda.io/docs/components/connectors/out-of-the-box-connectors/email/).", + "Define the search criteria using supported keywords and syntax to filter emails.", + description = + "Refer to our detailed documentation for full search syntax and examples: [Email Documentation](https://docs.camunda.io/docs/components/connectors/out-of-the-box-connectors/email/).", type = TemplateProperty.PropertyType.Text, feel = Property.FeelMode.required, optional = true, diff --git a/connectors/email/src/main/java/io/camunda/connector/email/outbound/protocols/actions/SmtpSendEmail.java b/connectors/email/src/main/java/io/camunda/connector/email/outbound/protocols/actions/SmtpSendEmail.java index 15f95327c3..8b80d2a197 100644 --- a/connectors/email/src/main/java/io/camunda/connector/email/outbound/protocols/actions/SmtpSendEmail.java +++ b/connectors/email/src/main/java/io/camunda/connector/email/outbound/protocols/actions/SmtpSendEmail.java @@ -18,13 +18,12 @@ public record SmtpSendEmail( label = "From", group = "sendEmailSmtp", id = "smtpFrom", - tooltip = - "Comma-separated list of email, e.g., 'email1@domain.com,email2@domain.com' or '=[ \"email1@domain.com\", \"email2@domain.com\"]'", + tooltip = "Address the email will be sent from", feel = Property.FeelMode.optional, binding = @TemplateProperty.PropertyBinding(name = "data.smtpAction.from")) @Valid @NotNull - Object from, + String from, @TemplateProperty( label = "To", group = "sendEmailSmtp", diff --git a/connectors/email/src/main/java/io/camunda/connector/email/response/ListEmailsResponse.java b/connectors/email/src/main/java/io/camunda/connector/email/response/ListEmailsResponse.java index fcf141849b..57e53da452 100644 --- a/connectors/email/src/main/java/io/camunda/connector/email/response/ListEmailsResponse.java +++ b/connectors/email/src/main/java/io/camunda/connector/email/response/ListEmailsResponse.java @@ -6,7 +6,5 @@ */ package io.camunda.connector.email.response; -import java.util.List; - public record ListEmailsResponse( - String messageId, List fromAddresses, String subject, Integer size) {} + String messageId, String fromAddress, String subject, Integer size) {} diff --git a/connectors/email/src/main/java/io/camunda/connector/email/response/ReadEmailResponse.java b/connectors/email/src/main/java/io/camunda/connector/email/response/ReadEmailResponse.java index 7c5c5162e3..98d8fda25d 100644 --- a/connectors/email/src/main/java/io/camunda/connector/email/response/ReadEmailResponse.java +++ b/connectors/email/src/main/java/io/camunda/connector/email/response/ReadEmailResponse.java @@ -6,12 +6,16 @@ */ package io.camunda.connector.email.response; +import io.camunda.connector.email.client.jakarta.Header; +import java.time.OffsetDateTime; import java.util.List; public record ReadEmailResponse( String messageId, - List fromAddresses, + String fromAddress, + List
headers, String subject, Integer size, String plainTextBody, - String htmlBody) {} + String htmlBody, + OffsetDateTime receivedDateTime) {} diff --git a/connectors/email/src/test/java/io/camunda/connector/email/client/jakarta/JakartaExecutorTest.java b/connectors/email/src/test/java/io/camunda/connector/email/client/jakarta/JakartaExecutorTest.java index 8b0a83e69e..354113b441 100644 --- a/connectors/email/src/test/java/io/camunda/connector/email/client/jakarta/JakartaExecutorTest.java +++ b/connectors/email/src/test/java/io/camunda/connector/email/client/jakarta/JakartaExecutorTest.java @@ -130,7 +130,8 @@ void executePop3ListEmails() throws MessagingException { null, "1", "", - List.of(""), + List.of(), + "", List.of(""), List.of(""), OffsetDateTime.now(), @@ -187,7 +188,8 @@ void executeImapListEmails() throws MessagingException { null, "1", "", - List.of(""), + List.of(), + "", List.of(""), List.of(""), OffsetDateTime.now(), @@ -242,7 +244,8 @@ void executePop3ReadEmail() throws MessagingException, IOException { new EmailBody("", "", List.of()), "1", "", - List.of(""), + List.of(), + "", List.of(""), List.of(""), OffsetDateTime.now(), @@ -296,7 +299,8 @@ void executeImapReadEmail() throws MessagingException, IOException { EmailBody.createBuilder().build(), "1", "", - List.of(""), + List.of(), + "", List.of(""), List.of(""), OffsetDateTime.now(), @@ -435,7 +439,8 @@ void executePop3SearchEmails() throws MessagingException, IOException { null, "1", "", - List.of(""), + List.of(), + "", List.of(""), List.of(""), OffsetDateTime.now(), @@ -490,7 +495,8 @@ void executeImapSearchEmails() throws MessagingException, IOException { null, "1", "", - List.of(""), + List.of(), + "", List.of(""), List.of(""), OffsetDateTime.now(), diff --git a/connectors/email/src/test/java/io/camunda/connector/email/client/jakarta/TestMessage.java b/connectors/email/src/test/java/io/camunda/connector/email/client/jakarta/TestMessage.java index 04280a9fce..f4bfbf499d 100644 --- a/connectors/email/src/test/java/io/camunda/connector/email/client/jakarta/TestMessage.java +++ b/connectors/email/src/test/java/io/camunda/connector/email/client/jakarta/TestMessage.java @@ -7,7 +7,12 @@ package io.camunda.connector.email.client.jakarta; import jakarta.activation.DataHandler; -import jakarta.mail.*; +import jakarta.mail.Address; +import jakarta.mail.Flags; +import jakarta.mail.Header; +import jakarta.mail.Message; +import jakarta.mail.MessagingException; +import jakarta.mail.Multipart; import jakarta.mail.internet.InternetAddress; import java.io.IOException; import java.io.InputStream; @@ -208,7 +213,17 @@ public void removeHeader(String header_name) throws MessagingException {} @Override public Enumeration
getAllHeaders() throws MessagingException { - return null; + return new Enumeration<>() { + @Override + public boolean hasMoreElements() { + return false; + } + + @Override + public Header nextElement() { + return null; + } + }; } @Override