diff --git a/src/main/java/com/meta/cp4m/message/WAMessageHandler.java b/src/main/java/com/meta/cp4m/message/WAMessageHandler.java index db42b3f..71d735a 100644 --- a/src/main/java/com/meta/cp4m/message/WAMessageHandler.java +++ b/src/main/java/com/meta/cp4m/message/WAMessageHandler.java @@ -21,6 +21,7 @@ import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.stream.Stream; import org.apache.hc.client5.http.fluent.Request; import org.apache.hc.core5.http.ContentType; import org.apache.hc.core5.http.io.entity.EntityUtils; @@ -71,7 +72,17 @@ private List> post(Context ctx, WebhookPayload payload) { .flatMap(e -> e.changes().stream()) .forEachOrdered( change -> { + Stream.concat( + change.value().statuses().stream().flatMap(s -> s.errors().stream()), + change.value().errors().stream()) + .forEach( + e -> + LOGGER + .atError() + .addKeyValue("body", ctx.body()) + .log("Whatsapp Error: " + e)); Identifier phoneNumberId = change.value().metadata().phoneNumberId(); + for (WebhookMessage message : change.value().messages()) { if (messageDeduplicator.addAndGetIsDuplicate(message.id())) { continue; // message is a duplicate diff --git a/src/main/java/com/meta/cp4m/message/webhook/whatsapp/Status.java b/src/main/java/com/meta/cp4m/message/webhook/whatsapp/Status.java index 8767ed6..6225774 100644 --- a/src/main/java/com/meta/cp4m/message/webhook/whatsapp/Status.java +++ b/src/main/java/com/meta/cp4m/message/webhook/whatsapp/Status.java @@ -79,7 +79,8 @@ public enum StatusType { DELIVERED, READ, SENT, - FAILED; + FAILED, + WARNING; public String toString() { return this.name().toLowerCase(); diff --git a/src/test/java/com/meta/cp4m/message/WAMessageHandlerTest.java b/src/test/java/com/meta/cp4m/message/WAMessageHandlerTest.java index a5f925c..23c52c5 100644 --- a/src/test/java/com/meta/cp4m/message/WAMessageHandlerTest.java +++ b/src/test/java/com/meta/cp4m/message/WAMessageHandlerTest.java @@ -123,7 +123,49 @@ class WAMessageHandlerTest { ] } """; - static final String NO_MESSAGES = + static final String VALID_WITH_ERROR = + """ +{ + "object": "whatsapp_business_account", + "entry": [ + { + "id": "355432333211112", + "changes": [ + { + "value": { + "messaging_product": "whatsapp", + "metadata": { + "display_phone_number": "15555559999", + "phone_number_id": "15555559999" + }, + "statuses": [ + { + "id": "wamid.lBgLMTI0ODk5MagXZMzgVAgARGDIwQ0FDRENCODA3RjczNUYxNzQA", + "status": "failed", + "timestamp": "1222493493", + "recipient_id": "15555558888", + "errors": [ + { + "code": 131047, + "title": "Re-engagement message", + "message": "Re-engagement message", + "error_data": { + "details": "Message failed to send because more than 24 hours have passed since the customer last replied to this number." + }, + "href": "https://developers.facebook.com/docs/whatsapp/cloud-api/support/error-codes/" + } + ] + } + ] + }, + "field": "messages" + } + ] + } + ] +} +"""; + static final String VALID_NO_MESSAGES = """ { "object": "whatsapp_business_account", @@ -368,10 +410,15 @@ void doesNotSendNonTextMessages() throws IOException, InterruptedException { .isEqualTo("read"); } - @Test - void noMessages() throws IOException, InterruptedException { + static Stream validPayloadsWithNoResponse() { + return Stream.of(VALID_WITH_ERROR, VALID_NO_MESSAGES); + } + + @ParameterizedTest + @MethodSource("validPayloadsWithNoResponse") + void noMessages(String payload) throws IOException, InterruptedException { harness.start(); - Response request = harness.post(NO_MESSAGES).execute(); + Response request = harness.post(payload).execute(); assertThat(request.returnResponse().getCode()).isEqualTo(200); assertThat(harness.pollWebserver(250)).isNull(); assertThat(harness.chatStore().list()).hasSize(0);