Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(email-connector): add document handling to the email connector #3645

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,30 @@
},
"tooltip" : "Email's Html content",
"type" : "Text"
}, {
"id" : "attachmentsSmtp",
"label" : "Attachment",
"description" : "Email's attachment. e.g., =[ document1, document2]",
"optional" : true,
"feel" : "required",
"group" : "sendEmailSmtp",
"binding" : {
"name" : "data.smtpAction.attachments",
"type" : "zeebe:input"
},
"condition" : {
"allMatch" : [ {
"property" : "data.smtpActionDiscriminator",
"equals" : "sendEmailSmtp",
"type" : "simple"
}, {
"property" : "protocol",
"equals" : "smtp",
"type" : "simple"
} ]
},
"tooltip" : "Email's attachments, should be set as a list ",
"type" : "String"
}, {
"id" : "pop3maxToBeRead",
"label" : "Maximum number of emails to be read",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,30 @@
},
"tooltip" : "Email's Html content",
"type" : "Text"
}, {
"id" : "attachmentsSmtp",
"label" : "Attachment",
"description" : "Email's attachment. e.g., =[ document1, document2]",
"optional" : true,
"feel" : "required",
"group" : "sendEmailSmtp",
"binding" : {
"name" : "data.smtpAction.attachments",
"type" : "zeebe:input"
},
"condition" : {
"allMatch" : [ {
"property" : "data.smtpActionDiscriminator",
"equals" : "sendEmailSmtp",
"type" : "simple"
}, {
"property" : "protocol",
"equals" : "smtp",
"type" : "simple"
} ]
},
"tooltip" : "Email's attachments, should be set as a list ",
"type" : "String"
}, {
"id" : "pop3maxToBeRead",
"label" : "Maximum number of emails to be read",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
*/
package io.camunda.connector.email.client;

import io.camunda.connector.email.outbound.model.EmailRequest;
import io.camunda.connector.api.outbound.OutboundConnectorContext;

public interface EmailActionExecutor {
Object execute(EmailRequest emailRequest);
Object execute(OutboundConnectorContext context);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@
*/
package io.camunda.connector.email.client.jakarta.inbound;

import io.camunda.connector.api.inbound.ActivationCheckResult;
import io.camunda.connector.api.inbound.InboundConnectorContext;
import io.camunda.connector.email.authentication.Authentication;
import io.camunda.connector.email.client.jakarta.models.Email;
import io.camunda.connector.email.client.jakarta.utils.JakartaUtils;
import io.camunda.connector.email.inbound.model.*;
import io.camunda.connector.email.response.ReadEmailResponse;
import io.camunda.document.Document;
import io.camunda.document.store.DocumentCreationRequest;
import jakarta.mail.*;
import jakarta.mail.search.FlagTerm;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import org.eclipse.angus.mail.imap.IMAPMessage;
import org.slf4j.Logger;
Expand Down Expand Up @@ -144,6 +148,7 @@ private void processMail(IMAPMessage message, PollingConfig pollingConfig) {

private void correlateEmail(Message message, InboundConnectorContext connectorContext) {
Email email = this.jakartaUtils.createEmail(message);
List<Document> documents = this.createDocumentList(email, connectorContext);
connectorContext.correlateWithResult(
new ReadEmailResponse(
email.messageId(),
Expand All @@ -153,9 +158,36 @@ private void correlateEmail(Message message, InboundConnectorContext connectorCo
email.size(),
email.body().bodyAsPlainText(),
email.body().bodyAsHtml(),
documents,
email.receivedAt()));
}

private List<Document> createDocumentList(Email email, InboundConnectorContext connectorContext) {
if (!(connectorContext.canActivate(
new ReadEmailResponse(
email.messageId(),
email.from(),
email.headers(),
email.subject(),
email.size(),
email.body().bodyAsPlainText(),
email.body().bodyAsHtml(),
List.of(),
email.receivedAt()))
instanceof ActivationCheckResult.Success)) {
return List.of();
} else
return email.body().attachments().stream()
.map(
document ->
connectorContext.createDocument(
DocumentCreationRequest.from(document.inputStream())
.contentType(document.contentType())
.fileName(document.name())
.build()))
.toList();
}

public long delay() {
return this.emailListenerConfig.pollingWaitTime().getSeconds();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,33 @@

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.camunda.connector.api.outbound.OutboundConnectorContext;
import io.camunda.connector.email.authentication.Authentication;
import io.camunda.connector.email.client.EmailActionExecutor;
import io.camunda.connector.email.client.jakarta.models.EmailAttachment;
import io.camunda.connector.email.client.jakarta.utils.JakartaUtils;
import io.camunda.connector.email.outbound.model.EmailRequest;
import io.camunda.connector.email.outbound.protocols.Protocol;
import io.camunda.connector.email.outbound.protocols.actions.*;
import io.camunda.connector.email.response.*;
import io.camunda.document.Document;
import io.camunda.document.store.DocumentCreationRequest;
import jakarta.activation.DataHandler;
import jakarta.activation.DataSource;
import jakarta.mail.*;
import jakarta.mail.internet.*;
import jakarta.mail.search.*;
import jakarta.mail.util.ByteArrayDataSource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Consumer;

public class JakartaEmailActionExecutor implements EmailActionExecutor {

private final JakartaUtils jakartaUtils;
private final ObjectMapper objectMapper;
private OutboundConnectorContext connectorContext;

private JakartaEmailActionExecutor(JakartaUtils jakartaUtils, ObjectMapper objectMapper) {
this.jakartaUtils = jakartaUtils;
Expand All @@ -36,7 +46,9 @@
return new JakartaEmailActionExecutor(sessionFactory, objectMapper);
}

public Object execute(EmailRequest emailRequest) {
public Object execute(OutboundConnectorContext context) {

Check notice

Code scanning / CodeQL

Missing Override annotation Note

This method overrides
EmailActionExecutor.execute
; it is advisable to add an Override annotation.
this.connectorContext = context;
EmailRequest emailRequest = context.bindVariables(EmailRequest.class);
Authentication authentication = emailRequest.authentication();
Protocol protocol = emailRequest.data();
Action action = protocol.getProtocolAction();
Expand Down Expand Up @@ -93,6 +105,7 @@
email.size(),
email.body().bodyAsPlainText(),
email.body().bodyAsHtml(),
this.createDocumentList(email.body().attachments(), connectorContext),
email.receivedAt()))
.orElseThrow(() -> new MessagingException("Could not find an email ID"));
}
Expand Down Expand Up @@ -196,6 +209,8 @@
email.size(),
email.body().bodyAsPlainText(),
email.body().bodyAsHtml(),
this.createDocumentList(
email.body().attachments(), this.connectorContext),
email.receivedAt()))
.orElseThrow(() -> new MessagingException("No emails have been found with this ID"));
}
Expand Down Expand Up @@ -257,6 +272,9 @@
headers.ifPresent(stringObjectMap -> setMessageHeaders(stringObjectMap, message));
message.setSubject(smtpSendEmail.subject());
Multipart multipart = getMultipart(smtpSendEmail);
if (!Objects.isNull(smtpSendEmail.attachments())) {
smtpSendEmail.attachments().forEach(getDocumentConsumer(multipart));
}
message.setContent(multipart);
try (Transport transport = session.getTransport()) {
this.jakartaUtils.connectTransport(transport, authentication);
Expand Down Expand Up @@ -362,4 +380,32 @@
"Unexpected value: " + object + ". List or String was expected");
});
}

