diff --git a/src/main/java/com/resend/services/emails/model/CreateEmailOptions.java b/src/main/java/com/resend/services/emails/model/CreateEmailOptions.java index 7306422..540de45 100644 --- a/src/main/java/com/resend/services/emails/model/CreateEmailOptions.java +++ b/src/main/java/com/resend/services/emails/model/CreateEmailOptions.java @@ -44,6 +44,9 @@ public class CreateEmailOptions { @JsonProperty("scheduled_at") private final String scheduledAt; + @JsonProperty("template") + private final Template template; + private CreateEmailOptions(Builder builder) { this.from = builder.from; this.to = builder.to; @@ -57,6 +60,7 @@ private CreateEmailOptions(Builder builder) { this.html = builder.html; this.headers = builder.headers; this.scheduledAt = builder.scheduledAt; + this.template = builder.template; } /** @@ -167,6 +171,15 @@ public String getScheduledAt() { return scheduledAt; } + /** + * Retrieves the template configuration of the email. + * + * @return The template configuration of the email. + */ + public Template getTemplate() { + return template; + } + /** * Creates a new builder instance to construct CreateEmailOptions. * @@ -192,6 +205,7 @@ public static class Builder { private List tags; private Map headers; private String scheduledAt; + private Template template; /** * Set the 'from' email address. @@ -528,6 +542,21 @@ public Builder scheduledAt(String scheduledAt) { return this; } + /** + * Set the template configuration for the email. + *

+ * Note: If a template is provided, you cannot send html, text, or react in the payload. + * When sending a template, the payload for from, subject, and reply_to take precedence + * over the template's defaults for these fields. + * + * @param template The template configuration. + * @return This builder instance for method chaining. + */ + public Builder template(Template template) { + this.template = template; + return this; + } + /** * Builds and returns a {@code CreateEmailOptions} based on the configured properties. * diff --git a/src/main/java/com/resend/services/emails/model/Template.java b/src/main/java/com/resend/services/emails/model/Template.java new file mode 100644 index 0000000..9c73d5b --- /dev/null +++ b/src/main/java/com/resend/services/emails/model/Template.java @@ -0,0 +1,172 @@ +package com.resend.services.emails.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.HashMap; +import java.util.Map; + +/** + * Represents a template configuration for sending emails. + */ +public class Template { + + @JsonProperty("id") + private final String id; + + @JsonProperty("variables") + private final Map variables; + + /** + * Constructs a Template using the provided builder. + * + * @param builder The builder to construct the Template. + */ + private Template(Builder builder) { + this.id = builder.id; + this.variables = builder.variables; + } + + /** + * Gets the template ID. + * + * @return The template ID. + */ + public String getId() { + return id; + } + + /** + * Gets the template variables. + * + * @return The template variables. + */ + public Map getVariables() { + return variables; + } + + /** + * Creates a new builder instance for constructing Template objects. + * + * @return A new builder instance. + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Helper method to create a Variable for use with varargs methods. + * + * @param key The variable key. + * @param value The variable value. + * @return A new Variable instance. + */ + public static Variable variable(String key, Object value) { + return new Variable(key, value); + } + + /** + * Represents a template variable with a key and value. + */ + public static class Variable { + private final String key; + private final Object value; + + /** + * Constructs a Variable with the specified key and value. + * + * @param key The variable key. + * @param value The variable value. + */ + public Variable(String key, Object value) { + this.key = key; + this.value = value; + } + + /** + * Gets the variable key. + * + * @return The variable key. + */ + public String getKey() { + return key; + } + + /** + * Gets the variable value. + * + * @return The variable value. + */ + public Object getValue() { + return value; + } + } + + /** + * Builder class for constructing Template objects. + */ + public static class Builder { + private String id; + private Map variables; + + /** + * Set the template ID. + * + * @param id The template ID (must be a published template). + * @return The builder instance. + */ + public Builder id(String id) { + this.id = id; + return this; + } + + /** + * Set the template variables. + * + * @param variables The template variables as key/value pairs. + * @return The builder instance. + */ + public Builder variables(Map variables) { + this.variables = variables; + return this; + } + + /** + * Add multiple template variables using varargs. + * + * @param variables The variables to add. + * @return The builder instance. + */ + public Builder variables(Variable... variables) { + if (this.variables == null) { + this.variables = new HashMap<>(); + } + for (Variable variable : variables) { + this.variables.put(variable.getKey(), variable.getValue()); + } + return this; + } + + /** + * Add a single template variable. + * + * @param key The variable key. + * @param value The variable value. + * @return The builder instance. + */ + public Builder addVariable(String key, Object value) { + if (this.variables == null) { + this.variables = new HashMap<>(); + } + this.variables.put(key, value); + return this; + } + + /** + * Build a new Template object. + * + * @return A new Template object. + */ + public Template build() { + return new Template(this); + } + } +} diff --git a/src/test/java/com/resend/services/emails/EmailsTest.java b/src/test/java/com/resend/services/emails/EmailsTest.java index c929084..81bb38d 100644 --- a/src/test/java/com/resend/services/emails/EmailsTest.java +++ b/src/test/java/com/resend/services/emails/EmailsTest.java @@ -218,4 +218,71 @@ public void testListAttachmentsWithPagination_Success() throws ResendException { assertEquals(expectedResponse.hasMore(), response.hasMore()); verify(emails, times(1)).listAttachments(emailId, params); } + + @Test + public void testSendEmail_WithTemplate_Success() throws ResendException { + Template template = Template.builder() + .id("template_123") + .addVariable("firstName", "John") + .addVariable("lastName", "Doe") + .addVariable("company", "Acme Corp") + .build(); + + CreateEmailOptions emailWithTemplate = CreateEmailOptions.builder() + .from("Acme ") + .to("john.doe@example.com") + .subject("Welcome John!") + .template(template) + .build(); + + CreateEmailResponse expectedResponse = EmailsUtil.createSendEmailResponse(); + + when(emails.send(emailWithTemplate)).thenReturn(expectedResponse); + + CreateEmailResponse response = emails.send(emailWithTemplate); + + assertNotNull(response); + assertEquals(expectedResponse.getId(), response.getId()); + verify(emails, times(1)).send(emailWithTemplate); + } + + @Test + public void testSendBatchEmails_WithTemplate_Success() throws ResendException { + Template template1 = Template.builder() + .id("template_123") + .addVariable("firstName", "John") + .addVariable("company", "Tech Corp") + .build(); + + Template template2 = Template.builder() + .id("template_123") + .addVariable("firstName", "Jane") + .addVariable("company", "Design Studios") + .build(); + + CreateEmailOptions email1 = CreateEmailOptions.builder() + .from("Acme ") + .to("john@example.com") + .subject("Welcome John!") + .template(template1) + .build(); + + CreateEmailOptions email2 = CreateEmailOptions.builder() + .from("Acme ") + .to("jane@example.com") + .subject("Welcome Jane!") + .template(template2) + .build(); + + List batchEmails = java.util.Arrays.asList(email1, email2); + CreateBatchEmailsResponse expectedResponse = EmailsUtil.createBatchEmailsResponse(); + + when(batch.send(batchEmails)).thenReturn(expectedResponse); + + CreateBatchEmailsResponse response = batch.send(batchEmails); + + assertNotNull(response); + assertEquals(expectedResponse.getData().size(), response.getData().size()); + verify(batch, times(1)).send(batchEmails); + } } diff --git a/src/test/java/com/resend/services/util/EmailsUtil.java b/src/test/java/com/resend/services/util/EmailsUtil.java index b791daf..efaadc1 100644 --- a/src/test/java/com/resend/services/util/EmailsUtil.java +++ b/src/test/java/com/resend/services/util/EmailsUtil.java @@ -27,6 +27,35 @@ public static Tag createTag() { .build(); } + public static Template createTemplate() { + Map variables = new HashMap<>(); + variables.put("name", "John"); + variables.put("company", "Acme Corp"); + + return Template.builder() + .id("template_123") + .variables(variables) + .build(); + } + + public static Template createTemplateWithAddVariable() { + return Template.builder() + .id("template_123") + .addVariable("name", "John") + .addVariable("company", "Acme Corp") + .build(); + } + + public static Template createTemplateWithVarargs() { + return Template.builder() + .id("template_123") + .variables( + Template.variable("name", "John"), + Template.variable("company", "Acme Corp") + ) + .build(); + } + public static CreateEmailOptions createEmailOptions() { return CreateEmailOptions.builder() .from("Acme ") @@ -42,6 +71,15 @@ public static CreateEmailOptions createEmailOptions() { .build(); } + public static CreateEmailOptions createEmailOptionsWithTemplate() { + return CreateEmailOptions.builder() + .from("Acme ") + .to(Arrays.asList("example@resend.dev")) + .subject("Welcome to Acme") + .template(createTemplate()) + .build(); + } + public static RequestOptions createRequestOptions() { return RequestOptions.builder() .setIdempotencyKey("welcome-user/123456789").build();