////
This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/master/docs/src/main/asciidoc
////
= Quarkus - Sending emails

include::./attributes.adoc[]

This guide demonstrates how your Quarkus application can send emails using an SMTP server.

== Prerequisites

To complete this guide, you need:

* less than 15 minutes
* The SMTP hostname, port and credentials, and an email address
* an IDE
* JDK 1.8+ installed with `JAVA_HOME` configured appropriately
* Apache Maven {maven-version}
* GraalVM installed if you want to run in native mode.

== Architecture

In this guide, we are going to see how you can send emails from a Quarkus application.
It covers simple emails, attachments, inlined attachments, the reactive and imperative APIs...

== Creating the Maven Project

Create a new project with the following command:

[source, subs=attributes+]
----
mvn io.quarkus:quarkus-maven-plugin:{quarkus-version}:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=sending-email-quickstart \
    -Dextensions="mailer"
cd sending-email-quickstart
----

If you already have an existing project, add the `mailer` extension:

[source]
----
./mvnw quarkus:add-extensions -Dextensions="mailer"
----

== Configuring the mailer

The Quarkus mailer is using SMTP. In the `src/main/resources/application.properties` file, you need to configure the host, port, username, password as well as the other configuration aspect.
Note that the password can also be configured using system properties and environment variables.

Here is an example using _sendgrid_:

[source]
----
quarkus.mailer.from=test@quarkus.io
quarkus.mailer.host=smtp.sendgrid.net
quarkus.mailer.port=465
quarkus.mailer.ssl=true
quarkus.mailer.username=....
quarkus.mailer.password=....
quarkus.mailer.mock=false
----

[NOTE]
====
It is recommended to encrypt any sensitive data, such as the `quarkus.mailer.password`.
One approach is to save the value into a secure store like HashiCorp Vault, and refer to it from the configuration.
Assuming for instance that Vault contains key `mail-password` at path `myapps/myapp/myconfig`, then the mailer
extension can be simply configured as:
```
...
# path within the kv secret engine where is located the application sensitive configuration
quarkus.vault.secret-config-kv-path=myapps/myapp/myconfig

...
quarkus.mailer.password=${mail-password}
```
Please note that the password value is evaluated only once, at startup time. If `mail-password` was changed in Vault,
the only way to get the new value would be to restart the application.
====

[TIP]
For more information about the Mailer extension configuration please refer to the <<configuration-reference, Configuration Reference>>.

== Sending simple emails

In a JAX-RS resource, or in a bean, you can inject the mailer as follows:

[source, java]
----
@Inject
Mailer mailer;

@Inject
ReactiveMailer reactiveMailer;
----

There are 2 APIs:

* `io.quarkus.mailer.Mailer` provides the imperative (blocking and synchronous) API;
* `io.quarkus.mailer.reactive.ReactiveMailer` provides the reactive (non-blocking and asynchronous) API

NOTE: The two APIs are equivalent feature-wise. Actually the `Mailer` implementation is built on top of the `ReactiveMailer` implementation.

[NOTE]
.Deprecation
====
`io.quarkus.mailer.ReactiveMailer` is deprecated in favor of `io.quarkus.mailer.reactive.ReactiveMailer`.
====

[TIP]
.Mutiny
====
The reactive mailer uses Mutiny reactive types, if you're not familiar with them, read the link:getting-started-reactive#mutiny[Getting Started with Reactive guide] first.
====

To send a simple email, proceed as follows:

[source, java]
----
// Imperative API:
mailer.send(Mail.withText("to@acme.org", "A simple email from quarkus", "This is my body."));
// Reactive API:
Uni<Void> stage = reactiveMailer.send(Mail.withText("to@acme.org", "A reactive email from quarkus", "This is my body."));
----

For example, you can use the `Mailer` in a JAX-RS endpoint as follows:

[source, java]
----
@GET
@Path("/simple")
public Response sendASimpleEmail() {
    mailer.send(Mail.withText("to@acme.org", "A simple email from quarkus", "This is my body"));
    return Response.accepted().build();
}

