= SES Integration
Spring has a built-in support to send e-mails based on the https://www.oracle.com/technetwork/java/javamail/index.html[Java Mail API]
to avoid any static method calls while using the Java Mail API and thus supporting the testability of an application.
Spring Cloud AWS supports the https://aws.amazon.com/de/ses/[Amazon SES] as an implementation of the Spring Mail abstraction.

As a result Spring Cloud AWS users can decide to use the Spring Cloud AWS implementation of the Amazon SES service or
use the standard Java Mail API based implementation that sends e-mails via SMTP to Amazon SES.

[TIP]
====
It is preferred to use the Spring Cloud AWS implementation instead of SMTP mainly for performance reasons.
Spring Cloud AWS uses one API call to send a mail message, while the SMTP protocol makes multiple requests (EHLO, MAIL FROM, RCPT TO, DATA, QUIT)
until it sends an e-mail.
====

A Spring Boot starter is provided to auto-configure SES integration beans.

Maven coordinates, using <<index.adoc#bill-of-materials, Spring Cloud AWS BOM>>:

[source,xml]
----
<dependency>
    <groupId>io.awspring.cloud</groupId>
    <artifactId>spring-cloud-aws-starter-ses</artifactId>
</dependency>
----

== Sending simple mails
Application developers can inject the `MailSender` into their application code and directly send simple text based e-mail
messages. The sample below demonstrates the creation of a simple mail message.

[source,java,indent=0]
----
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;

class MailSendingService {

	private final MailSender mailSender;

	public MailSendingService(MailSender mailSender) {
		this.mailSender = mailSender;
	}

	public void sendMailMessage() {
		SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
		simpleMailMessage.setFrom("foo@bar.com");
		simpleMailMessage.setTo("bar@baz.com");
		simpleMailMessage.setSubject("test subject");
		simpleMailMessage.setText("test content");
		this.mailSender.send(simpleMailMessage);
	}
}
----

== Sending attachments and/or HTML e-mails

Sending attachments with e-mail or HTML e-mails requires MIME messages to be created and sent. In order to create MIME messages,
the Java Mail API dependency and an implementation need to be in the classpath. Spring Cloud AWS will detect the
dependency and create a `org.springframework.mail.javamail.JavaMailSender` implementation that allows to create and
build MIME messages and send them. Dependencies for the Java Mail API and an implementation are the only needed configuration changes as shown below.

[source,xml,indent=0]
----
<dependency>
	<groupId>jakarta.mail</groupId>
	<artifactId>jakarta.mail-api</artifactId>
</dependency>
<dependency>
	<groupId>org.eclipse.angus</groupId>
	<artifactId>jakarta.mail</artifactId>
</dependency>
----

[NOTE]
====
Even though there is a dependency to the Java Mail API there is still the Amazon SES API used underneath to send mail
messages. There is no https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-email-smtp.html[SMTP setup] required
on the Amazon AWS side.
====

Sending the mail requires the application developer to use the `JavaMailSender` to send an e-mail as shown in the example
below.

[source,java,indent=0]
----
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;

class MailSendingService {

	private final JavaMailSender mailSender;

	public MailSendingService(JavaMailSender mailSender) {
		this.mailSender = mailSender;
	}

	public void sendMailMessage() {
		this.mailSender.send(new MimeMessagePreparator() {

   			@Override
   			public void prepare(MimeMessage mimeMessage) throws Exception {
   				MimeMessageHelper helper =
   					new MimeMessageHelper(mimeMessage, true, "UTF-8");
   				helper.addTo("foo@bar.com");
   				helper.setFrom("bar@baz.com");
   				helper.addAttachment("test.txt", ...);
   				helper.setSubject("test subject with attachment");
   				helper.setText("mime body", false);
   			}
   		});
	}
}
----

== Authenticating e-mails

To avoid any spam attacks on the Amazon SES mail service, applications without production access must
https://docs.aws.amazon.com/ses/latest/DeveloperGuide/verify-email-addresses.html[verify] each
e-mail receiver otherwise the mail sender will throw a `software.amazon.awssdk.services.ses.model.MessageRejectedException`.

https://docs.aws.amazon.com/ses/latest/DeveloperGuide/request-production-access.html[Production access] can be requested
and will disable the need for mail address verification.

== Configuration

The Spring Boot Starter for SES provides the following configuration options:

[cols="3,3,1,1"]
|===
| Name | Description | Required | Default value
| `spring.cloud.aws.ses.enabled` | Enables the SES integration. | No | `true`
| `spring.cloud.aws.ses.endpoint` | Configures endpoint used by `SesClient`. | No |
| `spring.cloud.aws.ses.region` | Configures region used by `SesClient`. | No |
| `spring.cloud.aws.ses.sourceArn` | Configures source ARN, used only for sending authorization. | No |
|===

Amazon SES is not available in all https://docs.aws.amazon.com/ses/latest/DeveloperGuide/regions.html[regions] of the
Amazon Web Services cloud. Therefore, an application hosted and operated in a region that does not support the mail
service will produce an error while using the mail service. Therefore, the region must be overridden for the mail
sender configuration. The example below shows a typical combination of a region (`EU-CENTRAL-1`) that does not provide
an SES service where the client is overridden to use a valid region (`EU-WEST-1`).

`sourceArn` is the ARN of the identity that is associated with the sending authorization policy. For information about when to use this parameter, see the
description see https://docs.aws.amazon.com/ses/latest/dg/sending-authorization-delegate-sender-tasks-email.html[Amazon SES Developer Guide].

[source,properties,indent=0]
----
spring.cloud.aws.ses.region=eu-west-1
spring.cloud.aws.ses.sourceArn=arn:aws:ses:eu-west-1:123456789012:identity/example.com
----

== IAM Permissions
Following IAM permissions are required by Spring Cloud AWS:

[cols="2"]
|===
| Send e-mail without attachment
| `ses:SendEmail`

| Send e-mail with attachment
| `ses:SendRawEmail`

|===

Sample IAM policy granting access to SES:

[source,json,indent=0]
----
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ses:SendEmail",
                "ses:SendRawEmail"
            ],
            "Resource": "arn:aws:ses:your:arn"
        }
    ]
}
----
