From 760472bb8ebdf40e3e69d5593c0e8c17146b5557 Mon Sep 17 00:00:00 2001 From: Norbert Bartels Date: Fri, 12 Nov 2021 23:53:54 +0100 Subject: [PATCH] Issue #1182 - Product template added to messaging webhook object --- .../messaging/MessagingAttachment.java | 14 +++++ .../webhook/messaging/MessagingPayload.java | 5 ++ .../types/webhook/messaging/ProductItem.java | 57 +++++++++++++++++++ .../messaging/ProductTemplateItem.java | 40 +++++++++++++ .../restfb/types/WebhookMessagingTest.java | 46 ++++++++++++++- .../messaging-message-product-template-2.json | 42 ++++++++++++++ .../messaging-message-product-template.json | 41 +++++++++++++ 7 files changed, 243 insertions(+), 2 deletions(-) create mode 100644 src/main/lombok/com/restfb/types/webhook/messaging/ProductItem.java create mode 100644 src/main/lombok/com/restfb/types/webhook/messaging/ProductTemplateItem.java create mode 100644 src/test/resources/json/webhooks/messaging-message-product-template-2.json create mode 100644 src/test/resources/json/webhooks/messaging-message-product-template.json diff --git a/src/main/lombok/com/restfb/types/webhook/messaging/MessagingAttachment.java b/src/main/lombok/com/restfb/types/webhook/messaging/MessagingAttachment.java index 6bb77a8d6..9e895d3b1 100644 --- a/src/main/lombok/com/restfb/types/webhook/messaging/MessagingAttachment.java +++ b/src/main/lombok/com/restfb/types/webhook/messaging/MessagingAttachment.java @@ -61,6 +61,11 @@ public class MessagingAttachment { */ public static final String VIDEO = "video"; + /** + * The "template" attachment type. + */ + public static final String TEMPLATE = "template"; + @Getter @Setter @Facebook @@ -145,4 +150,13 @@ public boolean isLocation() { public boolean isVideo() { return VIDEO.equals(type); } + + /** + * convenience method to check if the attachment type is template + * + * @return {@code true} if template, {@code false} if not template + */ + public boolean isTemplate() { + return TEMPLATE.equals(type); + } } diff --git a/src/main/lombok/com/restfb/types/webhook/messaging/MessagingPayload.java b/src/main/lombok/com/restfb/types/webhook/messaging/MessagingPayload.java index e8730a5af..b1a36044d 100644 --- a/src/main/lombok/com/restfb/types/webhook/messaging/MessagingPayload.java +++ b/src/main/lombok/com/restfb/types/webhook/messaging/MessagingPayload.java @@ -183,6 +183,11 @@ public class MessagingPayload { @Facebook("boarding_pass") private List boardingPassItems; + @Getter + @Setter + @Facebook + private ProductTemplateItem product; + @Getter @Setter private String fallback; diff --git a/src/main/lombok/com/restfb/types/webhook/messaging/ProductItem.java b/src/main/lombok/com/restfb/types/webhook/messaging/ProductItem.java new file mode 100644 index 000000000..a56b6c386 --- /dev/null +++ b/src/main/lombok/com/restfb/types/webhook/messaging/ProductItem.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2010-2021 Mark Allen, Norbert Bartels. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.restfb.types.webhook.messaging; + +import com.restfb.Facebook; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@ToString +public class ProductItem { + + @Getter + @Setter + @Facebook + private String id; + + @Getter + @Setter + @Facebook("retailer_id") + private String retailerId; + + @Getter + @Setter + @Facebook("image_url") + private String imageUrl; + + @Getter + @Setter + @Facebook + private String title; + + @Getter + @Setter + @Facebook + private String subtitle; +} \ No newline at end of file diff --git a/src/main/lombok/com/restfb/types/webhook/messaging/ProductTemplateItem.java b/src/main/lombok/com/restfb/types/webhook/messaging/ProductTemplateItem.java new file mode 100644 index 000000000..50e7a58e6 --- /dev/null +++ b/src/main/lombok/com/restfb/types/webhook/messaging/ProductTemplateItem.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2010-2021 Mark Allen, Norbert Bartels. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.restfb.types.webhook.messaging; + +import java.util.ArrayList; +import java.util.List; + +import com.restfb.Facebook; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@ToString +public class ProductTemplateItem { + + @Getter + @Setter + @Facebook + private List elements = new ArrayList<>(); +} diff --git a/src/test/java/com/restfb/types/WebhookMessagingTest.java b/src/test/java/com/restfb/types/WebhookMessagingTest.java index 47022c2e4..e3868dab1 100644 --- a/src/test/java/com/restfb/types/WebhookMessagingTest.java +++ b/src/test/java/com/restfb/types/WebhookMessagingTest.java @@ -67,8 +67,10 @@ public void delivery(DeliveryItem delivery, MessagingParticipant recipient, Mess assertEquals("1458668856253", delivery.getWatermark()); foundDeprecated.set(true); } + @Override - public void delivery(DeliveryItem delivery, MessagingParticipant recipient, MessagingParticipant sender, Date timestamp) { + public void delivery(DeliveryItem delivery, MessagingParticipant recipient, MessagingParticipant sender, + Date timestamp) { assertNotNull(delivery); assertEquals("1458668856253", delivery.getWatermark()); found.set(true); @@ -571,7 +573,7 @@ void messagingPostbackWithReferral() { @Test void messagingPostbackFromChat() { WebhookObject webhookObject = - createJsonMapper().toJavaObject(jsonFromClasspath("webhooks/messaging-postback-chat"), WebhookObject.class); + createJsonMapper().toJavaObject(jsonFromClasspath("webhooks/messaging-postback-chat"), WebhookObject.class); assertThat(webhookObject).isNotNull(); assertThat(webhookObject.getEntryList()).isNotEmpty(); WebhookEntry entry = webhookObject.getEntryList().get(0); @@ -786,4 +788,44 @@ public void requestThreadControl(RequestThreadControlItem requestThreadControl, webhookListener.process(webhookObject); assertTrue(found.get()); } + + @Test + void productTemplate() { + WebhookObject webhookObject = createJsonMapper() + .toJavaObject(jsonFromClasspath("webhooks/messaging-message-product-template"), WebhookObject.class); + assertNotNull(webhookObject); + ProductItem productItem = extractProductItem(webhookObject); + assertThat(productItem.getId()).isEqualTo(""); + assertThat(productItem.getImageUrl()).endsWith("sdsd"); + assertThat(productItem.getTitle()).isEqualTo("Some product title"); + assertThat(productItem.getRetailerId()).isEqualTo(""); + assertThat(productItem.getSubtitle()).isEqualTo("$40"); + } + + @Test + void productTemplateLive() { + WebhookObject webhookObject = createJsonMapper() + .toJavaObject(jsonFromClasspath("webhooks/messaging-message-product-template-2"), WebhookObject.class); + assertNotNull(webhookObject); + ProductItem productItem = extractProductItem(webhookObject); + assertThat(productItem.getId()).isEqualTo("12345678910"); + assertThat(productItem.getImageUrl()).contains("andSoOn.png"); + assertThat(productItem.getTitle()).isEqualTo("product name"); + assertThat(productItem.getRetailerId()).isEqualTo("123456"); + assertThat(productItem.getSubtitle()).isEqualTo("product price as a string"); + } + + private ProductItem extractProductItem(WebhookObject webhookObject) { + MessagingItem item = webhookObject.getEntryList().get(0).getMessaging().get(0); + assertNotNull(item); + assertTrue(item.getMessage().hasAttachment()); + MessagingAttachment messagingAttachment = item.getMessage().getAttachments().get(0); + assertNotNull(messagingAttachment); + assertTrue(messagingAttachment.isTemplate()); + final ProductTemplateItem product = messagingAttachment.getPayload().getProduct(); + assertFalse(product.getElements().isEmpty()); + ProductItem productItem = product.getElements().get(0); + assertNotNull(productItem); + return productItem; + } } diff --git a/src/test/resources/json/webhooks/messaging-message-product-template-2.json b/src/test/resources/json/webhooks/messaging-message-product-template-2.json new file mode 100644 index 000000000..eb604fa9f --- /dev/null +++ b/src/test/resources/json/webhooks/messaging-message-product-template-2.json @@ -0,0 +1,42 @@ +{ + "object": "page", + "entry": [ + { + "id": "page id", + "time": 1636729432317, + "messaging": [ + { + "sender": { + "id": "send id" + }, + "recipient": { + "id": "page id" + }, + "timestamp": 1636729431949, + "message": { + "mid": "m_id", + "text": "text sent along with the product", + "attachments": [ + { + "type": "template", + "payload": { + "product": { + "elements": [ + { + "id": "12345678910", + "retailer_id": "123456", + "image_url": "https://scontent.xx.fbcdn.net/v/andSoOn.png", + "title": "product name", + "subtitle": "product price as a string" + } + ] + } + } + } + ] + } + } + ] + } + ] +} \ No newline at end of file diff --git a/src/test/resources/json/webhooks/messaging-message-product-template.json b/src/test/resources/json/webhooks/messaging-message-product-template.json new file mode 100644 index 000000000..6a4a7154d --- /dev/null +++ b/src/test/resources/json/webhooks/messaging-message-product-template.json @@ -0,0 +1,41 @@ +{ + "object": "page", + "entry": [ + { + "id": "682498302938465", + "time": 1518479195594, + "messaging": [ + { + "sender": { + "id": "" + }, + "recipient": { + "id": "" + }, + "timestamp": 1518479195308, + "message": { + "mid": "mid.$cAAJdkrCd2ORnva8ErFhjGm0X_Q_c", + "attachments": [ + { + "type": "template", + "payload": { + "product": { + "elements": [ + { + "id": "", + "retailer_id": "", + "image_url": "https://fb.cdn.com/sdsd", + "title": "Some product title", + "subtitle": "$40" + } + ] + } + } + } + ] + } + } + ] + } + ] +} \ No newline at end of file