From 0424115844bab0b727ec5b0bc0e50c90b90d0fea Mon Sep 17 00:00:00 2001 From: derrickobedgiu1 Date: Tue, 23 Apr 2024 16:30:50 +0300 Subject: [PATCH 1/2] Add react to message --- README.md | 22 ++++++ src/Message/ReactionMessage.php | 36 +++++++++ .../MessageRequest/RequestReactionMessage.php | 27 +++++++ src/WhatsAppCloudApi.php | 24 ++++++ tests/Integration/WhatsAppCloudApiTest.php | 31 ++++++++ tests/Unit/WhatsAppCloudApiTest.php | 75 +++++++++++++++++++ 6 files changed, 215 insertions(+) create mode 100644 src/Message/ReactionMessage.php create mode 100644 src/Request/MessageRequest/RequestReactionMessage.php diff --git a/README.md b/README.md index 9617a5b..7fd60a6 100644 --- a/README.md +++ b/README.md @@ -286,6 +286,27 @@ $whatsapp_cloud_api ); ``` +### React to a Message + +You can react to a message from your conversations if you know the messageid + +```php +sendReaction( + '', + '', + '👍', // the emoji + ); + +// Unreact to a message +$whatsapp_cloud_api->sendReaction( + '', + '' + ); + +``` + ## Media messages ### Upload media resources Media messages accept as identifiers an Internet URL pointing to a public resource (image, video, audio, etc.). When you try to send a media message from a URL you must instantiate the `LinkID` object. @@ -413,6 +434,7 @@ Fields list: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/b - Upload media resources to WhatsApp servers - Download media resources from WhatsApp servers - Mark messages as read +- React to a Message - Get/Update Business Profile - Webhook verification - Webhook notifications diff --git a/src/Message/ReactionMessage.php b/src/Message/ReactionMessage.php new file mode 100644 index 0000000..46e3e21 --- /dev/null +++ b/src/Message/ReactionMessage.php @@ -0,0 +1,36 @@ +emoji = $emoji; + $this->message_id = $message_id; + + parent::__construct($to, null); + } + + public function emoji(): string + { + return $this->emoji; + } + + public function message_id(): string + { + return $this->message_id; + } +} diff --git a/src/Request/MessageRequest/RequestReactionMessage.php b/src/Request/MessageRequest/RequestReactionMessage.php new file mode 100644 index 0000000..9bea82c --- /dev/null +++ b/src/Request/MessageRequest/RequestReactionMessage.php @@ -0,0 +1,27 @@ + $this->message->messagingProduct(), + 'recipient_type' => $this->message->recipientType(), + 'to' => $this->message->to(), + 'type' => $this->message->type(), + $this->message->type() => [ + 'message_id' => $this->message->message_id(), + 'emoji' => $this->message->emoji(), + ], + ]; + + return $body; + } +} diff --git a/src/WhatsAppCloudApi.php b/src/WhatsAppCloudApi.php index d9eed05..0a30f38 100644 --- a/src/WhatsAppCloudApi.php +++ b/src/WhatsAppCloudApi.php @@ -413,6 +413,30 @@ public function markMessageAsRead(string $message_id): Response return $this->client->sendMessage($request); } + /** + * Sends a reaction to a provided message id. + * + * @param string $to WhatsApp ID or phone number for the person you want to send a message to. + * @param string $message_id The ID of the message to react to. + * @param string $emoji The emoji to use as a reaction. + * @return Response + * + * @throws Response\ResponseException + */ + public function sendReaction(string $to, string $message_id, string $emoji = ''): Response + { + $message = new Message\ReactionMessage($to, $message_id, $emoji); + + $request = new Request\MessageRequest\RequestReactionMessage( + $message, + $this->app->accessToken(), + $this->app->fromPhoneNumberId(), + $this->timeout + ); + + return $this->client->sendMessage($request); + } + /** * Get Business Profile * diff --git a/tests/Integration/WhatsAppCloudApiTest.php b/tests/Integration/WhatsAppCloudApiTest.php index e4c89cd..30695b1 100644 --- a/tests/Integration/WhatsAppCloudApiTest.php +++ b/tests/Integration/WhatsAppCloudApiTest.php @@ -301,6 +301,37 @@ public function test_send_reply_buttons() $this->assertEquals(false, $response->isError()); } + public function test_send_reaction_message() + { + $this->markTestIncomplete( + 'This test should use a real message ID.' + ); + + $response = $this->whatsapp_app_cloud_api->sendReaction( + WhatsAppCloudApiTestConfiguration::$to_phone_number_id, + 'wamid.HBgMMjU2NzQyMDMwNDAzFQIAERgSMEU2MkE3Q0I3RTEyRDU5NzIwAA==', + '👍' + ); + + $this->assertEquals(200, $response->httpStatusCode()); + $this->assertEquals(false, $response->isError()); + } + + public function test_send_remove_reaction_message() + { + $this->markTestIncomplete( + 'This test should use a real message ID.' + ); + + $response = $this->whatsapp_app_cloud_api->sendReaction( + WhatsAppCloudApiTestConfiguration::$to_phone_number_id, + 'wamid.HBgMMjU2NzQyMDMwNDAzFQIAERgSMEU2MkE3Q0I3RTEyRDU5NzIwAA==' + ); + + $this->assertEquals(200, $response->httpStatusCode()); + $this->assertEquals(false, $response->isError()); + } + public function test_upload_media() { $response = $this->whatsapp_app_cloud_api->uploadMedia('tests/Support/netflie.png'); diff --git a/tests/Unit/WhatsAppCloudApiTest.php b/tests/Unit/WhatsAppCloudApiTest.php index b391dbb..64e9d87 100644 --- a/tests/Unit/WhatsAppCloudApiTest.php +++ b/tests/Unit/WhatsAppCloudApiTest.php @@ -1170,6 +1170,81 @@ public function test_mark_a_message_as_read() $this->assertEquals(false, $response->isError()); } + public function test_send_reaction_message() + { + $to = $this->faker->phoneNumber; + $url = $this->buildMessageRequestUri(); + $emoji = $this->faker->emoji; + $message_id = $this->faker->uuid; + + $body = [ + 'messaging_product' => 'whatsapp', + 'recipient_type' => 'individual', + 'to' => $to, + 'type' => 'reaction', + 'reaction' => [ + 'message_id' => $message_id, + 'emoji' => $emoji, + ], + ]; + $headers = [ + 'Authorization' => 'Bearer ' . $this->access_token, + ]; + + $this->client_handler + ->postJsonData($url, $body, $headers, Argument::type('int')) + ->shouldBeCalled() + ->willReturn(new RawResponse($headers, $this->successfulMessageNodeResponse(), 200)); + + $response = $this->whatsapp_app_cloud_api->sendReaction( + $to, + $message_id, + $emoji + ); + + $this->assertEquals(200, $response->httpStatusCode()); + $this->assertEquals(json_decode($this->successfulMessageNodeResponse(), true), $response->decodedBody()); + $this->assertEquals($this->successfulMessageNodeResponse(), $response->body()); + $this->assertEquals(false, $response->isError()); + } + + public function test_send_remove_reaction_message() + { + $to = $this->faker->phoneNumber; + $url = $this->buildMessageRequestUri(); + $emoji = ''; + $message_id = $this->faker->uuid; + + $body = [ + 'messaging_product' => 'whatsapp', + 'recipient_type' => 'individual', + 'to' => $to, + 'type' => 'reaction', + 'reaction' => [ + 'message_id' => $message_id, + 'emoji' => $emoji, + ], + ]; + $headers = [ + 'Authorization' => 'Bearer ' . $this->access_token, + ]; + + $this->client_handler + ->postJsonData($url, $body, $headers, Argument::type('int')) + ->shouldBeCalled() + ->willReturn(new RawResponse($headers, $this->successfulMessageNodeResponse(), 200)); + + $response = $this->whatsapp_app_cloud_api->sendReaction( + $to, + $message_id + ); + + $this->assertEquals(200, $response->httpStatusCode()); + $this->assertEquals(json_decode($this->successfulMessageNodeResponse(), true), $response->decodedBody()); + $this->assertEquals($this->successfulMessageNodeResponse(), $response->body()); + $this->assertEquals(false, $response->isError()); + } + private function buildBaseUri(): string { return Client::BASE_GRAPH_URL . '/' . static::TEST_GRAPH_VERSION . '/'; From 25622bff429d293f677ece2bc81c39e3586b3798 Mon Sep 17 00:00:00 2001 From: derrickobedgiu1 Date: Wed, 3 Jul 2024 11:00:24 +0300 Subject: [PATCH 2/2] patch tests --- tests/Integration/WhatsAppCloudApiTest.php | 28 +++++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/tests/Integration/WhatsAppCloudApiTest.php b/tests/Integration/WhatsAppCloudApiTest.php index 30695b1..147c746 100644 --- a/tests/Integration/WhatsAppCloudApiTest.php +++ b/tests/Integration/WhatsAppCloudApiTest.php @@ -303,13 +303,17 @@ public function test_send_reply_buttons() public function test_send_reaction_message() { - $this->markTestIncomplete( - 'This test should use a real message ID.' + $textMessage = $this->whatsapp_app_cloud_api->sendTextMessage( + WhatsAppCloudApiTestConfiguration::$to_phone_number_id, + 'This text will receive a reaction', + true ); + $messageId = $textMessage->decodedBody()['messages'][0]['id']; + $response = $this->whatsapp_app_cloud_api->sendReaction( WhatsAppCloudApiTestConfiguration::$to_phone_number_id, - 'wamid.HBgMMjU2NzQyMDMwNDAzFQIAERgSMEU2MkE3Q0I3RTEyRDU5NzIwAA==', + $messageId, '👍' ); @@ -319,13 +323,25 @@ public function test_send_reaction_message() public function test_send_remove_reaction_message() { - $this->markTestIncomplete( - 'This test should use a real message ID.' + $textMessage = $this->whatsapp_app_cloud_api->sendTextMessage( + WhatsAppCloudApiTestConfiguration::$to_phone_number_id, + 'This text will receive a reaction and then the reaction will be removed', + true ); + $messageId = $textMessage->decodedBody()['messages'][0]['id']; + + $reactToMessage = $this->whatsapp_app_cloud_api->sendReaction( + WhatsAppCloudApiTestConfiguration::$to_phone_number_id, + $messageId, + '👍' + ); + + // sleep(3); // can delay next request to see reaction + $response = $this->whatsapp_app_cloud_api->sendReaction( WhatsAppCloudApiTestConfiguration::$to_phone_number_id, - 'wamid.HBgMMjU2NzQyMDMwNDAzFQIAERgSMEU2MkE3Q0I3RTEyRDU5NzIwAA==' + $messageId ); $this->assertEquals(200, $response->httpStatusCode());