Open, General and Highly Adaptative Messaging library.
It is a reusable Java library in charge of sending any kind of message (email, SMS, mobile notification, tweet, SNMP...). The content of the message can follow any templating engine convention (Thymeleaf, FreeMarker, ...). The library also provides bridges for framework integration (Spring, JSF, ...). It is designed to be easily extended.
Several libraries for sending email already exist (Apache Commons Email, Simple Java Mail/Vesijama, Spring Email Integration...). These libraries help you send an email but if you want to use a templated content, you will have to manually integrate a template engine.
These libraries also provide only implementations based on Java Mail API. But in some environments, you might NOT want to send the email directly but to use a web service to do it for you (SendGrid for example). Furthermore, those libraries are bound by design to frameworks or libraries that you might not want to use in your own context.
So, now you would want to find a sending library with a high level of abstraction to avoid binding issues with any template engine, design framework or sender service... Is email the only possible message type ? No, so why not sending SMS, Tweet or anything the same way ?
This module is designed for handling any kind of message the same way. It also provides several implementations for the same message type. It selects the best implementation based on the classpath or properties for example. You can easily add your own implementation.
It also provides templating support and integrates natively several template engines. You can also add your own.
It is framework and library agnostic but provides bridges for common frameworks integration (Spring, JSF, ...).
When using the module to send email based on an HTML template, the templating system let you design your HTML like a standard HTML page. It automatically transforms the associated resources (images, css files...) to be usable in an email context (automatic inline css, embed images...). You don't need to write your HTML specifically for email.
Send email
- Basic email
- Email with template
- Email with attachments
- Both HTML and text content
- Extract subject from template
Send SMS
- Basic SMS
- SMS with template
- Extract subject from template
Templating
- Multi-template engine support
- Internalize template CSS and images for you
Managing lookup prefixes like JNDI
- For templates
- For resources
- For attachments
Automatic configuration
- Automatically detect email implementation to use
- Automatically detect SMS implementation to use
- Automatically detect template engine to use
Integration with Spring
Extensible
- Add your own message sender
- Integrate your own template engine
- Many other possible extensions
This section describes how to use the library with no framework and default behavior.
To include the library in your project, you just have to add the dependency to your pom.xml:
...
<dependencies>
...
<dependency>
<groupId>fr.sii.ogham</groupId>
<artifactId>ogham-core</artifactId>
<version>1.1.0</version>
</dependency>
...
</dependencies>
...
The samples are available in the sample-standard-usage sub-project.
All these samples show how to send email through SMTP. See configuration to know how to send email using another implementation.
This sample shows how to send a basic email. The sample is available here.
The first lines configure the properties that will be used by the sender. Then you must create the service. You can use the MessagingBuilder to help you to create the service. Finally, the last line sends the email. The specified email is really basic. It only contains the subject, the textual content and the receiver address. The sender address is automatically added to the email by the service based on configuration properties.
See other examples for advanced usages (using a templated content or adding attachments).
package fr.sii.ogham.sample.standard.email;
import java.util.Properties;
import fr.sii.ogham.core.builder.MessagingBuilder;
import fr.sii.ogham.core.exception.MessagingException;
import fr.sii.ogham.core.service.MessagingService;
import fr.sii.ogham.email.message.Email;
public class BasicSample {
public static void main(String[] args) throws MessagingException {
// configure properties (could be stored in a properties file or defined
// in System properties)
Properties properties = new Properties();
properties.put("mail.smtp.host", "<your server host>");
properties.put("mail.smtp.port", "<your server port>");
properties.put("ogham.email.from", "<email address to display for the sender user>");
// Instantiate the messaging service using default behavior and
// provided properties
MessagingService service = new MessagingBuilder().useAllDefaults(properties).build();
// send the email
service.send(new Email("subject", "email content", "<recipient address>"));
}
}
If you prefer, you can also use the fluent API:
package fr.sii.ogham.sample.standard.email;
import java.util.Properties;
import fr.sii.ogham.core.builder.MessagingBuilder;
import fr.sii.ogham.core.exception.MessagingException;
import fr.sii.ogham.core.service.MessagingService;
import fr.sii.ogham.email.message.Email;
public class BasicSample {
public static void main(String[] args) throws MessagingException {
// configure properties (could be stored in a properties file or defined
// in System properties)
Properties properties = new Properties();
properties.put("mail.smtp.host", "<your server host>");
properties.put("mail.smtp.port", "<your server port>");
properties.put("ogham.email.from", "<email address to display for the sender user>");
// Instantiate the messaging service using default behavior and
// provided properties
MessagingService service = new MessagingBuilder().useAllDefaults(properties).build();
// send the email
service.send(new Email().
subject("subject").
content("email content").
to("<recipient address>"));
}
}
This sample shows how to send a basic email. The sample is available here.
If you want to put properties in a configuration file, you can create a properties file (email.properties for example) in src/main/resources folder with the following content:
mail.smtp.host=<your server host>
mail.smtp.port=<your server port>
ogham.email.from=<email address to display for the sender user>
And then load these properties before creating messaging service:
package fr.sii.ogham.sample.standard.email;
import java.io.IOException;
import java.util.Properties;
import fr.sii.ogham.core.builder.MessagingBuilder;
import fr.sii.ogham.core.exception.MessagingException;
import fr.sii.ogham.core.service.MessagingService;
import fr.sii.ogham.email.message.Email;
public class BasicSampleExternalProperties {
public static void main(String[] args) throws MessagingException, IOException {
// load properties (available at src/main/resources)
Properties properties = new Properties();
properties.load(BasicSampleExternalProperties.class.getResourceAsStream("/email.properties"));
// Instantiate the messaging service using default behavior and
// provided properties
MessagingService service = new MessagingBuilder().useAllDefaults(properties).build();
// send the email
service.send(new Email("subject", "email content", "<recipient address>"));
// or using fluent API
service.send(new Email().
subject("subject").
content("email content").
to("<recipient address>"));
}
}
This sample shows how to send a basic email through GMail. The sample is available here.
The first lines configure the properties that will be used by the sender. Then you must create the service. You can use the MessagingBuilder to help you to create the service. Finally, the last line sends the email. The specified email is really basic. It only contains the subject, the textual content and the receiver address. The sender address is automatically added to the email by the service based on configuration properties.
See other examples for advanced usages (using a templated content or adding attachments).
package fr.sii.ogham.sample.standard.email.gmail;
import java.util.Properties;
import fr.sii.ogham.core.builder.MessagingBuilder;
import fr.sii.ogham.core.exception.MessagingException;
import fr.sii.ogham.core.service.MessagingService;
import fr.sii.ogham.email.message.Email;
public class BasicGmailSSLSample {
public static void main(String[] args) throws MessagingException {
// configure properties (could be stored in a properties file or defined
// in System properties)
Properties properties = new Properties();
properties.setProperty("mail.smtp.auth", "true");
properties.setProperty("mail.smtp.host", "smtp.gmail.com");
properties.setProperty("mail.smtp.port", "465");
properties.setProperty("mail.smtp.socketFactory.port", "465");
properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
properties.setProperty("ogham.email.authenticator.username", "<your gmail username>");
properties.setProperty("ogham.email.authenticator.password", "<your gmail password>");
properties.setProperty("ogham.email.from", "<your gmail address>");
// Instantiate the messaging service using default behavior and
// provided properties
MessagingService service = new MessagingBuilder().useAllDefaults(properties).build();
// send the email
service.send(new Email("subject", "email content", "<recipient address>"));
// or using fluent API
service.send(new Email().
subject("subject").
content("email content").
to("<recipient address>"));
}
}
This sample shows how to send an email with a content following a template engine language. The sample is available here.
The first lines configure the properties that will be used by the sender. Then you must create the service. You can use the MessagingBuilder to help you to create the service. Finally, the last line sends the email. The specified email is really basic too. It only contains the subject, the content based on a templated content available in the classpath, a bean to use as source of variable substitutions and the receiver address. The sender address is automatically added to the email by the service based on configuration properties.
See other examples for advanced usages (adding attachments).
package fr.sii.ogham.sample.standard.email;
import java.util.Properties;
import fr.sii.ogham.context.SimpleBean;
import fr.sii.ogham.core.builder.MessagingBuilder;
import fr.sii.ogham.core.exception.MessagingException;
import fr.sii.ogham.core.message.content.TemplateContent;
import fr.sii.ogham.core.service.MessagingService;
import fr.sii.ogham.email.message.Email;
public class HtmlTemplateSample {
public static void main(String[] args) throws MessagingException {
// configure properties (could be stored in a properties file or defined
// in System properties)
Properties properties = new Properties();
properties.setProperty("mail.smtp.host", "<your server host>");
properties.setProperty("mail.smtp.port", "<your server port>");
properties.setProperty("ogham.email.from", "<email address to display for the sender user>");
// Instantiate the messaging service using default behavior and
// provided properties
MessagingService service = new MessagingBuilder().useAllDefaults(properties).build();
// send the email
service.send(new Email("subject", new TemplateContent("classpath:/template/thymeleaf/simple.html", new SimpleBean("foo", 42)), "<recipient address>"));
// or using fluent API
service.send(new Email().
subject("subject").
content(new TemplateContent("classpath:/template/thymeleaf/simple.html", new SimpleBean("foo", 42))).
to("<recipient address>"));
}
}
Here is the templated content:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8" />
</head>
<body>
<h1 class="title" th:text="${name}"></h1>
<p class="text" th:text="${value}"></p>
</body>
</html>
The template is available here
This sample is a variant of the previous one. It allows you to directly use the HTML title as subject of your email. It may be useful to use variables in the subject too, to mutualize the code and to avoid to create a new file just for one line.
package fr.sii.ogham.sample.standard.email;
import java.util.Properties;
import fr.sii.ogham.context.SimpleBean;
import fr.sii.ogham.core.builder.MessagingBuilder;
import fr.sii.ogham.core.exception.MessagingException;
import fr.sii.ogham.core.message.content.TemplateContent;
import fr.sii.ogham.core.service.MessagingService;
import fr.sii.ogham.email.message.Email;
public class HtmlTemplateWithSubjectSample {
public static void main(String[] args) throws MessagingException {
// configure properties (could be stored in a properties file or defined
// in System properties)
Properties properties = new Properties();
properties.setProperty("mail.smtp.host", "<your server host>");
properties.setProperty("mail.smtp.port", "<your server port>");
properties.setProperty("ogham.email.from", "<email address to display for the sender user>");
// Instantiate the messaging service using default behavior and
// provided properties
MessagingService service = new MessagingBuilder().useAllDefaults(properties).build();
// send the email
// subject is set to null to let automatic mechanism to read the title
// of the HTML and use it as subject of your email
service.send(new Email(null, new TemplateContent("classpath:/template/thymeleaf/simpleWithSubject.html", new SimpleBean("foo", 42)), "<recipient address>"));
// or using fluent API (do not set subject)
service.send(new Email().
content(new TemplateContent("classpath:/template/thymeleaf/simpleWithSubject.html", new SimpleBean("foo", 42))).
to("<recipient address>"));
}
}
Here is the templated content :
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Subject of the email</title>
<meta charset="utf-8" />
</head>
<body>
<h1 class="title" th:text="${name}"></h1>
<p class="text" th:text="${value}"></p>
</body>
</html>
You can look directly at the sample codes: Java and HTML.
This sample shows how to send an email with attached file. The sample is available here
The first lines configure the properties that will be used by the sender. Then you must create the service. You can use the MessagingBuilder to help you to create the service. Finally, the last line sends the email. The specified email is really basic too. It only contains the subject, the textual content, the receiver address and the attachment file that is available in the classpath. You may use several attachments too. The sender address is automatically added to the email by the service based on configuration properties.
package fr.sii.ogham.sample.standard.email;
import java.util.Properties;
import fr.sii.ogham.core.builder.MessagingBuilder;
import fr.sii.ogham.core.exception.MessagingException;
import fr.sii.ogham.core.service.MessagingService;
import fr.sii.ogham.email.attachment.Attachment;
import fr.sii.ogham.email.message.Email;
public class WithAttachmentSample {
public static void main(String[] args) throws MessagingException {
// configure properties (could be stored in a properties file or defined
// in System properties)
Properties properties = new Properties();
properties.put("mail.smtp.host", "<your server host>");
properties.put("mail.smtp.port", "<your server port>");
properties.put("ogham.email.from", "<email address to display for the sender user>");
// Instantiate the messaging service using default behavior and
// provided properties
MessagingService service = new MessagingBuilder().useAllDefaults(properties).build();
// send the email
service.send(new Email("subject", "content of the email", "<recipient address>", new Attachment("classpath:/attachment/test.pdf")));
// or using fluent API
service.send(new Email().
subject("subject").
content("content of the email").
to("<recipient address>").
attach(new Attachment("classpath:/attachment/test.pdf")));
}
}
Sending an email with HTML content and text content might be really important, at least for smartphones. When a smartphone receives an email, it displays the sender, the subject and also a preview of the message, using the text alternative. If the message is only HTML, the preview might be unreadable.
This sample shows how to provide both HTML content and text content. This sample is available here.
package fr.sii.ogham.sample.standard.email;
import java.util.Properties;
import fr.sii.ogham.core.builder.MessagingBuilder;
import fr.sii.ogham.core.exception.MessagingException;
import fr.sii.ogham.core.message.content.MultiContent;
import fr.sii.ogham.core.service.MessagingService;
import fr.sii.ogham.email.message.Email;
public class HtmlAndTextSample {
public static void main(String[] args) throws MessagingException {
// configure properties (could be stored in a properties file or defined
// in System properties)
Properties properties = new Properties();
properties.put("mail.smtp.host", "<your server host>");
properties.put("mail.smtp.port", "<your server port>");
properties.put("ogham.email.from", "<email address to display for the sender user>");
// Instantiate the messaging service using default behavior and
// provided properties
MessagingService service = new MessagingBuilder().useAllDefaults(properties).build();
// send the email
String html = "<!DOCTYPE html><html><head><meta charset=\"utf-8\" /></head><body><h1 class=\"title\">Hello World</h1><p class=\"text\">Foo bar</p></body></html>";
String text = "Hello World !\r\nFoo bar";
service.send(new Email("subject", new MultiContent(html, text), "<recipient address>"));
// or using fluent API
service.send(new Email().
subject("subject").
content(new MultiContent(html, text)).
to("<recipient address>"));
}
}
This sample shows how to provide both HTML content and text content following a template engine language. The sample shows the shorthand version that avoids specifying twice the path to the template. This sample is available here.
package fr.sii.ogham.sample.standard.email;
import java.util.Properties;
import fr.sii.ogham.context.SimpleBean;
import fr.sii.ogham.core.builder.MessagingBuilder;
import fr.sii.ogham.core.exception.MessagingException;
import fr.sii.ogham.core.message.content.MultiTemplateContent;
import fr.sii.ogham.core.service.MessagingService;
import fr.sii.ogham.email.message.Email;
public class HtmlAndTextTemplateSample {
public static void main(String[] args) throws MessagingException {
// configure properties (could be stored in a properties file or defined
// in System properties)
Properties properties = new Properties();
properties.setProperty("mail.smtp.host", "<your server host>");
properties.setProperty("mail.smtp.port", "<your server port>");
properties.setProperty("ogham.email.from", "<email address to display for the sender user>");
// Instantiate the messaging service using default behavior and
// provided properties
MessagingService service = new MessagingBuilder().useAllDefaults(properties).build();
// send the email
// Note that the extension of the template is not given. This version
// automatically takes the provided path and adds the '.html' extension
// for the HTML template and '.txt' for text template
service.send(new Email("subject", new MultiTemplateContent("classpath:/template/thymeleaf/simple", new SimpleBean("foo", 42)), "<recipient address>"));
// or using fluent API
service.send(new Email().
subject("subject").
content(new MultiTemplateContent("classpath:/template/thymeleaf/simple", new SimpleBean("foo", 42))).
to("<recipient address>"));
}
}
Here is the content of the HTML template (available here):
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8" />
</head>
<body>
<h1 class="title" th:text="${name}"></h1>
<p class="text" th:text="${value}"></p>
</body>
</html>
And the templated content (available here):
<html xmlns:th="http://www.thymeleaf.org" th:inline="text" th:remove="tag">
[[${name}]]
[[${value}]]
</html>
This sample combines all features:
- Uses templates (HTML and text templates)
- HTML template includes page fragments
- HTML template references external CSS and images
- The subject is directly extracted from template
- The email is sent with one attachment
Here is the Java code (available here):
package fr.sii.ogham.sample.standard.email;
import java.io.IOException;
import java.util.Properties;
import fr.sii.ogham.context.SimpleBean;
import fr.sii.ogham.core.builder.MessagingBuilder;
import fr.sii.ogham.core.exception.MessagingException;
import fr.sii.ogham.core.message.content.MultiTemplateContent;
import fr.sii.ogham.core.service.MessagingService;
import fr.sii.ogham.email.attachment.Attachment;
import fr.sii.ogham.email.message.Email;
public class FullSample {
public static void main(String[] args) throws MessagingException, IOException {
// configure properties from file
Properties properties = new Properties();
properties.load(FullSample.class.getResourceAsStream("/email-template.properties"));
// Instantiate the messaging service using default behavior and
// provided properties
MessagingService service = new MessagingBuilder().useAllDefaults(properties).build();
// send the email using fluent API
// @formatter:off
service.send(new Email().
content(new MultiTemplateContent("full", new SimpleBean("foo", 42))).
to("<recipient address>").
attach(new Attachment("/attachment/test.pdf")));
// @formatter:on
}
}
The loaded property file content:
# general SMTP server
mail.smtp.host=<your server host>
mail.smtp.port=<your server port>
# using with Gmail
#mail.smtp.auth=true
#mail.smtp.host=smtp.gmail.com
#mail.smtp.port=465
#mail.smtp.socketFactory.port=465
#mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
#ogham.email.authenticator.username=<your gmail username>
#ogham.email.authenticator.password=<your gmail password>
# ogham additional properties
ogham.email.from=<sender email address>
ogham.email.template.prefix=/template/thymeleaf/email/
The HTML template content is available here. The content of the HTML is not displayed entirely. Just useful parts are shown here:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<!-- Load fragment that contains external CSS -->
<head th:replace="fragments/header.html :: header"> </head>
<body id="body_2a02_0">
...
<!-- Use image -->
<img src="classpath:/resources/images/h1.gif" alt="Creating Email Magic" width="300" height="230" />
...
<!-- Use of variables and CSS classes that will be interned -->
<tr>
<td id="td_2a02_3">
<span class="name" th:text="${name}">${name}</span>
</td>
</tr>
<tr>
<td id="td_2a02_4" class="value" th:text="${value}">
</td>
</tr>
...
Now the content of the header (available here). The header contains the subject of the email (with title tag) and references external CSS files that will be interned directly in the HTML:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="header">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Full Sample</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link href="classpath:/resources/css/external1.css" rel="stylesheet" />
<link href="classpath:/resources/css/external2.css" rel="stylesheet" />
</head>
</html>
The content of the CSS files are not displayed here but can be found in samples. Useful classes are name
and value
.
The text template is available here.
The SMPP protocol is the standard way to send SMS. This sample defines two properties mandatory (system ID and password) by this protocol in order to use it. This sample is available here.
package fr.sii.ogham.sample.standard.sms;
import java.util.Properties;
import fr.sii.ogham.core.builder.MessagingBuilder;
import fr.sii.ogham.core.exception.MessagingException;
import fr.sii.ogham.core.service.MessagingService;
import fr.sii.ogham.sms.message.Sms;
public class BasicSample {
public static void main(String[] args) throws MessagingException {
// configure properties (could be stored in a properties file or defined
// in System properties)
Properties properties = new Properties();
properties.setProperty("ogham.sms.smpp.host", "<your server host>");
properties.setProperty("ogham.sms.smpp.port", "<your server port>");
properties.setProperty("ogham.sms.smpp.systemId", "<your server system ID>");
properties.setProperty("ogham.sms.smpp.password", "<your server password>");
properties.setProperty("ogham.sms.from", "<phone number to display for the sender>");
// Instantiate the messaging service using default behavior and
// provided properties
MessagingService service = new MessagingBuilder().useAllDefaults(properties).build();
// send the sms
service.send(new Sms("sms content", "<recipient phone number>"));
}
}
If you prefer, you can also use the fluent API:
package fr.sii.ogham.sample.standard.sms;
import java.util.Properties;
import fr.sii.ogham.core.builder.MessagingBuilder;
import fr.sii.ogham.core.exception.MessagingException;
import fr.sii.ogham.core.service.MessagingService;
import fr.sii.ogham.sms.message.Sms;
public class BasicSample {
public static void main(String[] args) throws MessagingException {
// configure properties (could be stored in a properties file or defined
// in System properties)
Properties properties = new Properties();
properties.setProperty("ogham.sms.smpp.host", "<your server host>");
properties.setProperty("ogham.sms.smpp.port", "<your server port>");
properties.setProperty("ogham.sms.smpp.systemId", "<your server system ID>");
properties.setProperty("ogham.sms.smpp.password", "<your server password>");
properties.setProperty("ogham.sms.from", "<phone number to display for the sender>");
// Instantiate the messaging service using default behavior and
// provided properties
MessagingService service = new MessagingBuilder().useAllDefaults(properties).build();
// send the sms
service.send(new Sms().
content("sms content").
to("<recipient phone number>"));
}
}
This sample shows how to send a basic email. The sample is available here.
If you want to put properties in a configuration file, you can create a properties file (sms.properties for example) in src/main/resources folder with the following content:
ogham.sms.smpp.host<your server host>
ogham.sms.smpp.port=<your server port>
ogham.sms.smpp.systemId=<your server system ID>
ogham.sms.smpp.password=<your server password>
ogham.sms.from=<phone number to display for the sender>
And then load these properties before creating messaging service:
package fr.sii.ogham.sample.standard.sms;
import java.io.IOException;
import java.util.Properties;
import fr.sii.ogham.core.builder.MessagingBuilder;
import fr.sii.ogham.core.exception.MessagingException;
import fr.sii.ogham.core.service.MessagingService;
import fr.sii.ogham.sms.message.Sms;
public class BasicSampleExternalProperties {
public static void main(String[] args) throws MessagingException, IOException {
// load properties (available at src/main/resources)
Properties properties = new Properties();
properties.load(BasicSampleExternalProperties.class.getResourceAsStream("/sms.properties"));
// Instantiate the messaging service using default behavior and
// provided properties
MessagingService service = new MessagingBuilder().useAllDefaults(properties).build();
// send the sms
service.send(new Sms("sms content", "<recipient phone number>"));
// or using fluent API
service.send(new Sms().
content("sms content").
to("<recipient phone number>"));
}
}
Sending SMS with a templated content is exactly the same as sending email with a templated content. The sample is available here.
The first lines configure the properties that will be used by the sender. Then you must create the service. You can use the MessagingBuilder to help you to create the service. Finally, the last line sends the SMS. The specified SMS is really basic too. It only contains the templated content available in the classpath, a bean to use as source of variable substitutions and the receiver number. The sender number is automatically added to the SMS by the service based on configuration properties.
package fr.sii.ogham.sample.standard.sms;
import java.util.Properties;
import fr.sii.ogham.context.SimpleBean;
import fr.sii.ogham.core.builder.MessagingBuilder;
import fr.sii.ogham.core.exception.MessagingException;
import fr.sii.ogham.core.message.content.TemplateContent;
import fr.sii.ogham.core.service.MessagingService;
import fr.sii.ogham.sms.message.Sms;
public class TemplateSample {
public static void main(String[] args) throws MessagingException {
// configure properties (could be stored in a properties file or defined
// in System properties)
Properties properties = new Properties();
properties.setProperty("ogham.sms.smpp.host", "<your server host>");
properties.setProperty("ogham.sms.smpp.port", "<your server port>");
properties.setProperty("ogham.sms.smpp.systemId", "<your server system ID>");
properties.setProperty("ogham.sms.smpp.password", "<your server password>");
properties.setProperty("ogham.sms.from", "<phone number to display for the sender>");
// Instantiate the messaging service using default behavior and
// provided properties
MessagingService service = new MessagingBuilder().useAllDefaults(properties).build();
// send the sms
service.send(new Sms(new TemplateContent("classpath:/template/thymeleaf/simple.txt", new SimpleBean("foo", 42)), "<recipient phone number>"));
// or using fluent API
service.send(new Sms().
content(new TemplateContent("classpath:/template/thymeleaf/simple.txt", new SimpleBean("foo", 42))).
to("<recipient phone number>"));
}
}
As you may know, SMS stands for Short Message Service. Basically, the messages are limited to a maximum of 160 characters (depends of char encoding). If needed, the library will split your messages into several parts the right way to be recomposed by clients later. So the code doesn't change at all (the sample is available here):
package fr.sii.ogham.sample.standard.sms;
import java.util.Properties;
import fr.sii.ogham.core.builder.MessagingBuilder;
import fr.sii.ogham.core.exception.MessagingException;
import fr.sii.ogham.core.service.MessagingService;
import fr.sii.ogham.sms.message.Sms;
public class LongMessageSample {
public static void main(String[] args) throws MessagingException {
// configure properties (could be stored in a properties file or defined
// in System properties)
Properties properties = new Properties();
properties.setProperty("ogham.sms.smpp.host", "<your server host>");
properties.setProperty("ogham.sms.smpp.port", "<your server port>");
properties.setProperty("ogham.sms.smpp.systemId", "<your server system ID>");
properties.setProperty("ogham.sms.smpp.password", "<your server password>");
properties.setProperty("ogham.sms.from", "<phone number to display for the sender>");
// Instantiate the messaging service using default behavior and
// provided properties
MessagingService service = new MessagingBuilder().useAllDefaults(properties).build();
String longMessage = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
// send the sms
service.send(new Sms(longMessage, "<recipient phone number>"));
// or using fluent API
service.send(new Sms().
content(longMessage).
to("<recipient phone number>"));
}
}
To use Ogham and let Spring Boot auto-configuration mechanism handle integration, just add dependency to your pom.xml:
...
<dependencies>
...
<dependency>
<groupId>fr.sii.ogham</groupId>
<artifactId>ogham-spring</artifactId>
<version>1.1.0</version>
</dependency>
...
</dependencies>
...
It will automatically create and register MessagingService bean. It will also automatically use Spring Thymeleaf integration if it is in the classpath. The Spring environment (configuration provided by configuration files for example) will be automatically used to configure the Ogham module.
Then to use it in your code, simply autowire the service:
public class UserService {
@Autowired
MessagingService messagingService;
public UserDTO register(UserDTO user) {
...
messagingService.send(new Email("account registered", "email content", user.getEmailAddress()));
...
}
}
For additional usage information or manual integration see how to use the module with Spring.
Spring comes with very useful management of configuration properties (environment and profiles). Ogham module is able to use environment provided by Spring.
Add the following information in the application.properties (or according to profile, into the right configuration file):
mail.smtp.host=<your server host>
mail.smtp.port=<your server port>
ogham.email.from=<your gmail address>
To use Ogham in Spring, you can directly inject (autowire) it. Here is a full Spring Boot application serving one REST endpoint for sending email using Ogham (sample available here):
package fr.sii.ogham.context.sample.springboot.email;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import fr.sii.ogham.core.exception.MessagingException;
import fr.sii.ogham.core.service.MessagingService;
import fr.sii.ogham.email.message.Email;
@SpringBootApplication
public class BasicSample {
public static void main(String[] args) throws MessagingException {
SpringApplication.run(BasicSample.class, args);
}
@RestController
public static class BasicController {
// Messaging service is automatically created using Spring Boot features
// The configuration can be set into application-basic.properties
// The configuration files are stored into src/main/resources
@Autowired
MessagingService messagingService;
@RequestMapping(value="api/email", method=RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public void sendMail(@RequestParam("subject") String subject, @RequestParam("content") String content, @RequestParam("to") String to) throws MessagingException {
// send the email
messagingService.send(new Email(subject, content, to));
// or using fluent API
messagingService.send(new Email().
subject(subject).
content(content).
to(to));
}
}
}
Spring comes with very useful management of configuration properties (environment and profiles). Ogham module is able to use environment provided by Spring.
Add the following information in the application.properties (or according to profile, into the right configuration file):
ogham.sms.smpp.host<your server host>
ogham.sms.smpp.port=<your server port>
ogham.sms.smpp.systemId=<your server system ID>
ogham.sms.smpp.password=<your server password>
ogham.sms.from=<phone number to display for the sender>
To use Ogham in Spring, you can directly inject (autowire) it. Here is a full Spring Boot application serving one REST endpoint for sending SMS using Ogham (sample available here):
package fr.sii.ogham.context.sample.springboot.sms;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import fr.sii.ogham.core.exception.MessagingException;
import fr.sii.ogham.core.service.MessagingService;
import fr.sii.ogham.sms.message.Sms;
@SpringBootApplication
public class BasicSample {
public static void main(String[] args) throws MessagingException {
SpringApplication.run(BasicSample.class, args);
}
@RestController
public static class BasicController {
// Messaging service is automatically created using Spring Boot features
// The configuration can be set into application-basic.properties
// The configuration files are stored into src/main/resources
@Autowired
MessagingService messagingService;
@RequestMapping(value="api/sms", method=RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public void sendMail(@RequestParam("content") String content, @RequestParam("to") String to) throws MessagingException {
// send the SMS
messagingService.send(new Sms(content, to));
// or using fluent API
messagingService.send(new Sms().
content(content).
to(to));
}
}
}
If you prefer FreeMarker as template engine, you just need to create your templates using FreeMarker (templates for FreeMarker are suffixed by .ftl
extension).
Content of the HTML template (simple.html.ftl):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h1 class="title">${name}</h1>
<p class="text">${value}</p>
</body>
</html>
Content of the text template (simple.txt.ftl):
${name} ${value}
The Java code is the same as before, no difference at all. Ogham automatically discover your templates and understands that you are using FreeMarker template files.
package fr.sii.ogham.sample.standard.template.freemarker;
import java.util.Properties;
import fr.sii.ogham.context.SimpleBean;
import fr.sii.ogham.core.builder.MessagingBuilder;
import fr.sii.ogham.core.exception.MessagingException;
import fr.sii.ogham.core.message.content.MultiTemplateContent;
import fr.sii.ogham.core.service.MessagingService;
import fr.sii.ogham.email.message.Email;
public class HtmlAndTextTemplateSample {
public static void main(String[] args) throws MessagingException {
// configure properties (could be stored in a properties file or defined
// in System properties)
Properties properties = new Properties();
properties.setProperty("mail.smtp.host", "<your server host>");
properties.setProperty("mail.smtp.port", "<your server port>");
properties.setProperty("ogham.email.from", "<email address to display for the sender user>");
// Instantiate the messaging service using default behavior and
// provided properties
MessagingService service = new MessagingBuilder().useAllDefaults(properties).build();
// send the email
// Note that the extension of the template is not given. This version
// automatically takes the provided path and adds the '.html' extension
// for the HTML template and '.txt' for text template
service.send(new Email("subject", new MultiTemplateContent("classpath:/template/freemarker/simple", new SimpleBean("foo", 42)), "<recipient address>"));
// or using fluent API
service.send(new Email()
.subject("subject")
.content(new MultiTemplateContent("classpath:/template/freemarker/simple", new SimpleBean("foo", 42)))
.to("<recipient address>"));
}
}
It is possible to mix templates in the same application. Even better, you can use a template engine that is better suited for HTML like Thymeleaf and FreeMarker that is better for textual version for the same email. Just write your templates with the engine you want.
See samples to ensure that Java code is still the same.
Only the templates are different:
See wiki to know how to the library selects the right implementation.
Hidden complexity
One of the main aim of the library is to hide the implementation complexity and provide automatic behaviors to simplify the development.
When you send an email, it is really important to indicate what is the type of the message (html, text or maybe anything else). The library automatically detects for you the Mime Type of the email content and add this information into the real sent email.
Moreover, every attached file must also provide the Mime Type in order to be correctly handled by the email client. Besides, some email clients may provide a preview of attached file. This will be possible only if the correct Mime Type is provided. The library comes with a handy Mime Type Detector policy.
To be sure that most of Email clients will handle an HTML content, there are many rules to follow when writing the content. They might be very complex and time consuming. The library do all this headache work for you.
All these features can be either disabled or use another implementation instead of the default one.
For Web developers, it is important to write clean code and separate the concerns. So when writing HTML, developers want to externalize CSS files and images. This is also really important to mutualize the code of CSS files and images for reuse.
However, email clients do not handle external CSS files. Styles might be included in a style
tag but Gmail doesn't support it. So all rules provided in the CSS MUST be inlined directly in the HTML. Writing code like this is just painful and error prone. Moreover, images can be referenced externally but only if you know in advance what will be the URL of the final image. And even then, the email client might block those images for safety purpose. Not mentioning offline issues.
The library will automatically inlines CSS rules directly on the HTML tags. The images are either inlined as base64 encoded in img
src
attribute or images are attached with the email (with inline content disposition and references in the HTML).
CSS properties can be written using shorthand version:
padding: 4px 2px;
This is equivalent to:
padding: 4px 2px 4px 2px;
Some email clients do not handle shorthand properties. So all properties written in shorthand version should be expanded in order to work everywhere.
The library will automatically expand properties from shorthand versions.
Several attributes should be added on some HTML tags in order to be compliant with email clients. For example, tables and images must have attribute border="0"
in order to prevent an ugly border on some clients.
The library will automatically add these attributes.
It is recommended to write XHTML instead of HTML due to some email clients. The library do it for you.
Background images are not correctly handled by several email clients. And again, some workarounds to apply to fix this issue.
The library will apply those workarounds to your HTML.
TODO
There are some implementation constraints for sending a SMS following SMPP protocol. The library will help you handle these constraints.
SMPP defines two main properties related to the sender and recipient phone number formats: TON and NPI.
The library provides a default policy : Just pass the phone numbers and the library will guess the TON and NPI. You can also directly provide the TON and NPI in order to prevent this automatic behavior.
Sending SMS with the wrong charset might cause your message to be unreadable. But SMPP Charset are quite different from the common charset definition. The charset resolution is done using a simple mapping between Java charsets and SMPP charsets. By default, Java uses UTF-8 charset and the librairy will map to the SMPP charset GSM. The library offers you the ability to provide your own charset when sending SMS if need.
See wiki to know how to configure the library to customize its behavior.
See wiki to know how to add custom implementations
You must log in via your web browser. You may have received an email asking to allow or not the connection. See this post on stackoverflow