From 181ca9c8b697631777371cf373facfce61e085a7 Mon Sep 17 00:00:00 2001 From: Mauricio Binda da Costa Date: Sat, 25 Mar 2023 13:50:57 -0300 Subject: [PATCH] fix #58 - fix incorrect serialization of parameter currency. - fix null value on DocumentParameter; - added new test. --- .../api/domain/messages/Currency.java | 96 +++++++++++++++++++ .../domain/messages/CurrencyParameter.java | 67 ++++--------- .../domain/messages/DocumentParameter.java | 3 + .../api/domain/messages/HeaderComponent.java | 3 + .../whatsapp/api/domain/messages/Image.java | 3 + .../SendTemplateMarketingMessageExample.java | 74 ++++++++++++++ .../impl/WhatsappBusinessCloudApiTest.java | 57 +++++++++++ .../expected/message/expectedMessage5.json | 73 ++++++++++++++ 8 files changed, 326 insertions(+), 50 deletions(-) create mode 100644 src/main/java/com/whatsapp/api/domain/messages/Currency.java create mode 100644 src/test/java/com/whatsapp/api/examples/SendTemplateMarketingMessageExample.java create mode 100644 src/test/resources/expected/message/expectedMessage5.json diff --git a/src/main/java/com/whatsapp/api/domain/messages/Currency.java b/src/main/java/com/whatsapp/api/domain/messages/Currency.java new file mode 100644 index 000000000..f8b3c2067 --- /dev/null +++ b/src/main/java/com/whatsapp/api/domain/messages/Currency.java @@ -0,0 +1,96 @@ +package com.whatsapp.api.domain.messages; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * The type Currency. + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Currency { + @JsonProperty("fallback_value") + private String fallbackValue; + @JsonProperty("code") + private String code; + @JsonProperty("amount_1000") + private long amount1000; + + /** + * Instantiates a new Currency. + */ + public Currency() { + } + + /** + * Instantiates a new Currency. + * + * @param fallbackValue the fallback value + * @param code the code + * @param amount1000 the amount 1000 + */ + public Currency(String fallbackValue, String code, long amount1000) { + this.fallbackValue = fallbackValue; + this.code = code; + this.amount1000 = amount1000; + } + + /** + * Gets fallback value. + * + * @return the fallback value + */ + public String getFallbackValue() { + return fallbackValue; + } + + /** + * Sets fallback value. + * + * @param fallbackValue the fallback value + * @return the fallback value + */ + public Currency setFallbackValue(String fallbackValue) { + this.fallbackValue = fallbackValue; + return this; + } + + /** + * Gets code. + * + * @return the code + */ + public String getCode() { + return code; + } + + /** + * Sets code. + * + * @param code the code + * @return the code + */ + public Currency setCode(String code) { + this.code = code; + return this; + } + + /** + * Gets amount 1000. + * + * @return the amount 1000 + */ + public long getAmount1000() { + return amount1000; + } + + /** + * Sets amount 1000. + * + * @param amount1000 the amount 1000 + * @return the amount 1000 + */ + public Currency setAmount1000(long amount1000) { + this.amount1000 = amount1000; + return this; + } +} diff --git a/src/main/java/com/whatsapp/api/domain/messages/CurrencyParameter.java b/src/main/java/com/whatsapp/api/domain/messages/CurrencyParameter.java index 30a57449d..f3ca4b765 100644 --- a/src/main/java/com/whatsapp/api/domain/messages/CurrencyParameter.java +++ b/src/main/java/com/whatsapp/api/domain/messages/CurrencyParameter.java @@ -9,12 +9,9 @@ */ @JsonInclude(JsonInclude.Include.NON_NULL) public class CurrencyParameter extends Parameter { - @JsonProperty("fallback_value") - private String fallbackValue; - @JsonProperty("code") - private String code; - @JsonProperty("amount_1000") - private long amount1000; + + @JsonProperty("currency") + private Currency currency; /** * Instantiates a new Currency parameter. @@ -24,62 +21,32 @@ public CurrencyParameter() { } /** - * Gets fallback value. - * - * @return the fallback value - */ - public String getFallbackValue() { - return fallbackValue; - } - - /** - * Sets fallback value. - * - * @param fallbackValue the fallback value - * @return the fallback value - */ - public CurrencyParameter setFallbackValue(String fallbackValue) { - this.fallbackValue = fallbackValue; - return this; - } - - /** - * Gets code. - * - * @return the code - */ - public String getCode() { - return code; - } - - /** - * Sets code. + * Instantiates a new Currency parameter. * - * @param code the code - * @return the code + * @param currency the currency */ - public CurrencyParameter setCode(String code) { - this.code = code; - return this; + public CurrencyParameter(Currency currency) { + super(ParameterType.CURRENCY); + this.currency = currency; } /** - * Gets amount 1000. + * Gets currency. * - * @return the amount 1000 + * @return the currency */ - public long getAmount1000() { - return amount1000; + public Currency getCurrency() { + return currency; } /** - * Sets amount 1000. + * Sets currency. * - * @param amount1000 the amount 1000 - * @return the amount 1000 + * @param currency the currency + * @return the currency */ - public CurrencyParameter setAmount1000(long amount1000) { - this.amount1000 = amount1000; + public CurrencyParameter setCurrency(Currency currency) { + this.currency = currency; return this; } } diff --git a/src/main/java/com/whatsapp/api/domain/messages/DocumentParameter.java b/src/main/java/com/whatsapp/api/domain/messages/DocumentParameter.java index 9cf78a6ac..426a92e91 100644 --- a/src/main/java/com/whatsapp/api/domain/messages/DocumentParameter.java +++ b/src/main/java/com/whatsapp/api/domain/messages/DocumentParameter.java @@ -1,11 +1,14 @@ package com.whatsapp.api.domain.messages; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; import com.whatsapp.api.domain.messages.type.ParameterType; /** * The type Document parameter. */ +@JsonInclude(Include.NON_NULL) public class DocumentParameter extends Parameter { @JsonProperty("id") diff --git a/src/main/java/com/whatsapp/api/domain/messages/HeaderComponent.java b/src/main/java/com/whatsapp/api/domain/messages/HeaderComponent.java index 7fd0301c3..acd3f726f 100644 --- a/src/main/java/com/whatsapp/api/domain/messages/HeaderComponent.java +++ b/src/main/java/com/whatsapp/api/domain/messages/HeaderComponent.java @@ -1,6 +1,9 @@ package com.whatsapp.api.domain.messages; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.whatsapp.api.domain.messages.type.ComponentType; +@JsonInclude(Include.NON_NULL) public class HeaderComponent extends Component { /** diff --git a/src/main/java/com/whatsapp/api/domain/messages/Image.java b/src/main/java/com/whatsapp/api/domain/messages/Image.java index bb9fe69ef..7584ff604 100644 --- a/src/main/java/com/whatsapp/api/domain/messages/Image.java +++ b/src/main/java/com/whatsapp/api/domain/messages/Image.java @@ -1,10 +1,13 @@ package com.whatsapp.api.domain.messages; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; /** * The type Image. */ +@JsonInclude(Include.NON_NULL) public class Image { @JsonProperty("id") diff --git a/src/test/java/com/whatsapp/api/examples/SendTemplateMarketingMessageExample.java b/src/test/java/com/whatsapp/api/examples/SendTemplateMarketingMessageExample.java new file mode 100644 index 000000000..c269d4796 --- /dev/null +++ b/src/test/java/com/whatsapp/api/examples/SendTemplateMarketingMessageExample.java @@ -0,0 +1,74 @@ +package com.whatsapp.api.examples; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.whatsapp.api.TestConstants; +import com.whatsapp.api.WhatsappApiFactory; +import com.whatsapp.api.domain.messages.BodyComponent; +import com.whatsapp.api.domain.messages.ButtonComponent; +import com.whatsapp.api.domain.messages.ButtonPayloadParameter; +import com.whatsapp.api.domain.messages.Currency; +import com.whatsapp.api.domain.messages.CurrencyParameter; +import com.whatsapp.api.domain.messages.DateTime; +import com.whatsapp.api.domain.messages.DateTimeParameter; +import com.whatsapp.api.domain.messages.HeaderComponent; +import com.whatsapp.api.domain.messages.Image; +import com.whatsapp.api.domain.messages.ImageParameter; +import com.whatsapp.api.domain.messages.Language; +import com.whatsapp.api.domain.messages.Message.MessageBuilder; +import com.whatsapp.api.domain.messages.TemplateMessage; +import com.whatsapp.api.domain.messages.type.ButtonSubType; +import com.whatsapp.api.domain.messages.type.CalendarType; +import com.whatsapp.api.domain.templates.type.LanguageType; +import com.whatsapp.api.impl.WhatsappBusinessCloudApi; + +import static com.whatsapp.api.TestConstants.PHONE_NUMBER_1; +import static com.whatsapp.api.TestConstants.PHONE_NUMBER_ID; + +public class SendTemplateMarketingMessageExample { + public static void main(String[] args) throws JsonProcessingException { + WhatsappApiFactory factory = WhatsappApiFactory.newInstance(TestConstants.TOKEN); + + WhatsappBusinessCloudApi whatsappBusinessCloudApi = factory.newBusinessCloudApi(); + + + var message = MessageBuilder.builder()// + .setTo(PHONE_NUMBER_1)// + .buildTemplateMessage(// + new TemplateMessage()// + .setLanguage(new Language(LanguageType.EN_US))// + .setName("marketing_music_2")// + .addComponent(new HeaderComponent()// + .addParameter(new ImageParameter()// + .setImage(new Image()// + .setId("3196424913981611")// + ) + )).addComponent(// + new BodyComponent()// + .addParameter(new DateTimeParameter()// + .setDateTime(new DateTime()// + .setCalendar(CalendarType.GREGORIAN)// + .setDayOfMonth(26)// + .setMonth(3)// + .setYear(2023)// + .setHour(10) + .setMinute(50) + .setDayOfWeek(1).setFallbackValue("May 10th, 2023")// + ))// + .addParameter(new CurrencyParameter()// + .setCurrency(new Currency("$35", "USD", 30000))))// + + .addComponent(new ButtonComponent()// + .setIndex(0)// + .setSubType(ButtonSubType.QUICK_REPLY)// + .addParameter(new ButtonPayloadParameter("OP_SHN_454584")))// + .addComponent(new ButtonComponent()// + .setIndex(1)// + .setSubType(ButtonSubType.QUICK_REPLY)// + .addParameter(new ButtonPayloadParameter("OP_SPR_454585")))// + ); + System.out.println(new ObjectMapper().writeValueAsString(message)); + + whatsappBusinessCloudApi.sendMessage(PHONE_NUMBER_ID, message); + } +} diff --git a/src/test/java/com/whatsapp/api/impl/WhatsappBusinessCloudApiTest.java b/src/test/java/com/whatsapp/api/impl/WhatsappBusinessCloudApiTest.java index ab088bd88..dd63e4528 100644 --- a/src/test/java/com/whatsapp/api/impl/WhatsappBusinessCloudApiTest.java +++ b/src/test/java/com/whatsapp/api/impl/WhatsappBusinessCloudApiTest.java @@ -6,10 +6,15 @@ import com.whatsapp.api.domain.messages.BodyComponent; import com.whatsapp.api.domain.messages.ButtonComponent; import com.whatsapp.api.domain.messages.ButtonPayloadParameter; +import com.whatsapp.api.domain.messages.Currency; +import com.whatsapp.api.domain.messages.CurrencyParameter; import com.whatsapp.api.domain.messages.DateTime; import com.whatsapp.api.domain.messages.DateTimeParameter; import com.whatsapp.api.domain.messages.DocumentMessage; +import com.whatsapp.api.domain.messages.HeaderComponent; +import com.whatsapp.api.domain.messages.Image; import com.whatsapp.api.domain.messages.ImageMessage; +import com.whatsapp.api.domain.messages.ImageParameter; import com.whatsapp.api.domain.messages.Language; import com.whatsapp.api.domain.messages.Message.MessageBuilder; import com.whatsapp.api.domain.messages.StickerMessage; @@ -238,6 +243,58 @@ void testSendTemplateButtonMessageWithDateTimeParam() throws IOException, URISyn } + @Test + void testSendTemplateButtonMessageMarketing() throws IOException, URISyntaxException, InterruptedException, JSONException { + mockWebServer.enqueue(new MockResponse().setResponseCode(200).setBody(DEFAULT_SEND_MESSAGE_RESPONSE)); + + var expectedJson = fromResource(EXPECTED_FOLDER + "expectedMessage5.json"); + + var templateMessage = new TemplateMessage()// + .setLanguage(new Language(LanguageType.EN_US))// + .setName("marketing_music_2")// + .addComponent(new HeaderComponent()// + .addParameter(new ImageParameter()// + .setImage(new Image()// + .setId("3196424913981611")// + ))).addComponent(// + new BodyComponent()// + .addParameter(new DateTimeParameter()// + .setDateTime(new DateTime()// + .setCalendar(CalendarType.GREGORIAN)// + .setDayOfMonth(26)// + .setMonth(3)// + .setYear(2023)// + .setHour(10).setMinute(50).setDayOfWeek(1).setFallbackValue("May 10th, 2023")// + ))// + .addParameter(new CurrencyParameter()// + .setCurrency(new Currency("$35", "USD", 30000))))// + + .addComponent(new ButtonComponent()// + .setIndex(0)// + .setSubType(ButtonSubType.QUICK_REPLY)// + .addParameter(new ButtonPayloadParameter("OP_SHN_454584")))// + .addComponent(new ButtonComponent()// + .setIndex(1)// + .setSubType(ButtonSubType.QUICK_REPLY)// + .addParameter(new ButtonPayloadParameter("OP_SPR_454585"))); + + + var message = MessageBuilder.builder()// + .setTo(PHONE_NUMBER_1)// + .buildTemplateMessage(templateMessage); + + whatsappBusinessCloudApi.sendMessage(PHONE_NUMBER_ID, message); + + RecordedRequest recordedRequest = mockWebServer.takeRequest(); + Assertions.assertEquals("POST", recordedRequest.getMethod()); + Assertions.assertEquals("/" + API_VERSION + "/" + PHONE_NUMBER_ID + "/messages", recordedRequest.getPath()); + //System.out.println(recordedRequest.getBody().readUtf8()); + + JSONAssert.assertEquals(expectedJson, recordedRequest.getBody().readUtf8(), JSONCompareMode.STRICT); + + } + + @Test void testSendAudioMessage() throws IOException, URISyntaxException, InterruptedException { mockWebServer.enqueue(new MockResponse().setResponseCode(200).setBody(DEFAULT_SEND_MESSAGE_RESPONSE)); diff --git a/src/test/resources/expected/message/expectedMessage5.json b/src/test/resources/expected/message/expectedMessage5.json new file mode 100644 index 000000000..c77b19201 --- /dev/null +++ b/src/test/resources/expected/message/expectedMessage5.json @@ -0,0 +1,73 @@ +{ + "messaging_product": "whatsapp", + "recipient_type": "individual", + "to": "121212121212", + "type": "template", + "template": { + "components": [ + { + "type": "header", + "parameters": [ + { + "type": "image", + "image": { + "id": "3196424913981611" + } + } + ] + }, + { + "type": "body", + "parameters": [ + { + "type": "date_time", + "date_time": { + "fallback_value": "May 10th, 2023", + "calendar": "GREGORIAN", + "month": 3, + "hour": 10, + "year": 2023, + "day_of_month": 26, + "day_of_week": 1, + "minute": 50 + } + }, + { + "type": "currency", + "currency": { + "fallback_value": "$35", + "code": "USD", + "amount_1000": 30000 + } + } + ] + }, + { + "type": "button", + "parameters": [ + { + "type": "payload", + "payload": "OP_SHN_454584" + } + ], + "index": 0, + "sub_type": "quick_reply" + }, + { + "type": "button", + "parameters": [ + { + "type": "payload", + "payload": "OP_SPR_454585" + } + ], + "index": 1, + "sub_type": "quick_reply" + } + ], + "name": "marketing_music_2", + "language": { + "code": "en_US" + } + } +} \ No newline at end of file