Skip to content

Commit

Permalink
Make forwarded fields optional on WA messages
Browse files Browse the repository at this point in the history
  • Loading branch information
hunterjackson committed Aug 7, 2024
1 parent 9dd5ed2 commit e4249c0
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ public final class WebhookMessageContext {

@JsonCreator
public WebhookMessageContext(
@JsonProperty("forwarded") boolean forwarded,
@JsonProperty("frequently_forwarded") boolean frequentlyForwarded,
@JsonProperty("forwarded") @Nullable Boolean forwarded,
@JsonProperty("frequently_forwarded") @Nullable Boolean frequentlyForwarded,
@JsonProperty("from") String from,
@JsonProperty("id") String id,
@JsonProperty("referred_product") @Nullable ReferredProduct referredProduct) {
this.forwarded = forwarded;
this.frequentlyForwarded = frequentlyForwarded;
this.forwarded = Objects.requireNonNullElse(forwarded, false);
this.frequentlyForwarded = Objects.requireNonNullElse(frequentlyForwarded, false);
this.from = Identifier.from(Objects.requireNonNull(from));
this.id = Identifier.from(Objects.requireNonNull(id));
this.referredProduct = referredProduct;
Expand Down
96 changes: 76 additions & 20 deletions src/test/java/com/meta/cp4m/message/WAMessageHandlerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
import com.google.common.base.Stopwatch;
import com.meta.cp4m.DummyWebServer.ReceivedRequest;
import com.meta.cp4m.Identifier;
import com.meta.cp4m.message.webhook.whatsapp.GetMediaIdBody;
import com.meta.cp4m.message.webhook.whatsapp.SendResponse;
import com.meta.cp4m.message.webhook.whatsapp.Utils;
import com.meta.cp4m.message.webhook.whatsapp.*;
import io.javalin.http.HandlerType;
import java.io.IOException;
import java.net.URI;
Expand All @@ -32,11 +30,57 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.NullSource;
import org.junit.jupiter.params.provider.ValueSource;

class WAMessageHandlerTest {
static String BODY_TEXT = "this is a text message!@#$%^&*()’";
static final String VALID2 =
"""
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "362118040319556",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "13137829971",
"phone_number_id": "390095987512130"
},
"contacts": [
{
"profile": {
"name": "Benjamin Broadstone"
},
"wa_id": "12027330824"
}
],
"messages": [
{
"context": {
"from": "13137829971",
"id": "wamid.HBgLMTIwMjczMzA4MjQVAgARGBJCRjg3QkEwRjZGRTY5MERBMTUA"
},
"from": "12027330824",
"id": "wamid.HBgLMTIwMjczMzA4MjQVAgASGBQzQUFFNTkxMDIzQjk5RjNFQjQ5MgA=",
"timestamp": "1723063165",
"text": {
"body": "Cool"
},
"type": "text"
}
]
},
"field": "messages"
}
]
}
]
}
""";
static final String VALID =
"""
{
Expand Down Expand Up @@ -68,11 +112,7 @@ class WAMessageHandlerTest {
"timestamp": "1504902988",
"type": "text",
"text": {
"body": """
+ "\""
+ BODY_TEXT
+ "\""
+ """
"body": \"this is a text message!@#$%^&*()’\"
}
}
]
Expand Down Expand Up @@ -164,8 +204,13 @@ void welcomeMessage(final @Nullable String welcomeMessage)
}
}

@Test
void valid() throws IOException, InterruptedException {
static Stream<String> validWAPayloads() {
return Stream.of(VALID, VALID2);
}

@ParameterizedTest
@MethodSource("validWAPayloads")
void valid(String payload) throws IOException, InterruptedException {
final String sendResponse =
"""
{
Expand All @@ -183,9 +228,13 @@ void valid() throws IOException, InterruptedException {
}
]
}""";

// make sure we can parse the payload
WebhookPayload payloadParsed = Utils.JSON_MAPPER.readValue(payload, WebhookPayload.class);

harness.dummyWebServer().response(ctx -> ctx.body().contains("\"type\""), sendResponse);
harness.start();
Response request = harness.post(VALID).execute();
Response request = harness.post(payload).execute();
assertThat(request.returnResponse().getCode()).isEqualTo(200);

Collection<ReceivedRequest> responses =
Expand All @@ -205,25 +254,32 @@ void valid() throws IOException, InterruptedException {
List<ThreadState<WAMessage>> threads = harness.chatStore().list();
assertThat(threads).hasSize(1);
ThreadState<WAMessage> thread = threads.get(0);
Value valueParsed =
payloadParsed.entry().stream().findAny().orElseThrow().changes().stream()
.findAny()
.orElseThrow()
.value();
TextWebhookMessage parsedMessage =
(TextWebhookMessage) valueParsed.messages().stream().findAny().orElseThrow();
assertThat(thread.messages())
.hasSize(2)
.anySatisfy(
m -> {
assertThat(m.message()).isEqualTo(BODY_TEXT);
assertThat(m.instanceId()).isEqualTo(Identifier.from("ABGGFlA5Fpa"));
assertThat(m.senderId()).isEqualTo(Identifier.from("16315551181"));
assertThat(m.recipientId()).isEqualTo(Identifier.from("123456123"));
assertThat(m.message()).isEqualTo(parsedMessage.text().body());
assertThat(m.instanceId()).isEqualTo(parsedMessage.id());
assertThat(m.senderId()).isEqualTo(parsedMessage.from());
assertThat(m.recipientId()).isEqualTo(valueParsed.metadata().phoneNumberId());
assertThat(m.role()).isEqualTo(Message.Role.USER);
})
.anySatisfy(
m -> {
assertThat(m.role()).isEqualTo(Message.Role.ASSISTANT);
assertThat(m.senderId()).isEqualTo(Identifier.from("123456123"));
assertThat(m.recipientId()).isEqualTo(Identifier.from("16315551181"));
assertThat(m.senderId()).isEqualTo(valueParsed.metadata().phoneNumberId());
assertThat(m.recipientId()).isEqualTo(parsedMessage.from());
});
String testUserName =
MAPPER
.readTree(VALID)
.readTree(payload)
.get("entry")
.get(0)
.get("changes")
Expand All @@ -246,7 +302,7 @@ void valid() throws IOException, InterruptedException {
.satisfies(u -> assertThat(u.phoneNumber()).get().isEqualTo("16315551181"));

// repeat and show that it is not processed again because it is a duplicate
request = harness.post(VALID).execute();
request = harness.post(payload).execute();
assertThat(request.returnResponse().getCode()).isEqualTo(200);
assertThat(harness.pollWebserver(500)).isNull();
}
Expand Down

0 comments on commit e4249c0

Please sign in to comment.