@GET
@Path("/async")
public CompletionStage<Response> sendASimpleEmailAsync() {
    return reactiveMailer.send(
            Mail.withText("to@acme.org", "A reactive email from quarkus", "This is my body"))
            .subscribeAsCompletionStage()
            .thenApply(x -> Response.accepted().build());
}
----

[NOTE]
====
With the `quarkus-resteasy-mutiny` extension, you can return an instance of `Uni` directly.
====

With such a JAX-RS resource, you can check that everything is working with:

[source, bash]
----
curl http://localhost:8080/simple
curl http://localhost:8080/async
----

You can create new `io.quarkus.mailer.Mail` instances from the constructor or from the `Mail.withText` and
`Mail.withHtml` helper methods. The `Mail` instance lets you add recipients (to, cc, or bcc), set the subject,
headers, sender (from) address...

You can also send several `Mail` objects in one call:

[source, java]
----
mailer.send(mail1, mail2, mail3);
----

== Sending attachments

To send attachment, just use the `addAttachment` methods on the `io.quarkus.mailer.Mail` instance:

[source,java]
----
@GET
@Path("/attachment")
public Response sendEmailWithAttachment() {
    mailer.send(Mail.withText("to@acme.org", "An email from quarkus with attachment",
            "This is my body")
            .addAttachment("my-file.txt",
                "content of my file".getBytes(), "text/plain"));
    return Response.accepted().build();
}
----

Attachments can be created from raw bytes (as shown in the snippet) or files.

== Sending HTML emails with inlined attachments

When sending HTML email, you can add inlined attachments.
For example, you can send an image with your email, and this image will be displayed in the mail content. If you put the image file into resources folder, you should specify the full path to the file. "e.g." "META-INF/resources/quarkus-logo.png" otherwise quarkus will lookup in the root folder of the project

[source, java]
----
@GET
@Path("/html")
public Response sendingHTML() {
    String body = "<strong>Hello!</strong>" + "\n" +
        "<p>Here is an image for you: <img src=\"cid:my-image@quarkus.io\"/></p>" +
        "<p>Regards</p>";
    mailer.send(Mail.withHtml("to@acme.org", "An email in HTML", body)
        .addInlineAttachment("quarkus-logo.png",
            new File("quarkus-logo.png"),
            "image/png", "<my-image@quarkus.io>"));
    return Response.accepted().build();
}
----

Note the _content-id_ format and reference.
By spec, when you create the inline attachment, the content-id must be structured as follows: `<id@domain>`.
If you don't wrap your content-id between `<>`, it is automatically wrapped for you.
When you want to reference your attachment, for instance in the `src` attribute, use `cid:id@domain` (without the `<` and `>`).

== Message Body Based on Qute Templates

It's also possible to inject a mail template, where the message body is created automatically using link:qute[Qute templates].

[source, java]
----
@Inject
MailTemplate hello; <1>

@GET
@Path("/mail")
public CompletionStage<Response> send() {
    return hello.to("to@acme.org") <2>
       .subject("Hello from Qute template")
       // the template looks like: Hello {name}!
       .data("name", "John") <3>
       .send() <4>
       .subscribeAsCompletionStage()
       .thenApply(x -> Response.accepted().build());
}
----
<1> If there is no `@ResourcePath` qualifier provided, the field name is used to locate the template. In this particular case, we will use the `hello.html` and `hello.txt` templates to create the message body.
<2> Create a mail template instance and set the recipient.
<3> Set the data used in the template.
<4> `MailTemplate.send()` triggers the rendering and, once finished, sends the e-mail via a `Mailer` instance. 

TIP: Injected mail templates are validated during build. If there is no matching template in `src/main/resources/templates` the build fails.

== Testing email sending

Because it is very inconvenient to send emails during development and testing, you can set the `quarkus.mailer.mock` boolean
configuration to `true` to not actually send emails but print them on stdout and collect them in a `MockMailbox` bean instead.
This is the default if you are running Quarkus in `DEV` or `TEST` mode.

You can then write tests to verify that your emails were sent, for example, by a REST endpoint:

[source, java]
----
@QuarkusTest
class MailTest {

