Get a process variable of type "File" in a java class and attach this file to an email

Hello,

I have the following scenario:

  1. I have a process comprised of two service task activities, both implemented by a seperate java class.
    image

2)The first service task, creates a pdf file → File file=new File(“mypdf.pdf”)
Inside this class, I set a variable named “file” that has as value the created pdf file.

The code is the following:

import java.io.File;
import java.io.FileOutputStream;

import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import org.camunda.bpm.engine.variable.Variables;
import org.camunda.bpm.engine.variable.value.FileValue;

import com.itextpdf.text.Document;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

public class PDFDemo implements JavaDelegate {
	public void execute (DelegateExecution execution) throws Exception{
		try {
			//get the process variable "name"
			String name= (String) execution.getVariable("name");
			System.out.println("PDF preparation");
			
			//create a new document and set the path
			Document document=new Document();
			File file=new File("mypdf.pdf");
			PdfWriter.getInstance(document, new FileOutputStream(file));
			
			//open the document and add text
			document.open();
			document.add(new Paragraph("Hello "+name));
			
			
			PdfPTable table=new PdfPTable(2);
			PdfPCell c1=new PdfPCell(new Paragraph("name"));
			PdfPCell c2=new PdfPCell(new Paragraph("Image"));
		
			table.addCell(c1);
			table.addCell(c2);

			document.add(table);
			document.close();
			
			System.out.println("Successfully created");
			
			
			FileValue typedFileValue = Variables
					  .fileValue("myfile.pdf")
					  .file(file)
					  .mimeType("text/plain")
					  .encoding("UTF-8")
					  .create();
			
			//create a process variable that contains the pdf
			execution.setVariable("file", typedFileValue);
			
			}catch (Exception e) {
				System.out.println("Error occured");
			}

	}
}
  1. The previous service task creates a variable named “file”, that in cockpit looks like this:

Until now, the pdf file has been created successfully.

  1. Next, I want to get this variable “file”, in the second service task and attach it to the body of an email.
    For this purpose, I have the following class:
import java.io.File;
import java.io.InputStream;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import org.camunda.bpm.engine.ProcessEngine;
import org.camunda.bpm.engine.ProcessEngines;
import org.camunda.bpm.engine.RuntimeService;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import org.camunda.bpm.engine.variable.value.FileValue;


public class SendEmail implements JavaDelegate {
	public void execute (DelegateExecution execution) throws Exception{
		
			String email= (String) execution.getVariable("email");
			System.out.println("Email preparation to "+email);
			
			Properties properties=new Properties();
			
			properties.put("mail.smtp.auth", "true");
			properties.put("mail.smtp.starttls.enable", "true");
			properties.put("mail.smtp.host", "smtp.gmail.com");
			properties.put("mail.smtp.port", "587");
			properties.put("mail.smtp.ssl.trust", "smtp.gmail.com");
			
			String myAccountEmail="someone@gmail.com";
			String password="******";
			
			Session session=Session.getInstance(properties, new Authenticator() {
				@Override
				protected PasswordAuthentication getPasswordAuthentication() {
					return new PasswordAuthentication(myAccountEmail,password);
				}
			});
			
			ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
			RuntimeService runtimeService=processEngine.getRuntimeService();
			
			FileValue retrievedTypedFileValue = runtimeService.getVariableTyped(execution.getId(), "file");
			InputStream fileContent = retrievedTypedFileValue.getValue(); 
			
			
			Message message= prepareMessage (session, myAccountEmail, email, fileContent);
			
			
			try {
				Transport.send(message);
				System.out.println("Message sent successfully");
			} catch (MessagingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				System.out.println("Message was not send");
			}	
	}
	

	private static Message prepareMessage(Session session, String myAccountEmail, String recipient,InputStream file) {
		try {
			Message message=new MimeMessage(session);
			message.setFrom(new InternetAddress(myAccountEmail));
			message.setRecipient(Message.RecipientType.TO, new InternetAddress (recipient));
			message.setSubject("Uom Bank - Loan Application");
			//message.setText("Your application has been created.");
			
			Multipart emailContent=new MimeMultipart();
			
			
			
			//text body part
			MimeBodyPart textBodyPart=new MimeBodyPart();
			textBodyPart.setText("Thank you for trusting us.You will find your contract attached.");
			
			//Attachment body part
			MimeBodyPart pdfAttachment=new MimeBodyPart();
			pdfAttachment.attachFile(file);
			
			//Attach body parts
			emailContent.addBodyPart(textBodyPart);
			emailContent.addBodyPart(pdfAttachment);
			
			//Attach multipart to message
			message.setContent(emailContent);
			
			return message;
			
			
		} catch (Exception ex) {
			Logger.getLogger(SendEmail.class.getName()).log(Level.SEVERE,null, ex);
		}
		return null;
	}
}

More precisely, I try to fetch a process variable of type “File” named “file” and attach it to the body of the email. At first I fetch the process variable (marked with green on the following image) , then I send the file as a parameter to the method PrepareMessage() (marked with red), and finally I attach this file to the body of the email (marked with blue).

However there is an error, since the method attachFile() (MARKED WITH BLUE ABOVE) waits for an argmunet of type “File”, while I am passing a variable of type “InputStream”.

Even if the process variable is of type “File” in Cockpit, inside my java code I fetch this variable as “FileValue” and “InputStream”. Is there any way to make my process variable of type “File” inside my java code? Or to chane the “InputStream” variable to type “File”?

If you could help me on that, I would appreciate it so much, since I can not find a solution!!
Thank you in advance,

Smith.

1 Like

Hi,

have you tried creating a temporary file with inputStream.

File new_file = new File("test.pdf");
					try(OutputStream outputStream = new FileOutputStream(new_file)){
					    IOUtils.copy(inputStream, outputStream);
					} catch (FileNotFoundException e) {
					    // handle exception here
					} catch (IOException e) {
					    // handle exception here
					}

then deleting that file once you send the email…

3 Likes

Thank you so much!!Indeed, it works.

Thank you again.

Regards,
Smith.

1 Like