Ogham

The easiest way to send Email, SMS or whatever

Objectives

  1. Easy usage

  2. Focus on your business code

  3. Adapt to environment

1. Easy usage

1. Easy usage Quick start

Add Ogham dependency

plugins {
    id 'java'
}

repositories {
  mavenLocal()
  mavenCentral()
}

dependencies {
  implementation 'fr.sii.ogham:ogham-all:3.0.0'
}

1. Easy usage Quick start

Initialize Ogham

MessagingService service = MessagingBuilder.standard()
  // ... optional configuration
  .build();

1. Easy usage Quick start

Send an email

service.send(new Email()
  .subject("Hello !")
  .from("sender@anything.com")
  .to("recipient@anything.com")
  .body().string("Hello world !!"));

1. Easy usage Quick start

Send a SMS

service.send(new Sms()
  .from("000000000")
  .to("999999999")
  .message().string("Hello world !!"));

1. Easy usage Quick start

That’s it

1. Easy usage Spring Boot compatible

Add Ogham dependency for Spring Boot

// ... Gradle configuration provided by Spring Boot

dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-web'
  implementation 'fr.sii.ogham:ogham-spring-boot-starter-all:3.0.0'
  testImplementation('org.springframework.boot:spring-boot-starter-test') {
    exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
  }
}

1. Easy usage Spring Boot compatible

Inject Ogham in your Spring components

@Service
public class YourBusinessService {
  @Autowired MessagingService service;
}

1. Easy usage Spring Boot compatible

It’s even easier

2. Focus on business code

2. Focus on business code Separate concerns

Externalize content in templates

CustomModel yourModel = new CustomModel();
yourModel.setAnything("world");

service.send(new Email()
  .subject("Hello !")
  .from("sender@anything.com")
  .to("recipient@anything.com")
  .body().template("email/hello.html.ftl", yourModel));
<!DOCTYPE html>
<html>
    <head>
        <title>Hello !</title>
        <meta charset="utf-8" />
    </head>
    <body>
        <h1>Hello ${anything} !!</h1>
    </body>
</html>

Use any of your object as model

Externalize whole message related content by moving subject in template

2. Focus on business code Separate concerns

Externalize designs as usual

<!DOCTYPE html>
<html>
    <head>
        <title>Hello !</title>
        <meta charset="utf-8" />
        <link href="css/theme.css" rel="stylesheet" />
    </head>
    <body>
        <h1>Hello ${anything} !!</h1>
    </body>
</html>
h1 {
  color: #fff;
}

2. Focus on business code Separate concerns

Keep your best practices

2. Focus on business code Get rid of technical concerns

Ogham handles styles and images for emails

h1 {
  color: #fff;
}
body {
  background: url(../images/email-bg.png) top center no-repeat;
}

Generated HTML
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
    </head>
    <body style="background: url('cid:0') top center no-repeat">
        <h1 style="color: #fff">Hello ${anything} !!</h1>
    </body>
</html>

Styles are inlined for you

Image is attached to the email and referenced by a Content-ID

2. Focus on business code Get rid of technical concerns

Best encoding for minimum SMS characters

AnotherModel yourModel = new AnotherModel();
yourModel.setName("World");

service.send(new Sms()
  .from("000000000")
  .to("999999999")
  .message().template("sms/hello.txt.ftl", yourModel));
Hello ${name} !!

"World" contains only characters of GSM 03.38 character set.

Use GSM 03.38 character set


yourModel.setName("Hôtel");

"Hôtel" contains "ô" character that is not in GSM 03.38 character set.

Now uses UCS-2 character set instead

2. Focus on business code Get rid of technical concerns

Auto-split long SMS

<#list 1..50 as i>    (1)
${i}) Hello world !!
</#list>
1Generates a message with more than 800 characters.

Splits into several messages for you !

Number of characters per SMS depends on message encoding.

Ogham handles it for you !

2. Focus on business code Get rid of technical concerns

Don’t waste time on technical concerns anymore !!

