From ba66ce71624243c49feb7c585bb2b0ecd65919a8 Mon Sep 17 00:00:00 2001 From: Ramunas Pabreza Date: Tue, 31 Mar 2026 16:34:35 +0300 Subject: [PATCH 1/3] Whatsapp integration --- README.md | 74 +++++++++++ .../java/com/mailersend/sdk/MailerSend.java | 16 ++- .../com/mailersend/sdk/whatsapp/WhatsApp.java | 41 ++++++ .../sdk/whatsapp/WhatsAppBuilder.java | 124 ++++++++++++++++++ .../sdk/whatsapp/WhatsAppBuilderBody.java | 33 +++++ .../sdk/whatsapp/WhatsAppPersonalization.java | 67 ++++++++++ .../whatsapp/WhatsAppPersonalizationData.java | 28 ++++ .../mailersend/sdk/tests/WhatsAppTests.java | 79 +++++++++++ .../EmailSendTest_ScheduleEmailTest().json | 123 +---------------- ...ailSendTest_TestEmailWithAttachment().json | 2 +- ...boundRoutesTest_AddInboundRouteTest().json | 2 +- ...ndRoutesTest_UpdateInboundRouteTest().json | 2 +- .../WhatsAppTests_TestSendWhatsApp().json | 1 + ...TestSendWhatsAppWithPersonalization().json | 1 + 14 files changed, 466 insertions(+), 127 deletions(-) create mode 100644 src/main/java/com/mailersend/sdk/whatsapp/WhatsApp.java create mode 100644 src/main/java/com/mailersend/sdk/whatsapp/WhatsAppBuilder.java create mode 100644 src/main/java/com/mailersend/sdk/whatsapp/WhatsAppBuilderBody.java create mode 100644 src/main/java/com/mailersend/sdk/whatsapp/WhatsAppPersonalization.java create mode 100644 src/main/java/com/mailersend/sdk/whatsapp/WhatsAppPersonalizationData.java create mode 100644 src/test/java/com/mailersend/sdk/tests/WhatsAppTests.java create mode 100644 src/test/resources/fixtures/WhatsAppTests_TestSendWhatsApp().json create mode 100644 src/test/resources/fixtures/WhatsAppTests_TestSendWhatsAppWithPersonalization().json diff --git a/README.md b/README.md index a26fd8a..fff5f11 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,9 @@ MailerSend Java SDK - [Delete an SMS webhook](#delete-an-sms-webhook) - [SMS](#sms) - [Send an SMS with personalization](#send-an-sms-with-personalization) +- [WhatsApp](#whatsapp) + - [Send a WhatsApp message](#send-a-whatsapp-message) + - [Send a WhatsApp message with personalization](#send-a-whatsapp-message-with-personalization) - [Testing](#testing) - [Support and Feedback](#support-and-feedback) @@ -2740,6 +2743,77 @@ public void sendSms() { } ``` +# WhatsApp + +### Send a WhatsApp message + +```java +import com.mailersend.sdk.MailerSend; +import com.mailersend.sdk.exceptions.MailerSendException; + +public void sendWhatsApp() { + + MailerSend ms = new MailerSend(); + ms.setToken("mailersend token"); + + try { + + String messageId = ms.whatsapp().builder() + .from("12345678901") + .addRecipient("19191234567") + .templateId("your_template_id") + .send(); + + System.out.println(messageId); + + } catch (MailerSendException e) { + + e.printStackTrace(); + } +} +``` + +### Send a WhatsApp message with personalization + +```java +import com.mailersend.sdk.MailerSend; +import com.mailersend.sdk.exceptions.MailerSendException; +import com.mailersend.sdk.whatsapp.WhatsAppPersonalization; + +public void sendWhatsAppWithPersonalization() { + + MailerSend ms = new MailerSend(); + ms.setToken("mailersend token"); + + try { + + WhatsAppPersonalization p1 = new WhatsAppPersonalization("19191234567") + .setHeader(new String[]{"John"}) + .setBody(new String[]{"order #1234", "tomorrow"}) + .setButtons(new String[]{"https://example.com/track/1234"}); + + WhatsAppPersonalization p2 = new WhatsAppPersonalization("19199876543") + .setHeader(new String[]{"Jane"}) + .setBody(new String[]{"order #5678", "Friday"}); + + String messageId = ms.whatsapp().builder() + .from("12345678901") + .addRecipient("19191234567") + .addRecipient("19199876543") + .templateId("your_template_id") + .addPersonalization(p1) + .addPersonalization(p2) + .send(); + + System.out.println(messageId); + + } catch (MailerSendException e) { + + e.printStackTrace(); + } +} +``` + # Testing Change the properties in the `TestHelper` class of the `com.mailersend.sdk.tests` package to correspond to your account details, then simply run diff --git a/src/main/java/com/mailersend/sdk/MailerSend.java b/src/main/java/com/mailersend/sdk/MailerSend.java index 77eb4e9..322a613 100644 --- a/src/main/java/com/mailersend/sdk/MailerSend.java +++ b/src/main/java/com/mailersend/sdk/MailerSend.java @@ -17,6 +17,7 @@ import com.mailersend.sdk.scheduledmessages.ScheduledMessages; import com.mailersend.sdk.sms.Sms; import com.mailersend.sdk.templates.Templates; +import com.mailersend.sdk.whatsapp.WhatsApp; import com.mailersend.sdk.tokens.Tokens; import com.mailersend.sdk.webhooks.Webhooks; import com.mailsend.sdk.emailverification.EmailVerification; @@ -44,7 +45,8 @@ public class MailerSend { private ScheduledMessages scheduledMessages = null; private EmailVerification emailVerification = null; private Sms sms = null; - + private WhatsApp whatsapp = null; + /** *

Constructor for MailerSend.

*/ @@ -63,6 +65,7 @@ public MailerSend() { scheduledMessages = new ScheduledMessages(this); emailVerification = new EmailVerification(this); sms = new Sms(this); + whatsapp = new WhatsApp(this); } @@ -202,7 +205,16 @@ public EmailVerification emailVerification() { public Sms sms() { return sms; } - + + /** + * Get the whatsapp access object + * + * @return The WhatsApp object + */ + public WhatsApp whatsapp() { + return whatsapp; + } + /** * Sets the MailerSend token * diff --git a/src/main/java/com/mailersend/sdk/whatsapp/WhatsApp.java b/src/main/java/com/mailersend/sdk/whatsapp/WhatsApp.java new file mode 100644 index 0000000..594f3eb --- /dev/null +++ b/src/main/java/com/mailersend/sdk/whatsapp/WhatsApp.java @@ -0,0 +1,41 @@ +/************************************************* + * MailerSend Java SDK + * https://github.com/mailersend/mailersend-java + * + * @author MailerSend + * https://mailersend.com + **************************************************/ +package com.mailersend.sdk.whatsapp; + +import com.mailersend.sdk.MailerSend; + +/** + *

WhatsApp class.

+ * + * @author mailersend + * @version $Id: $Id + */ +public class WhatsApp { + + private MailerSend apiObjectReference; + private WhatsAppBuilder builder; + + /** + *

Constructor for WhatsApp.

+ * + * @param ref a {@link com.mailersend.sdk.MailerSend} object. + */ + public WhatsApp(MailerSend ref) { + apiObjectReference = ref; + builder = new WhatsAppBuilder(ref); + } + + /** + *

builder.

+ * + * @return a {@link com.mailersend.sdk.whatsapp.WhatsAppBuilder} object. + */ + public WhatsAppBuilder builder() { + return builder; + } +} diff --git a/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppBuilder.java b/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppBuilder.java new file mode 100644 index 0000000..502dc4d --- /dev/null +++ b/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppBuilder.java @@ -0,0 +1,124 @@ +/************************************************* + * MailerSend Java SDK + * https://github.com/mailersend/mailersend-java + * + * @author MailerSend + * https://mailersend.com + **************************************************/ +package com.mailersend.sdk.whatsapp; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.mailersend.sdk.MailerSend; +import com.mailersend.sdk.MailerSendApi; +import com.mailersend.sdk.MailerSendResponse; +import com.mailersend.sdk.exceptions.MailerSendException; +import com.mailersend.sdk.util.JsonSerializationDeserializationStrategy; + +/** + *

WhatsAppBuilder class.

+ * + * @author mailersend + * @version $Id: $Id + */ +public class WhatsAppBuilder { + + private WhatsAppBuilderBody builderBody; + private MailerSend apiObjectReference; + + /** + *

Constructor for WhatsAppBuilder.

+ * + * @param ref a {@link com.mailersend.sdk.MailerSend} object. + */ + public WhatsAppBuilder(MailerSend ref) { + apiObjectReference = ref; + builderBody = new WhatsAppBuilderBody(); + } + + /** + *

from.

+ * + * @param from sender phone number in international format without + + * @return a {@link com.mailersend.sdk.whatsapp.WhatsAppBuilder} object. + */ + public WhatsAppBuilder from(String from) { + builderBody.from = from; + return this; + } + + /** + *

addRecipient.

+ * + * @param phoneNumber recipient phone number in international format without + + * @return a {@link com.mailersend.sdk.whatsapp.WhatsAppBuilder} object. + */ + public WhatsAppBuilder addRecipient(String phoneNumber) { + builderBody.to.add(phoneNumber); + return this; + } + + /** + *

templateId.

+ * + * @param templateId the ID of the approved WhatsApp template + * @return a {@link com.mailersend.sdk.whatsapp.WhatsAppBuilder} object. + */ + public WhatsAppBuilder templateId(String templateId) { + builderBody.templateId = templateId; + return this; + } + + /** + *

addPersonalization.

+ * + * @param personalization a {@link com.mailersend.sdk.whatsapp.WhatsAppPersonalization} object. + * @return a {@link com.mailersend.sdk.whatsapp.WhatsAppBuilder} object. + */ + public WhatsAppBuilder addPersonalization(WhatsAppPersonalization personalization) { + if (builderBody.personalization == null) { + builderBody.personalization = new ArrayList(); + } + builderBody.personalization.add(personalization); + return this; + } + + /** + *

send.

+ * + * @return the message ID from the X-Message-Id response header + * @throws com.mailersend.sdk.exceptions.MailerSendException if any. + */ + public String send() throws MailerSendException { + String endpoint = "/whatsapp/send"; + + MailerSendApi api = new MailerSendApi(); + api.setToken(apiObjectReference.getToken()); + + Gson gson = new GsonBuilder() + .addSerializationExclusionStrategy(new JsonSerializationDeserializationStrategy(false)) + .addDeserializationExclusionStrategy(new JsonSerializationDeserializationStrategy(true)) + .create(); + + String json = gson.toJson(builderBody); + + builderBody = new WhatsAppBuilderBody(); + + MailerSendResponse response = api.postRequest(endpoint, json, MailerSendResponse.class); + + String messageId = null; + + for (Entry> entry : response.headers.entrySet()) { + if (entry.getKey().equals("x-message-id")) { + messageId = entry.getValue().get(0); + break; + } + } + + return messageId; + } +} diff --git a/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppBuilderBody.java b/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppBuilderBody.java new file mode 100644 index 0000000..abc80c6 --- /dev/null +++ b/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppBuilderBody.java @@ -0,0 +1,33 @@ +/************************************************* + * MailerSend Java SDK + * https://github.com/mailersend/mailersend-java + * + * @author MailerSend + * https://mailersend.com + **************************************************/ +package com.mailersend.sdk.whatsapp; + +import java.util.ArrayList; + +import com.google.gson.annotations.SerializedName; + +/** + *

WhatsAppBuilderBody class.

+ * + * @author mailersend + * @version $Id: $Id + */ +public class WhatsAppBuilderBody { + + @SerializedName("from") + public String from; + + @SerializedName("to") + public ArrayList to = new ArrayList(); + + @SerializedName("template_id") + public String templateId; + + @SerializedName("personalization") + public ArrayList personalization = null; +} diff --git a/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppPersonalization.java b/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppPersonalization.java new file mode 100644 index 0000000..d2438f6 --- /dev/null +++ b/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppPersonalization.java @@ -0,0 +1,67 @@ +/************************************************* + * MailerSend Java SDK + * https://github.com/mailersend/mailersend-java + * + * @author MailerSend + * https://mailersend.com + **************************************************/ +package com.mailersend.sdk.whatsapp; + +import com.google.gson.annotations.SerializedName; + +/** + *

WhatsAppPersonalization class.

+ * + * @author mailersend + * @version $Id: $Id + */ +public class WhatsAppPersonalization { + + @SerializedName("to") + public String to; + + @SerializedName("data") + public WhatsAppPersonalizationData data = new WhatsAppPersonalizationData(); + + /** + *

Constructor for WhatsAppPersonalization.

+ * + * @param to the recipient phone number + */ + public WhatsAppPersonalization(String to) { + this.to = to; + } + + /** + *

setHeader.

+ * + * @param header array of header variable values + * @return a {@link com.mailersend.sdk.whatsapp.WhatsAppPersonalization} object. + */ + public WhatsAppPersonalization setHeader(String[] header) { + this.data.header = header; + return this; + } + + /** + *

setBody.

+ * + * @param body array of body variable values + * @return a {@link com.mailersend.sdk.whatsapp.WhatsAppPersonalization} object. + */ + public WhatsAppPersonalization setBody(String[] body) { + this.data.body = body; + return this; + } + + /** + *

setButtons.

+ * + * @param buttons array of button variable values + * @return a {@link com.mailersend.sdk.whatsapp.WhatsAppPersonalization} object. + */ + public WhatsAppPersonalization setButtons(String[] buttons) { + this.data.buttons = buttons; + return this; + } +} diff --git a/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppPersonalizationData.java b/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppPersonalizationData.java new file mode 100644 index 0000000..e74cc65 --- /dev/null +++ b/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppPersonalizationData.java @@ -0,0 +1,28 @@ +/************************************************* + * MailerSend Java SDK + * https://github.com/mailersend/mailersend-java + * + * @author MailerSend + * https://mailersend.com + **************************************************/ +package com.mailersend.sdk.whatsapp; + +import com.google.gson.annotations.SerializedName; + +/** + *

WhatsAppPersonalizationData class.

+ * + * @author mailersend + * @version $Id: $Id + */ +public class WhatsAppPersonalizationData { + + @SerializedName("header") + public String[] header; + + @SerializedName("body") + public String[] body; + + @SerializedName("buttons") + public String[] buttons; +} diff --git a/src/test/java/com/mailersend/sdk/tests/WhatsAppTests.java b/src/test/java/com/mailersend/sdk/tests/WhatsAppTests.java new file mode 100644 index 0000000..c19ba13 --- /dev/null +++ b/src/test/java/com/mailersend/sdk/tests/WhatsAppTests.java @@ -0,0 +1,79 @@ +package com.mailersend.sdk.tests; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.fail; + +import java.io.IOException; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; + +import com.mailersend.sdk.MailerSend; +import com.mailersend.sdk.exceptions.MailerSendException; +import com.mailersend.sdk.whatsapp.WhatsAppPersonalization; +import com.mailersend.sdk.vcr.VcrRecorder; + +public class WhatsAppTests { + + @BeforeEach + public void setupEach(TestInfo info) throws IOException { + VcrRecorder.useRecording("WhatsAppTests_" + info.getDisplayName()); + } + + @AfterEach + public void afterEach() throws IOException { + VcrRecorder.stopRecording(); + } + + @Test + public void TestSendWhatsApp() { + MailerSend ms = new MailerSend(); + ms.setToken(TestHelper.validToken); + + try { + String messageId = ms.whatsapp().builder() + .from("12345678901") + .addRecipient("19191234567") + .templateId("template_id_123") + .send(); + + assertNotNull(messageId); + + } catch (MailerSendException e) { + fail(); + } + } + + @Test + public void TestSendWhatsAppWithPersonalization() { + MailerSend ms = new MailerSend(); + ms.setToken(TestHelper.validToken); + + try { + WhatsAppPersonalization p1 = new WhatsAppPersonalization("19191234567") + .setHeader(new String[]{"John"}) + .setBody(new String[]{"order #1234", "tomorrow"}) + .setButtons(new String[]{"https://example.com/track/1234"}); + + WhatsAppPersonalization p2 = new WhatsAppPersonalization("19199876543") + .setHeader(new String[]{"Jane"}) + .setBody(new String[]{"order #5678", "Friday"}); + + String messageId = ms.whatsapp().builder() + .from("12345678901") + .addRecipient("19191234567") + .addRecipient("19199876543") + .templateId("template_id_123") + .addPersonalization(p1) + .addPersonalization(p2) + .send(); + + assertNotNull(messageId); + + } catch (MailerSendException e) { + fail(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/fixtures/EmailSendTest_ScheduleEmailTest().json b/src/test/resources/fixtures/EmailSendTest_ScheduleEmailTest().json index 1f5a774..3e8ffee 100644 --- a/src/test/resources/fixtures/EmailSendTest_ScheduleEmailTest().json +++ b/src/test/resources/fixtures/EmailSendTest_ScheduleEmailTest().json @@ -1,122 +1 @@ -{ - "4f6a751939688d9c22a55807b9b1717ea74552f7": { - "body": "", - "headers": { - ":status": [ - "202" - ], - "cache-control": [ - "no-cache, private" - ], - "cf-cache-status": [ - "DYNAMIC" - ], - "cf-ray": [ - "8ac5d0d95b7f7176-ATH" - ], - "content-type": [ - "text/html; charset\u003dUTF-8" - ], - "date": [ - "Thu, 01 Aug 2024 12:26:18 GMT" - ], - "server": [ - "cloudflare" - ], - "strict-transport-security": [ - "max-age\u003d31536000; includeSubDomains" - ], - "x-apiquota-remaining": [ - "-1" - ], - "x-apiquota-reset": [ - "2024-08-02T00:00:00Z" - ], - "x-message-id": [ - "66ab7eea1101995a278ad874" - ] - }, - "statusCode": 202 - }, - "6b15cf69672ee532a9f601876778851cc4ca3135": { - "body": "", - "headers": { - ":status": [ - "202" - ], - "cache-control": [ - "no-cache, private" - ], - "cf-cache-status": [ - "DYNAMIC" - ], - "cf-ray": [ - "755442149ddbeea0-ATH" - ], - "content-type": [ - "text/html; charset\u003dUTF-8" - ], - "date": [ - "Wed, 05 Oct 2022 06:56:34 GMT" - ], - "server": [ - "cloudflare" - ], - "strict-transport-security": [ - "max-age\u003d15724800; includeSubDomains" - ], - "x-apiquota-remaining": [ - "-1" - ], - "x-apiquota-reset": [ - "2022-10-06T00:00:00Z" - ], - "x-message-id": [ - "633d2aa226762ac1d30457e0" - ], - "x-ratelimit-limit": [ - "120" - ], - "x-ratelimit-remaining": [ - "118" - ] - }, - "statusCode": 202 - }, - "e4a0bcf8b4e53b4dcfb4d96b2db3d8a0054a92f2": { - "body": "{\"message\":\"The send_at must be a date before or equal to 2024-08-04 12:24:25.\",\"errors\":{\"send_at\":[\"The send_at must be a date before or equal to 2024-08-04 12:24:25.\"]}}", - "headers": { - ":status": [ - "422" - ], - "cache-control": [ - "no-cache, private" - ], - "cf-cache-status": [ - "DYNAMIC" - ], - "cf-ray": [ - "8ac5ce134f316f56-ATH" - ], - "content-type": [ - "application/json" - ], - "date": [ - "Thu, 01 Aug 2024 12:24:25 GMT" - ], - "server": [ - "cloudflare" - ], - "strict-transport-security": [ - "max-age\u003d31536000; includeSubDomains" - ], - "x-apiquota-remaining": [ - "-1" - ], - "x-apiquota-reset": [ - "2024-08-02T00:00:00Z" - ] - }, - "statusCode": 422 - } -} \ No newline at end of file +{"4642fa6a28b7be97f75ff83526a63d726257c550":{"body":"{\"message\":\"Unauthenticated.\"}","headers":{":status":["401"],"alt-svc":["h3\u003d\":443\"; ma\u003d86400"],"cache-control":["no-cache, private"],"cf-cache-status":["DYNAMIC"],"cf-ray":["9e4f9a88dfcebc19-VNO"],"content-type":["application/json"],"date":["Tue, 31 Mar 2026 13:12:05 GMT"],"server":["cloudflare"],"x-envoy-upstream-service-time":["24"]},"statusCode":401},"6b15cf69672ee532a9f601876778851cc4ca3135":{"body":"","headers":{":status":["202"],"cache-control":["no-cache, private"],"cf-cache-status":["DYNAMIC"],"cf-ray":["755442149ddbeea0-ATH"],"content-type":["text/html; charset\u003dUTF-8"],"date":["Wed, 05 Oct 2022 06:56:34 GMT"],"server":["cloudflare"],"strict-transport-security":["max-age\u003d15724800; includeSubDomains"],"x-apiquota-remaining":["-1"],"x-apiquota-reset":["2022-10-06T00:00:00Z"],"x-message-id":["633d2aa226762ac1d30457e0"],"x-ratelimit-limit":["120"],"x-ratelimit-remaining":["118"]},"statusCode":202},"e4a0bcf8b4e53b4dcfb4d96b2db3d8a0054a92f2":{"body":"{\"message\":\"The send_at must be a date before or equal to 2024-08-04 12:24:25.\",\"errors\":{\"send_at\":[\"The send_at must be a date before or equal to 2024-08-04 12:24:25.\"]}}","headers":{":status":["422"],"cache-control":["no-cache, private"],"cf-cache-status":["DYNAMIC"],"cf-ray":["8ac5ce134f316f56-ATH"],"content-type":["application/json"],"date":["Thu, 01 Aug 2024 12:24:25 GMT"],"server":["cloudflare"],"strict-transport-security":["max-age\u003d31536000; includeSubDomains"],"x-apiquota-remaining":["-1"],"x-apiquota-reset":["2024-08-02T00:00:00Z"]},"statusCode":422},"4f6a751939688d9c22a55807b9b1717ea74552f7":{"body":"","headers":{":status":["202"],"cache-control":["no-cache, private"],"cf-cache-status":["DYNAMIC"],"cf-ray":["8ac5d0d95b7f7176-ATH"],"content-type":["text/html; charset\u003dUTF-8"],"date":["Thu, 01 Aug 2024 12:26:18 GMT"],"server":["cloudflare"],"strict-transport-security":["max-age\u003d31536000; includeSubDomains"],"x-apiquota-remaining":["-1"],"x-apiquota-reset":["2024-08-02T00:00:00Z"],"x-message-id":["66ab7eea1101995a278ad874"]},"statusCode":202}} \ No newline at end of file diff --git a/src/test/resources/fixtures/EmailSendTest_TestEmailWithAttachment().json b/src/test/resources/fixtures/EmailSendTest_TestEmailWithAttachment().json index b692dbd..4916112 100644 --- a/src/test/resources/fixtures/EmailSendTest_TestEmailWithAttachment().json +++ b/src/test/resources/fixtures/EmailSendTest_TestEmailWithAttachment().json @@ -1 +1 @@ -{"872ed332468f4b2427c07accf4e75f1353d64c4d":{"body":"","headers":{":status":["202"],"cache-control":["no-cache, private"],"cf-cache-status":["DYNAMIC"],"cf-ray":["8ac5ca303f6738c9-ATH"],"content-type":["text/html; charset\u003dUTF-8"],"date":["Thu, 01 Aug 2024 12:21:45 GMT"],"server":["cloudflare"],"strict-transport-security":["max-age\u003d31536000; includeSubDomains"],"x-apiquota-remaining":["-1"],"x-apiquota-reset":["2024-08-02T00:00:00Z"],"x-message-id":["66ab7dd9cdde5c03b77e1432"]},"statusCode":202},"50ed637b263854bc74bee8aaecd31258246e6a23":{"body":"","headers":{":status":["202"],"cache-control":["no-cache, private"],"cf-cache-status":["DYNAMIC"],"cf-ray":["746fdaa6cc12fd66-ATH"],"content-type":["text/html; charset\u003dUTF-8"],"date":["Wed, 07 Sep 2022 13:40:04 GMT"],"server":["cloudflare"],"strict-transport-security":["max-age\u003d15724800; includeSubDomains"],"x-apiquota-remaining":["-1"],"x-apiquota-reset":["2022-09-08T00:00:00Z"],"x-message-id":["63189f3455817566900b378c"],"x-ratelimit-limit":["120"],"x-ratelimit-remaining":["116"]},"statusCode":202}} \ No newline at end of file +{"872ed332468f4b2427c07accf4e75f1353d64c4d":{"body":"","headers":{":status":["202"],"cache-control":["no-cache, private"],"cf-cache-status":["DYNAMIC"],"cf-ray":["8ac5ca303f6738c9-ATH"],"content-type":["text/html; charset\u003dUTF-8"],"date":["Thu, 01 Aug 2024 12:21:45 GMT"],"server":["cloudflare"],"strict-transport-security":["max-age\u003d31536000; includeSubDomains"],"x-apiquota-remaining":["-1"],"x-apiquota-reset":["2024-08-02T00:00:00Z"],"x-message-id":["66ab7dd9cdde5c03b77e1432"]},"statusCode":202},"50ed637b263854bc74bee8aaecd31258246e6a23":{"body":"","headers":{":status":["202"],"cache-control":["no-cache, private"],"cf-cache-status":["DYNAMIC"],"cf-ray":["746fdaa6cc12fd66-ATH"],"content-type":["text/html; charset\u003dUTF-8"],"date":["Wed, 07 Sep 2022 13:40:04 GMT"],"server":["cloudflare"],"strict-transport-security":["max-age\u003d15724800; includeSubDomains"],"x-apiquota-remaining":["-1"],"x-apiquota-reset":["2022-09-08T00:00:00Z"],"x-message-id":["63189f3455817566900b378c"],"x-ratelimit-limit":["120"],"x-ratelimit-remaining":["116"]},"statusCode":202},"131edff4e931fea86e4a62aef6aefd19e9f14d7a":{"body":"{\"message\":\"Unauthenticated.\"}","headers":{":status":["401"],"alt-svc":["h3\u003d\":443\"; ma\u003d86400"],"cache-control":["no-cache, private"],"cf-cache-status":["DYNAMIC"],"cf-ray":["9e4f9a8809fdbc0d-VNO"],"content-type":["application/json"],"date":["Tue, 31 Mar 2026 13:12:05 GMT"],"server":["cloudflare"],"x-envoy-upstream-service-time":["33"]},"statusCode":401}} \ No newline at end of file diff --git a/src/test/resources/fixtures/InboundRoutesTest_AddInboundRouteTest().json b/src/test/resources/fixtures/InboundRoutesTest_AddInboundRouteTest().json index b53fa65..6c6c4aa 100644 --- a/src/test/resources/fixtures/InboundRoutesTest_AddInboundRouteTest().json +++ b/src/test/resources/fixtures/InboundRoutesTest_AddInboundRouteTest().json @@ -1 +1 @@ -{"9bb4c41a079fb76c9e0851c184152ba8c20379ae":{"body":"{\"data\":{\"id\":\"jpr9084z9xlw63dn\",\"name\":\"Test inbound name\",\"address\":\"emcbcwyz41fdrr7uuiz1@inbound.mailersend.net\",\"domain\":null,\"dns_checked_at\":null,\"enabled\":true,\"filters\":[{\"type\":\"match_all\",\"key\":null,\"comparer\":null,\"value\":null}],\"forwards\":[{\"type\":\"webhook\",\"value\":\"https:\\/\\/example-domain.com\",\"secret\":\"FRwZFJCkf7nbydrn0oq9uLc76USD4iaI\"}],\"mxValues\":{\"priority\":\"10\",\"target\":\"inbound.mailersend.net\"}}}","headers":{":status":["201"],"cache-control":["no-cache, private"],"cf-cache-status":["DYNAMIC"],"cf-ray":["73d3b22358826f68-ATH"],"content-type":["application/json"],"date":["Fri, 19 Aug 2022 14:49:26 GMT"],"expect-ct":["max-age\u003d604800, report-uri\u003d\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\""],"server":["cloudflare"],"strict-transport-security":["max-age\u003d15724800; includeSubDomains"],"x-apiquota-remaining":["-1"],"x-apiquota-reset":["2022-08-20T00:00:00Z"],"x-ratelimit-limit":["60"],"x-ratelimit-remaining":["57"]},"statusCode":201}} \ No newline at end of file +{"9bb4c41a079fb76c9e0851c184152ba8c20379ae":{"body":"{\"data\":{\"id\":\"jpr9084z9xlw63dn\",\"name\":\"Test inbound name\",\"address\":\"emcbcwyz41fdrr7uuiz1@inbound.mailersend.net\",\"domain\":null,\"dns_checked_at\":null,\"enabled\":true,\"filters\":[{\"type\":\"match_all\",\"key\":null,\"comparer\":null,\"value\":null}],\"forwards\":[{\"type\":\"webhook\",\"value\":\"https:\\/\\/example-domain.com\",\"secret\":\"FRwZFJCkf7nbydrn0oq9uLc76USD4iaI\"}],\"mxValues\":{\"priority\":\"10\",\"target\":\"inbound.mailersend.net\"}}}","headers":{":status":["201"],"cache-control":["no-cache, private"],"cf-cache-status":["DYNAMIC"],"cf-ray":["73d3b22358826f68-ATH"],"content-type":["application/json"],"date":["Fri, 19 Aug 2022 14:49:26 GMT"],"expect-ct":["max-age\u003d604800, report-uri\u003d\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\""],"server":["cloudflare"],"strict-transport-security":["max-age\u003d15724800; includeSubDomains"],"x-apiquota-remaining":["-1"],"x-apiquota-reset":["2022-08-20T00:00:00Z"],"x-ratelimit-limit":["60"],"x-ratelimit-remaining":["57"]},"statusCode":201},"b8a0377fe05e24ddd4159a4076934d0e3fb8dad1":{"body":"{\"message\":\"Unauthenticated.\"}","headers":{":status":["401"],"alt-svc":["h3\u003d\":443\"; ma\u003d86400"],"cache-control":["no-cache, private"],"cf-cache-status":["DYNAMIC"],"cf-ray":["9e4f9a866c42c9e2-VNO"],"content-type":["application/json"],"date":["Tue, 31 Mar 2026 13:12:04 GMT"],"server":["cloudflare"],"x-envoy-upstream-service-time":["33"]},"statusCode":401}} \ No newline at end of file diff --git a/src/test/resources/fixtures/InboundRoutesTest_UpdateInboundRouteTest().json b/src/test/resources/fixtures/InboundRoutesTest_UpdateInboundRouteTest().json index bba3e90..e66ae6f 100644 --- a/src/test/resources/fixtures/InboundRoutesTest_UpdateInboundRouteTest().json +++ b/src/test/resources/fixtures/InboundRoutesTest_UpdateInboundRouteTest().json @@ -1 +1 @@ -{"ce75fac589ecb966bccf60ac703836fca6e34608":{"body":"{\"data\":{\"id\":\"83yxj6ljoq4do2rm\",\"name\":\"Updated route name\",\"address\":\"vxlarh7vthhnagf3zved@inbound.mailersend.net\",\"domain\":null,\"dns_checked_at\":null,\"enabled\":true,\"filters\":[{\"type\":\"match_all\",\"key\":null,\"comparer\":null,\"value\":null}],\"forwards\":[{\"type\":\"webhook\",\"value\":\"https:\\/\\/example.com\",\"secret\":\"9IAyXyE6eAg2pre8QQfvcs3VPJSS8iaW\"}],\"mxValues\":{\"priority\":\"10\",\"target\":\"inbound.mailersend.net\"}}}","headers":{":status":["200"],"cache-control":["no-cache, private"],"cf-cache-status":["DYNAMIC"],"cf-ray":["73d3bf27ad6238d6-ATH"],"content-type":["application/json"],"date":["Fri, 19 Aug 2022 14:58:19 GMT"],"expect-ct":["max-age\u003d604800, report-uri\u003d\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\""],"server":["cloudflare"],"strict-transport-security":["max-age\u003d15724800; includeSubDomains"],"x-apiquota-remaining":["-1"],"x-apiquota-reset":["2022-08-20T00:00:00Z"],"x-ratelimit-limit":["60"],"x-ratelimit-remaining":["59"]},"statusCode":200}} \ No newline at end of file +{"1aff61f4d4446105b742718ccb14f912cd075602":{"body":"{\n \"message\": \"Resource not found.\"\n}","headers":{":status":["404"],"alt-svc":["h3\u003d\":443\"; ma\u003d86400"],"cache-control":["no-cache, private"],"cf-cache-status":["DYNAMIC"],"cf-ray":["9e4f9a859958c9d5-VNO"],"content-type":["application/json"],"date":["Tue, 31 Mar 2026 13:12:04 GMT"],"server":["cloudflare"],"x-envoy-upstream-service-time":["31"]},"statusCode":404},"ce75fac589ecb966bccf60ac703836fca6e34608":{"body":"{\"data\":{\"id\":\"83yxj6ljoq4do2rm\",\"name\":\"Updated route name\",\"address\":\"vxlarh7vthhnagf3zved@inbound.mailersend.net\",\"domain\":null,\"dns_checked_at\":null,\"enabled\":true,\"filters\":[{\"type\":\"match_all\",\"key\":null,\"comparer\":null,\"value\":null}],\"forwards\":[{\"type\":\"webhook\",\"value\":\"https:\\/\\/example.com\",\"secret\":\"9IAyXyE6eAg2pre8QQfvcs3VPJSS8iaW\"}],\"mxValues\":{\"priority\":\"10\",\"target\":\"inbound.mailersend.net\"}}}","headers":{":status":["200"],"cache-control":["no-cache, private"],"cf-cache-status":["DYNAMIC"],"cf-ray":["73d3bf27ad6238d6-ATH"],"content-type":["application/json"],"date":["Fri, 19 Aug 2022 14:58:19 GMT"],"expect-ct":["max-age\u003d604800, report-uri\u003d\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\""],"server":["cloudflare"],"strict-transport-security":["max-age\u003d15724800; includeSubDomains"],"x-apiquota-remaining":["-1"],"x-apiquota-reset":["2022-08-20T00:00:00Z"],"x-ratelimit-limit":["60"],"x-ratelimit-remaining":["59"]},"statusCode":200}} \ No newline at end of file diff --git a/src/test/resources/fixtures/WhatsAppTests_TestSendWhatsApp().json b/src/test/resources/fixtures/WhatsAppTests_TestSendWhatsApp().json new file mode 100644 index 0000000..1afe4ed --- /dev/null +++ b/src/test/resources/fixtures/WhatsAppTests_TestSendWhatsApp().json @@ -0,0 +1 @@ +{"2bb7d30db82f0eb4ba655eee85d9d4faa9859778":{"body":"","headers":{":status":["202"],"cache-control":["no-cache, private"],"content-type":["application/json"],"x-message-id":["wa_msg_id_123"]},"statusCode":202}} \ No newline at end of file diff --git a/src/test/resources/fixtures/WhatsAppTests_TestSendWhatsAppWithPersonalization().json b/src/test/resources/fixtures/WhatsAppTests_TestSendWhatsAppWithPersonalization().json new file mode 100644 index 0000000..dcbf25f --- /dev/null +++ b/src/test/resources/fixtures/WhatsAppTests_TestSendWhatsAppWithPersonalization().json @@ -0,0 +1 @@ +{"fd5817b4599977adf389348739c54d7d68b3ccf0":{"body":"","headers":{":status":["202"],"cache-control":["no-cache, private"],"content-type":["application/json"],"x-message-id":["wa_msg_id_456"]},"statusCode":202}} \ No newline at end of file From 9e7bc8d619167de513367fbe9d13cf3013db8aee Mon Sep 17 00:00:00 2001 From: Ramunas Pabreza Date: Tue, 1 Sep 2026 14:02:45 +0300 Subject: [PATCH 2/3] Last touches --- README.md | 2 ++ .../sdk/whatsapp/WhatsAppBuilder.java | 28 ++++++++----------- .../sdk/whatsapp/WhatsAppPersonalization.java | 2 +- .../sdk/whatsapp/WhatsAppSendResponse.java | 23 +++++++++++++++ .../whatsapp/WhatsAppSendResponseData.java | 22 +++++++++++++++ .../mailersend/sdk/tests/WhatsAppTests.java | 27 +++++++++++++++--- .../WhatsAppTests_TestSendWhatsApp().json | 2 +- ...TestSendWhatsAppWithPersonalization().json | 2 +- ...tSendWhatsAppWithoutMessageIdHeader().json | 1 + 9 files changed, 86 insertions(+), 23 deletions(-) create mode 100644 src/main/java/com/mailersend/sdk/whatsapp/WhatsAppSendResponse.java create mode 100644 src/main/java/com/mailersend/sdk/whatsapp/WhatsAppSendResponseData.java create mode 100644 src/test/resources/fixtures/WhatsAppTests_TestSendWhatsAppWithoutMessageIdHeader().json diff --git a/README.md b/README.md index 6d901ec..618f7d1 100644 --- a/README.md +++ b/README.md @@ -4538,6 +4538,8 @@ public void deleteInvite() { # WhatsApp +`from` takes a connected WhatsApp sender, either as its phone number in E.164 format or as its MailerSend sender ID. A sender connected with a Meta virtual number has no phone number, so it can only be addressed by its sender ID. Recipients are phone numbers in E.164 format, or a BSUID taken from an inbound message. Sending requires a token with the `whatsapp_full` scope. + ### Send a WhatsApp message ```java diff --git a/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppBuilder.java b/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppBuilder.java index 502dc4d..d6d3ced 100644 --- a/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppBuilder.java +++ b/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppBuilder.java @@ -8,14 +8,11 @@ package com.mailersend.sdk.whatsapp; import java.util.ArrayList; -import java.util.List; -import java.util.Map.Entry; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.mailersend.sdk.MailerSend; import com.mailersend.sdk.MailerSendApi; -import com.mailersend.sdk.MailerSendResponse; import com.mailersend.sdk.exceptions.MailerSendException; import com.mailersend.sdk.util.JsonSerializationDeserializationStrategy; @@ -43,7 +40,7 @@ public WhatsAppBuilder(MailerSend ref) { /** *

from.

* - * @param from sender phone number in international format without + + * @param from the sender to send from, either a connected WhatsApp sender's phone number in E.164 format or its MailerSend sender ID * @return a {@link com.mailersend.sdk.whatsapp.WhatsAppBuilder} object. */ public WhatsAppBuilder from(String from) { @@ -54,11 +51,11 @@ public WhatsAppBuilder from(String from) { /** *

addRecipient.

* - * @param phoneNumber recipient phone number in international format without + + * @param recipient a phone number in E.164 format, or a BSUID taken from an inbound message * @return a {@link com.mailersend.sdk.whatsapp.WhatsAppBuilder} object. */ - public WhatsAppBuilder addRecipient(String phoneNumber) { - builderBody.to.add(phoneNumber); + public WhatsAppBuilder addRecipient(String recipient) { + builderBody.to.add(recipient); return this; } @@ -90,7 +87,7 @@ public WhatsAppBuilder addPersonalization(WhatsAppPersonalization personalizatio /** *

send.

* - * @return the message ID from the X-Message-Id response header + * @return the ID of the created message * @throws com.mailersend.sdk.exceptions.MailerSendException if any. */ public String send() throws MailerSendException { @@ -108,17 +105,16 @@ public String send() throws MailerSendException { builderBody = new WhatsAppBuilderBody(); - MailerSendResponse response = api.postRequest(endpoint, json, MailerSendResponse.class); + WhatsAppSendResponse response = api.postRequest(endpoint, json, WhatsAppSendResponse.class); - String messageId = null; + if (response.messageId != null && !response.messageId.isBlank()) { + return response.messageId; + } - for (Entry> entry : response.headers.entrySet()) { - if (entry.getKey().equals("x-message-id")) { - messageId = entry.getValue().get(0); - break; - } + if (response.data != null) { + return response.data.id; } - return messageId; + return null; } } diff --git a/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppPersonalization.java b/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppPersonalization.java index d2438f6..80f28e7 100644 --- a/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppPersonalization.java +++ b/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppPersonalization.java @@ -26,7 +26,7 @@ public class WhatsAppPersonalization { /** *

Constructor for WhatsAppPersonalization.

* - * @param to the recipient phone number + * @param to the recipient the values apply to, as listed in the message's recipients */ public WhatsAppPersonalization(String to) { this.to = to; diff --git a/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppSendResponse.java b/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppSendResponse.java new file mode 100644 index 0000000..aa31562 --- /dev/null +++ b/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppSendResponse.java @@ -0,0 +1,23 @@ +/************************************************* + * MailerSend Java SDK + * https://github.com/mailersend/mailersend-java + * + * @author MailerSend + * https://mailersend.com + **************************************************/ +package com.mailersend.sdk.whatsapp; + +import com.google.gson.annotations.SerializedName; +import com.mailersend.sdk.MailerSendResponse; + +/** + *

WhatsAppSendResponse class.

+ * + * @author mailersend + * @version $Id: $Id + */ +public class WhatsAppSendResponse extends MailerSendResponse { + + @SerializedName("data") + public WhatsAppSendResponseData data; +} diff --git a/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppSendResponseData.java b/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppSendResponseData.java new file mode 100644 index 0000000..de16da2 --- /dev/null +++ b/src/main/java/com/mailersend/sdk/whatsapp/WhatsAppSendResponseData.java @@ -0,0 +1,22 @@ +/************************************************* + * MailerSend Java SDK + * https://github.com/mailersend/mailersend-java + * + * @author MailerSend + * https://mailersend.com + **************************************************/ +package com.mailersend.sdk.whatsapp; + +import com.google.gson.annotations.SerializedName; + +/** + *

WhatsAppSendResponseData class.

+ * + * @author mailersend + * @version $Id: $Id + */ +public class WhatsAppSendResponseData { + + @SerializedName("id") + public String id; +} diff --git a/src/test/java/com/mailersend/sdk/tests/WhatsAppTests.java b/src/test/java/com/mailersend/sdk/tests/WhatsAppTests.java index c19ba13..4fa4f51 100644 --- a/src/test/java/com/mailersend/sdk/tests/WhatsAppTests.java +++ b/src/test/java/com/mailersend/sdk/tests/WhatsAppTests.java @@ -1,6 +1,6 @@ package com.mailersend.sdk.tests; -import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; import java.io.IOException; @@ -39,7 +39,7 @@ public void TestSendWhatsApp() { .templateId("template_id_123") .send(); - assertNotNull(messageId); + assertEquals("67f91abd69f79df391e9d78d", messageId); } catch (MailerSendException e) { fail(); @@ -70,10 +70,29 @@ public void TestSendWhatsAppWithPersonalization() { .addPersonalization(p2) .send(); - assertNotNull(messageId); + assertEquals("67f91b2c69f79df391e9d791", messageId); } catch (MailerSendException e) { fail(); } } -} \ No newline at end of file + + @Test + public void TestSendWhatsAppWithoutMessageIdHeader() { + MailerSend ms = new MailerSend(); + ms.setToken(TestHelper.validToken); + + try { + String messageId = ms.whatsapp().builder() + .from("12345678901") + .addRecipient("19191234567") + .templateId("template_id_123") + .send(); + + assertEquals("67f91abd69f79df391e9d78d", messageId); + + } catch (MailerSendException e) { + fail(); + } + } +} diff --git a/src/test/resources/fixtures/WhatsAppTests_TestSendWhatsApp().json b/src/test/resources/fixtures/WhatsAppTests_TestSendWhatsApp().json index 1afe4ed..6feb226 100644 --- a/src/test/resources/fixtures/WhatsAppTests_TestSendWhatsApp().json +++ b/src/test/resources/fixtures/WhatsAppTests_TestSendWhatsApp().json @@ -1 +1 @@ -{"2bb7d30db82f0eb4ba655eee85d9d4faa9859778":{"body":"","headers":{":status":["202"],"cache-control":["no-cache, private"],"content-type":["application/json"],"x-message-id":["wa_msg_id_123"]},"statusCode":202}} \ No newline at end of file +{"2bb7d30db82f0eb4ba655eee85d9d4faa9859778": {"body": "{\"data\":{\"id\":\"67f91abd69f79df391e9d78d\",\"created_at\":\"2026-08-31 07:24:20\"}}", "headers": {":status": ["202"], "cache-control": ["no-cache, private"], "content-type": ["application/json"], "date": ["Mon, 31 Aug 2026 07:24:20 GMT"], "x-message-id": ["67f91abd69f79df391e9d78d"], "x-ratelimit-limit": ["60"], "x-ratelimit-remaining": ["59"]}, "statusCode": 202}} \ No newline at end of file diff --git a/src/test/resources/fixtures/WhatsAppTests_TestSendWhatsAppWithPersonalization().json b/src/test/resources/fixtures/WhatsAppTests_TestSendWhatsAppWithPersonalization().json index dcbf25f..6a1ad0d 100644 --- a/src/test/resources/fixtures/WhatsAppTests_TestSendWhatsAppWithPersonalization().json +++ b/src/test/resources/fixtures/WhatsAppTests_TestSendWhatsAppWithPersonalization().json @@ -1 +1 @@ -{"fd5817b4599977adf389348739c54d7d68b3ccf0":{"body":"","headers":{":status":["202"],"cache-control":["no-cache, private"],"content-type":["application/json"],"x-message-id":["wa_msg_id_456"]},"statusCode":202}} \ No newline at end of file +{"fd5817b4599977adf389348739c54d7d68b3ccf0": {"body": "{\"data\":{\"id\":\"67f91b2c69f79df391e9d791\",\"created_at\":\"2026-08-31 07:26:04\"}}", "headers": {":status": ["202"], "cache-control": ["no-cache, private"], "content-type": ["application/json"], "date": ["Mon, 31 Aug 2026 07:24:20 GMT"], "x-message-id": ["67f91b2c69f79df391e9d791"], "x-ratelimit-limit": ["60"], "x-ratelimit-remaining": ["59"]}, "statusCode": 202}} \ No newline at end of file diff --git a/src/test/resources/fixtures/WhatsAppTests_TestSendWhatsAppWithoutMessageIdHeader().json b/src/test/resources/fixtures/WhatsAppTests_TestSendWhatsAppWithoutMessageIdHeader().json new file mode 100644 index 0000000..285b563 --- /dev/null +++ b/src/test/resources/fixtures/WhatsAppTests_TestSendWhatsAppWithoutMessageIdHeader().json @@ -0,0 +1 @@ +{"2bb7d30db82f0eb4ba655eee85d9d4faa9859778": {"body": "{\"data\":{\"id\":\"67f91abd69f79df391e9d78d\",\"created_at\":\"2026-08-31 07:24:20\"}}", "headers": {":status": ["202"], "cache-control": ["no-cache, private"], "content-type": ["application/json"], "date": ["Mon, 31 Aug 2026 07:24:20 GMT"], "x-ratelimit-limit": ["60"], "x-ratelimit-remaining": ["58"]}, "statusCode": 202}} \ No newline at end of file From b856cb30813bdedd294ae4e62d653297c1bb501e Mon Sep 17 00:00:00 2001 From: Ramunas Pabreza Date: Tue, 1 Sep 2026 14:30:30 +0300 Subject: [PATCH 3/3] Version bump --- README.md | 4 ++-- pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 618f7d1..21eb661 100644 --- a/README.md +++ b/README.md @@ -175,12 +175,12 @@ Using Maven: com.mailersend java-sdk - 2.1.0 + 2.2.0 Using Gradle: - implementation 'com.mailersend:java-sdk:2.1.0' + implementation 'com.mailersend:java-sdk:2.2.0' # Usage diff --git a/pom.xml b/pom.xml index 40e8d8e..4ac3e8b 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 com.mailersend java-sdk - 2.1.0 + 2.2.0 MailerSend Java SDK An SDK for MailerSend API https://github.com/mailersend/mailersend-java