    private static final String TO = "foo@quarkus.io";

    @Inject
    MockMailbox mailbox;

    @BeforeEach
    void init() {
        mailbox.clear();
    }

    @Test
    void testTextMail() throws MessagingException, IOException {
        // call a REST endpoint that sends email
        given()
        .when()
        .get("/send-email")
        .then()
           .statusCode(202)
           .body(is("OK"));

        // verify that it was sent
        List<Mail> sent = mailbox.getMessagesSentTo(TO);
        assertThat(sent).hasSize(1);
        Mail actual = sent.get(0);
        assertThat(actual.getText()).contains("Wake up!");
        assertThat(actual.getSubject()).isEqualTo("Alarm!");

        assertThat(mailbox.getTotalMessagesSent()).isEqualTo(6);
    }
}
----

== Gmail specific configuration

If you want to use the Gmail SMTP server, first create a dedicated password in `Google Account > Security > App passwords` or go to https://myaccount.google.com/apppasswords.

When done, you can configure your Quarkus application by adding the following properties to your `application.properties`:

With TLS:

[source]
----
quarkus.mailer.auth-methods=DIGEST-MD5 CRAM-SHA256 CRAM-SHA1 CRAM-MD5 PLAIN LOGIN
quarkus.mailer.from=YOUREMAIL@gmail.com
quarkus.mailer.host=smtp.gmail.com
quarkus.mailer.port=587
quarkus.mailer.start-tls=REQUIRED
quarkus.mailer.username=YOUREMAIL@gmail.com
quarkus.mailer.password=YOURGENERATEDAPPLICATIONPASSWORD
----

Or with SSL:

[source]
---- 
quarkus.mailer.auth-methods=DIGEST-MD5 CRAM-SHA256 CRAM-SHA1 CRAM-MD5 PLAIN LOGIN
quarkus.mailer.from=YOUREMAIL@gmail.com
quarkus.mailer.host=smtp.gmail.com
quarkus.mailer.port=465
quarkus.mailer.ssl=true
quarkus.mailer.username=YOUREMAIL@gmail.com
quarkus.mailer.password=YOURGENERATEDAPPLICATIONPASSWORD
----

[NOTE]
====
The `quarkus.mailer.auth-methods` configuration option is needed for the Quarkus mailer to support password authentication with Gmail.
By default both the mailer and Gmail default to `XOAUTH2` which requires registering an application, getting tokens, etc.
====

== Using SSL with native executables

Note that if you enable SSL for the mailer and you want to build a native executable, you will need to enable the SSL support.
Please refer to the link:native-and-ssl[Using SSL With Native Executables] guide for more information.

== Using the underlying Vert.x Mail Client

The Quarkus Mailer is implemented on top of the https://vertx.io/docs/vertx-mail-client/java/[Vert.x Mail Client], providing an asynchronous and non-blocking way to send emails.
If you need fine control on how the mail is sent, for instance if you need to retrieve the message ids, you can inject the underlying client, and use it directly:

[source, java]
----
@Inject MailClient client;
----

Three API flavors are exposed:

* the Mutiny client (`io.vertx.mutiny.ext.mail.MailClient`)
* the Axle client (`io.vertx.axle.ext.mail.MailClient`), using `CompletionStage` and Reactive Streams `Publisher` - deprecated, it is recommended to switch to the Mutiny client
* the RX Java 2 client (`io.vertx.reactivex.ext.mail.MailClient`) - deprecated, it is recommended to switch to the Mutiny client
* the bare client (`io.vertx.ext.mail.MailClient`)

Check the link:vertx[Using Vert.x guide] for further details about these different APIs and how to select the most suitable for you.

The retrieved `MailClient` is configured using the configuration key presented above.
You can also create your own instance, and pass your own configuration.

== Conclusion

This guide has shown how you can send emails from a Quarkus application.
The _mailer_ extension works in JVM and native mode.


[[configuration-reference]]
== Mailer Configuration Reference

include::{generated-dir}/config/quarkus-mailer.adoc[opts=optional, leveloffset=+1]