private Consumer<Document> getDocumentConsumer(Multipart multipart) {
return document -> {
try {
BodyPart attachment = new MimeBodyPart();
DataSource dataSource =
new ByteArrayDataSource(document.asInputStream(), document.metadata().getContentType());
attachment.setDataHandler(new DataHandler(dataSource));
attachment.setFileName(document.metadata().getFileName());
multipart.addBodyPart(attachment);
} catch (IOException | MessagingException e) {
throw new RuntimeException(e);
}
};
}

private List<Document> createDocumentList(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's a code in PollingManager that looks like this one, do we want to re this function in the PollingManager?

List<EmailAttachment> attachments, OutboundConnectorContext connectorContext) {
return attachments.stream()
.map(
document ->
connectorContext.createDocument(
DocumentCreationRequest.from(document.inputStream())
.fileName(document.name())
.contentType(document.contentType())
.build()))
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ public EmailConnectorFunction(EmailActionExecutor emailActionExecutor) {

@Override
public Object execute(OutboundConnectorContext context) {
EmailRequest emailRequest = context.bindVariables(EmailRequest.class);
return emailActionExecutor.execute(emailRequest);
return emailActionExecutor.execute(context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
import io.camunda.connector.generator.dsl.Property;
import io.camunda.connector.generator.java.annotation.TemplateProperty;
import io.camunda.connector.generator.java.annotation.TemplateSubType;
import io.camunda.document.Document;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;

@TemplateSubType(id = "sendEmailSmtp", label = "Send Email")
Expand Down Expand Up @@ -124,5 +126,16 @@ public record SmtpSendEmail(
property = "contentType",
oneOf = {"HTML", "MULTIPART"}))
@Valid
String htmlBody)
String htmlBody,
@TemplateProperty(
label = "Attachment",
group = "sendEmailSmtp",
id = "attachmentsSmtp",
tooltip = "Email's attachments, should be set as a list ",
type = TemplateProperty.PropertyType.String,
feel = Property.FeelMode.required,
optional = true,
description = "Email's attachment. e.g., =[ document1, document2]",
binding = @TemplateProperty.PropertyBinding(name = "data.smtpAction.attachments"))
List<Document> attachments)
implements SmtpAction {}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package io.camunda.connector.email.response;

import io.camunda.connector.email.client.jakarta.models.Header;
import io.camunda.document.Document;
import java.time.OffsetDateTime;
import java.util.List;

Expand All @@ -18,4 +19,5 @@ public record ReadEmailResponse(
Integer size,
String plainTextBody,
String htmlBody,
List<Document> attachments,
OffsetDateTime receivedDateTime) {}
Loading
Loading