Skip to main content

Email Library

Email Library

Email-utils is a set of utilities for working with various e-mail protocols. It allows you to send and receive e-mails as well as manage mailboxes using the following protocols:

  • SMTP
  • POP3
  • Exchane

Below there are three examples of how to use this library.

Important

In this article many parameters and credantials are declared in code. It is highly recommended to use ConfigurationService and VaultService to work with it in projects.

  1. Send a simple email via SMTP.

    SendSimpleEmailTask.java
    package eu.ibagroup.easyrpa.email.task;
    
    import eu.ibagroup.easyrpa.email.RobotEmail;
    import eu.ibagroup.easyrpa.engine.annotation.ApTaskEntry;
    import eu.ibagroup.easyrpa.engine.apflow.ApTask;
    import eu.ibagroup.easyrpa.engine.model.SecretCredentials;
    
    @ApTaskEntry(name = "Send Email using EmailUtils")
    public class SendSimpleEmailTask extends ApTask {
    
    	private static final String RECIPIENTS = "abc@gmail.com";
    
    	private static final String SUBJECT = "Test email";
    
    	private static final String EMAIL_SERVICE = "smtp.gmail.com:587";
    
    	private static final String EMAIL_SERVICE_PROTOCOL = "smtp_over_tsl";
    
    	private static final String SENDER_NAME = "EasyRPA Bot";
    
    	private static final String BODY = "This message was sent by EasyRPA Bot.";
    
    	@Override
    	public void execute() {
    
    		SecretCredentials secret = new SecretCredentials("example@gmail.com", "password");
    
    		RobotEmail emailSender = new RobotEmail();
    		emailSender.setCredentials(secret);
    		emailSender.setEmailService(EMAIL_SERVICE);
    		emailSender.setEmailServiceProtocol(EMAIL_SERVICE_PROTOCOL);
    		emailSender.setSender(secret.getUser());
    
    		emailSender.subject(SUBJECT).recipients(RECIPIENTS).body(BODY).setSenderName(SENDER_NAME);
    		emailSender.send();
    	}
    }
    	
  2. Generate a table in the body of the message using ftl-template, css and send via SMTP.

    In this approach, you have to create a robot class that extends RobotEmail, override the beforeSend() method, configure the robot in this method and then call the send() method from its object.

    RobotEmail uses FreeMarker to generate the message body code. Read more about FreeMarker and ftl templates here.

    SendFtlEmailTask.java
    package eu.ibagroup.easyrpa.email.task;
    
    import eu.ibagroup.easyrpa.email.entities.Book;
    import eu.ibagroup.easyrpa.email.robot.SendFtlEmailRobot;
    import eu.ibagroup.easyrpa.engine.annotation.ApTaskEntry;
    import eu.ibagroup.easyrpa.engine.apflow.ApTask;
    import eu.ibagroup.easyrpa.engine.model.SecretCredentials;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.UUID;
    
    @ApTaskEntry(name = "Generate Email Report")
    public class SendFtlEmailTask extends ApTask {
    
    	@Override
    	public void execute() {
    		try {
    			List<Book> books = getBooks();
    
    			SendFtlEmailRobot robot = new SendFtlEmailRobot(new SecretCredentials("example@gmail.com", "password"));
    			robot.setDebtorsList(books).send();
    		} catch (Exception e) {
    			handleStepError(e);
    		}
    	}
    
    	// prepare test data
    	private List<Book> getBooks() {
    		Book thinkingInJava = new Book(UUID.randomUUID().toString(), "Thinking in Java", "Bruce Eckel");
    		Book cipollino = new Book(UUID.randomUUID().toString(), "Le avventure di Cipollino", "Giovanni Francesco Rodari");
    		Book wadAndPeace = new Book(UUID.randomUUID().toString(), "War and Peace", "Lev Tolstoy");
    
    		List<Book> books = Arrays.asList(thinkingInJava, cipollino, wadAndPeace);
    		return books;
    	}
    }
    
    
    SendFtlEmailRobot.java
    package eu.ibagroup.easyrpa.email.robot;
    
    import com.google.common.io.Resources;
    import eu.ibagroup.easyrpa.email.RobotEmail;
    import eu.ibagroup.easyrpa.email.entities.Book;
    import eu.ibagroup.easyrpa.engine.model.SecretCredentials;
    
    import java.io.IOException;
    import java.net.URL;
    import java.nio.charset.StandardCharsets;
    import java.util.Arrays;
    import java.util.List;
    
    public class SendFtlEmailRobot extends RobotEmail {
    
    	private static final String TEMPLATE_FILE_PATH = "books.email.tpl/books.ftl";
    
    	private static final String RECIPIENTS = "timy2517@gmail.com";
    
    	private static final String SUBJECT = "Book list";
    
    	private static final String EMAIL_SERVICE = "smtp.gmail.com:587";
    
    	private static final String EMAIL_SERVICE_PROTOCOL = "smtp_over_tsl";
    
    	private static final String SENDER_NAME = "EasyRPA Bot";
    
    	// typeName is a prefix for the parameters of a specific robot in the
    	// configuration file
    	private static final String TYPE_NAME = "books_email";
    
    	private List<Book> books;
    
    	private SecretCredentials secret;
    
    	public SendFtlEmailRobot(SecretCredentials secret) {
    		super();
    		this.secret = secret;
    		setTypeName(TYPE_NAME);
    	}
    
    	public SendFtlEmailRobot setDebtorsList(List<Book> books) {
    		this.books = books;
    		return this;
    	}
    
    	@Override
    	protected void beforeSend() {
    		setRecipients(Arrays.asList(RECIPIENTS));
    		setCredentials(secret);
    		subject(SUBJECT);
    		setEmailService(EMAIL_SERVICE);
    		setEmailServiceProtocol(EMAIL_SERVICE_PROTOCOL);
    		sender(secret.getUser());
    		senderName(SENDER_NAME);
    
    		URL url = Resources.getResource(TEMPLATE_FILE_PATH);
    		String body = null;
    		try {
    			body = Resources.toString(url, StandardCharsets.UTF_8);
    		} catch (IOException e) {
    			// do something
    		}
    		body(body);
    		property("books", books);
    	}
    }
     

    The source code of the template and css:

    books.ftl
    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<#include "books.email.tpl/books.css">
    </head>
    <body>
    
    <div class="container">
    	<table class="responsive-table">
    	<caption>Books</caption>
    	<thead>
    		<tr>
    		<th scope="col">Name</th>
    		<th scope="col">Author</th>
    		</tr>
    	</thead>
    	<tbody>
    		<#list books as book>
    		<tr>
    		<td data-title="Name">${book.name}</td>
    		<td data-title="Author">${book.author}</td>
    		</tr>
    		</#list>
    	</tbody>
    	</table>
    </div>
    
    </body>
    </html>
    books.css
    <style>
    body {
    	background: #fafafa url(https://jackrugile.com/images/misc/noise-diagonal.png);
    	color: #444;
    	font: 100%/30px 'Helvetica Neue', helvetica, arial, sans-serif;
    	text-shadow: 0 1px 0 #fff;
    }
    
    strong {
    	font-weight: bold;
    }
    
    em {
    	font-style: italic;
    }
    
    table {
    	background: #f5f5f5;
    	border-collapse: separate;
    	box-shadow: inset 0 1px 0 #fff;
    	font-size: 14px;
    	line-height: 24px;
    	margin: 30px auto;
    	text-align: center;
    	width: 800px;
    }
    
    caption {
    	 font-size: 18px;
    	 font-weight: bold;
    	 }
    
    th {
    	background: url(https://jackrugile.com/images/misc/noise-diagonal.png), linear-gradient(#777, #444);
    	border-left: 1px solid #555;
    	border-right: 1px solid #777;
    	border-top: 1px solid #555;
    	border-bottom: 1px solid #333;
    	box-shadow: inset 0 1px 0 #999;
    	color: #fff;
    	font-weight: bold;
    	padding: 10px 15px;
    	position: relative;
    	text-shadow: 0 1px 0 #000;
    }
    
    th:after {
    	background: linear-gradient(rgba(255,255,255,0), rgba(255,255,255,.08));
    	content: '';
    	display: block;
    	height: 25%;
    	left: 0;
    	margin: 1px 0 0 0;
    	position: absolute;
    	top: 25%;
    	width: 100%;
    }
    
    th:first-child {
    	border-left: 1px solid #777;
    	box-shadow: inset 1px 1px 0 #999;
    }
    
    th:last-child {
    	box-shadow: inset -1px 1px 0 #999;
    }
    
    td {
    	border-right: 1px solid #fff;
    	border-left: 1px solid #e8e8e8;
    	border-top: 1px solid #fff;
    	border-bottom: 1px solid #e8e8e8;
    	padding: 10px 15px;
    	position: relative;
    	transition: all 300ms;
    }
    
    td:first-child {
    	box-shadow: inset 1px 0 0 #fff;
    }
    
    td:last-child {
    	border-right: 1px solid #e8e8e8;
    	box-shadow: inset -1px 0 0 #fff;
    }
    
    tr {
    	background: url(https://jackrugile.com/images/misc/noise-diagonal.png);
    }
    
    tr:nth-child(odd) td {
    	background: #f1f1f1 url(https://jackrugile.com/images/misc/noise-diagonal.png);
    }
    
    tr:last-of-type td {
    	box-shadow: inset 0 -1px 0 #fff;
    }
    
    tr:last-of-type td:first-child {
    	box-shadow: inset 1px -1px 0 #fff;
    }
    
    tr:last-of-type td:last-child {
    	box-shadow: inset -1px -1px 0 #fff;
    }
    
    tbody:hover td {
    	color: transparent;
    	text-shadow: 0 0 3px #aaa;
    }
    
    tbody:hover tr:hover td {
    	color: #444;
    	text-shadow: 0 1px 0 #fff;
    }
    
    </style>

    Result Email:

     
  3. Receive mails and mailbox folder list via POP3 protocol.

    ReadEmailTask.java
    package eu.ibagroup.easyrpa.email.task;
    
    import eu.ibagroup.easyrpa.email.EmailClientProvider;
    import eu.ibagroup.easyrpa.email.message.EmailMessage;
    import eu.ibagroup.easyrpa.email.service.javax.ImapPop3EmailClient;
    import eu.ibagroup.easyrpa.engine.annotation.ApTaskEntry;
    import eu.ibagroup.easyrpa.engine.apflow.ApTask;
    import eu.ibagroup.easyrpa.engine.model.SecretCredentials;
    import eu.ibagroup.easyrpa.engine.service.ConfigurationService;
    import lombok.extern.slf4j.Slf4j;
    
    import javax.mail.search.AndTerm;
    import javax.mail.search.ComparisonTerm;
    import javax.mail.search.ReceivedDateTerm;
    import javax.mail.search.SearchTerm;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.List;
    
    @ApTaskEntry(name = "Read Email using EmailUtils")
    @Slf4j
    public class ReadEmailTask extends ApTask {
    	private static final String EMAIL_SERVICE = "imap.gmail.com:993";
    
    	private static final String EMAIL_SERVICE_PROTOCOL = "imap";
    
    	@Override
    	public void execute() {
    		ConfigurationService cfg = getConfigurationService();
    		SecretCredentials credentials = new SecretCredentials("example@gmail.com", "password");
    
    		EmailClientProvider emailScanner = new EmailClientProvider(cfg, credentials);
    		emailScanner.setEmailService(EMAIL_SERVICE);
    		emailScanner.setEmailServiceProtocol(EMAIL_SERVICE_PROTOCOL);
    
    		ImapPop3EmailClient client = (ImapPop3EmailClient) emailScanner.getClient();
    
    		// Now you can implement any search logic and call ImapPop3EmailClient method
    		// e.g.
    		// Get list of folders
    		log.info("List of folders: " + client.fetchFolderList().toString());
    		// Fetch all messages from the 'INBOX' folder during the last 3 days
    		Date currentDate = new Date();
    		Calendar cal = Calendar.getInstance();
    		cal.setTime(currentDate);
    		cal.add(Calendar.DATE, -3);
    		Date fromDate = cal.getTime();
    
    		cal.setTime(currentDate);
    		cal.add(Calendar.DATE, 1);
    		Date toDate = cal.getTime();
    		SearchTerm olderThanTerm = new ReceivedDateTerm(ComparisonTerm.LE, toDate);
    		SearchTerm newerThanTerm = new ReceivedDateTerm(ComparisonTerm.GE, fromDate);
    
    		SearchTerm dateRangeTerm = new AndTerm(olderThanTerm, newerThanTerm);
    
    		List<EmailMessage> messages = client.searchMessages("INBOX", dateRangeTerm);
    		for (EmailMessage msg : messages) {
    			log.info(msg.getSubject());
    		}
    
    	}
    }
    
    

    Other project files required to launch the example:

    SendEmailsAp
    package eu.ibagroup.easyrpa.email;
    
    import eu.ibagroup.easyrpa.email.task.SendNotificationEmailTask;
    import eu.ibagroup.easyrpa.engine.annotation.ApModuleEntry;
    import eu.ibagroup.easyrpa.engine.apflow.ApModule;
    import eu.ibagroup.easyrpa.engine.apflow.TaskOutput;
    
    @ApModuleEntry(name = "KB - Test EmailUtils")
    public class SendEmailsAp extends ApModule {
    
    	// change ReadEmail.class to any of the two remaining task-classes
    	public TaskOutput run() throws Exception {
    		return execute(getInput(), SendNotificationEmailTask.class).get();
    	}
    }
     
    LocalRunner.java
    package eu.ibagroup.easyrpa.email;
    
    import eu.ibagroup.easyrpa.engine.boot.ApModuleRunner;
    
    public class LocalRunner {
    
    	public static void main(String[] args) {
    		ApModuleRunner.localLaunch(SendEmailsAp.class);
    	}
    }