From 60cb7260ecf140883c0719c548e97d49c9b959d8 Mon Sep 17 00:00:00 2001 From: Bjarn Bronsveld Date: Fri, 27 Feb 2026 12:13:06 +0100 Subject: [PATCH] feat: support multiple reply-to addresses in EmailEndpoint --- .../lettermint/endpoints/EmailEndpoint.java | 12 +++--- .../java/co/lettermint/EmailEndpointTest.java | 42 ++++++++++++++++++- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/main/java/co/lettermint/endpoints/EmailEndpoint.java b/src/main/java/co/lettermint/endpoints/EmailEndpoint.java index b20ff75..3d72ced 100644 --- a/src/main/java/co/lettermint/endpoints/EmailEndpoint.java +++ b/src/main/java/co/lettermint/endpoints/EmailEndpoint.java @@ -15,7 +15,7 @@ public class EmailEndpoint extends Endpoint { private List to; private List cc; private List bcc; - private String replyTo; + private List replyTo; private String subject; private String html; private String text; @@ -39,7 +39,7 @@ private void reset() { this.to = new ArrayList<>(); this.cc = new ArrayList<>(); this.bcc = new ArrayList<>(); - this.replyTo = null; + this.replyTo = new ArrayList<>(); this.subject = null; this.html = null; this.text = null; @@ -85,10 +85,10 @@ public EmailEndpoint bcc(String... emails) { } /** - * Set the reply-to email address. + * Set reply-to email addresses. Replaces any existing reply-to addresses. */ - public EmailEndpoint replyTo(String replyTo) { - this.replyTo = replyTo; + public EmailEndpoint replyTo(String... emails) { + this.replyTo = new ArrayList<>(Arrays.asList(emails)); return this; } @@ -233,7 +233,7 @@ private Map buildPayload() { payload.put("bcc", bcc); } - if (replyTo != null) { + if (!replyTo.isEmpty()) { payload.put("reply_to", replyTo); } diff --git a/src/test/java/co/lettermint/EmailEndpointTest.java b/src/test/java/co/lettermint/EmailEndpointTest.java index 64a56f2..fd29966 100644 --- a/src/test/java/co/lettermint/EmailEndpointTest.java +++ b/src/test/java/co/lettermint/EmailEndpointTest.java @@ -97,7 +97,7 @@ void testEmailWithAllOptions() throws Exception { assertTrue(body.contains("\"to\":[\"recipient1@example.com\",\"recipient2@example.com\"]")); assertTrue(body.contains("\"cc\":[\"cc@example.com\"]")); assertTrue(body.contains("\"bcc\":[\"bcc@example.com\"]")); - assertTrue(body.contains("\"reply_to\":\"reply@example.com\"")); + assertTrue(body.contains("\"reply_to\":[\"reply@example.com\"]")); assertTrue(body.contains("\"subject\":\"Welcome!\"")); assertTrue(body.contains("\"html\":\"

Hello World

\"")); assertTrue(body.contains("\"text\":\"Hello World\"")); @@ -179,6 +179,46 @@ void testSingleHeaderMethod() throws Exception { assertTrue(body.contains("\"X-Second\":\"value2\"")); } + @Test + void testReplyToSingleString() throws Exception { + mockWebServer.enqueue(new MockResponse() + .setBody("{\"message_id\": \"msg_123\", \"status\": \"queued\"}") + .setHeader("Content-Type", "application/json")); + + lettermint.email() + .from("sender@example.com") + .to("recipient@example.com") + .subject("Test") + .text("Test") + .replyTo("reply@example.com") + .send(); + + RecordedRequest request = mockWebServer.takeRequest(); + String body = request.getBody().readUtf8(); + + assertTrue(body.contains("\"reply_to\":[\"reply@example.com\"]")); + } + + @Test + void testReplyToMultipleAddresses() throws Exception { + mockWebServer.enqueue(new MockResponse() + .setBody("{\"message_id\": \"msg_123\", \"status\": \"queued\"}") + .setHeader("Content-Type", "application/json")); + + lettermint.email() + .from("sender@example.com") + .to("recipient@example.com") + .subject("Test") + .text("Test") + .replyTo("reply1@example.com", "reply2@example.com") + .send(); + + RecordedRequest request = mockWebServer.takeRequest(); + String body = request.getBody().readUtf8(); + + assertTrue(body.contains("\"reply_to\":[\"reply1@example.com\",\"reply2@example.com\"]")); + } + @Test void testSingleMetadataMethod() throws Exception { mockWebServer.enqueue(new MockResponse()