2. Focus on business code Test your code

Start a SMTP server on a random port

@Rule
public GreenMailRule greenMail = new RandomPortGreenMailRule();

2. Focus on business code Test your code

Use Ogham assertions to ensure your business code sends email with the right information

@Test
public void userShouldReceiveConfirmationEmail() {
  // test your business code here that sends an email
  String code = yourAccountService.newAccount(someAccount);

  // ensure that email is received with right information
  assertThat(greenMail).receivedMessages()
    .count(is(1))
    .message(0)
      .subject(is("Welcome "+someAccount.getName()+" !"))
      .to()
        .address(hasItems(someAccount.getEmail()))
        .and()
      .body()
        .contentAsString(containsString("?confirmation="+code))
      // ... other assertions
}

2. Focus on business code Test your code

Start a SMPP server on a random port

@Rule
public SmppServerRule<SubmitSm> smppServer = new JsmppServerRule();

2. Focus on business code Test your code

Use Ogham assertions to ensure your business code sends SMS with the right information

@Test
public void userShouldReceiveConfirmationCode() {
  // test your business code here that sends a SMS
  String code = yourAccountService.newAccount(someAccount);

  // ensure that SMS is received with right information
  assertThat(smppServer).receivedMessages()
    .count(is(1))
    .message(0)
      .content(containsString("Confirmation code: "+code))
      .to()
        .number(is(someAccount.getPhoneNumber()))
      // ... other assertions
}

2. Focus on business code Test your code

Use testing tools to focus on testing your code !

3. Adapt to environment

3. Adapt to environment Externalize configuration

Default configuration files

In dev project classpath for default configuration:

  • config/ogham.properties

  • config/application.properties


External file relative to current running directory:

  • config/ogham.properties

  • config/application.properties

3. Adapt to environment Externalize configuration

Choose directory for configuration files

$ java \
    -Dogham.config.location=/etc/your-app \
    -jar ...other command line arguments...

Ogham also handle configuration profiles, such as:

  • 'dev'

  • 'test'

  • 'prod'

  • 'anything-you-want'

3. Adapt to environment Choose email sender

Use SMTP server for development

src/main/resources/config/ogham.properties
mail.smtp.host=localhost
mail.smtp.port=25

3. Adapt to environment Choose email sender

Use SendGrid service in production

src/main/resources/config/ogham.properties (dev config is unchanged)
mail.smtp.host=localhost
mail.smtp.port=25

+

/etc/your-app/ogham.properties (external config)
mail.smtp.host=                                 (1)

ogham.email.sendgrid.api-key=your-api-key
1Override to disable SMTP

=

merged
mail.smtp.host=
mail.smtp.port=25
ogham.email.sendgrid.api-key=your-api-key

3. Adapt to environment Choose SMS sender

Use SMPP server for development

src/main/resources/config/ogham.properties
ogham.sms.smpp.host=localhost
ogham.sms.smpp.port=2775

3. Adapt to environment Choose SMS sender

Use SmsGlobal service in production

src/main/resources/config/ogham.properties (dev config is unchanged)
ogham.sms.smpp.host=localhost
ogham.sms.smpp.port=2775

+

/etc/your-app/ogham.properties (external config)
ogham.sms.smpp.host=smpp.smsglobal.com
ogham.sms.smpp.port=1775
ogham.sms.smpp.system-id=your-smsglobal-account
ogham.sms.smpp.password=your-smsglobal-password

=

merged
ogham.sms.smpp.host=smpp.smsglobal.com
ogham.sms.smpp.port=1775
ogham.sms.smpp.system-id=your-smsglobal-account
ogham.sms.smpp.password=your-smsglobal-password

3. Adapt to environment

Don’t change your code, don’t code twice !!

Just update external configuration !!!

Roadmap

  • Send RCS messages

  • Other message types

  • More service integrations

  • More template engine integrations

  • More framework integrations

  • Make it even easier

  • Make it universal (JVM, NodeJS, iOS, Android)

-