Skip to content

Commit

Permalink
Merge pull request #150 from netflie/button-reply
Browse files Browse the repository at this point in the history
Button reply
  • Loading branch information
aalbarca authored Nov 19, 2023
2 parents 4262e84 + 5b65958 commit 67e3043
Show file tree
Hide file tree
Showing 8 changed files with 296 additions and 0 deletions.
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,36 @@ $whatsapp_cloud_api->sendList(
);
```

### Send a button reply message

```php
<?php

use Netflie\WhatsAppCloudApi\WhatsAppCloudApi;
use Netflie\WhatsAppCloudApi\Message\ButtonReply\Button;
use Netflie\WhatsAppCloudApi\Message\ButtonReply\ButtonAction;

$whatsapp_cloud_api = new WhatsAppCloudApi([
'from_phone_number_id' => 'your-configured-from-phone-number-id',
'access_token' => 'your-facebook-whatsapp-application-token'
]);

$rows = [
new Button('button-1', 'Yes'),
new Button('button-2', 'No'),
new Button('button-3', 'Not Now'),
];
$action = new ButtonAction($rows);

$whatsapp_cloud_api->sendButton(
'<destination-phone-number>',
'Would you like to rate us on Trustpilot?',
$action,
'RATE US', // Optional: Specify a header (type "text")
'Please choose an option' // Optional: Specify a footer
);
```

## 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.
Expand Down Expand Up @@ -345,6 +375,7 @@ Fields list: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/b
- Send Locations
- Send Contacts
- Send Lists
- Send Buttons
- Upload media resources to WhatsApp servers
- Download media resources from WhatsApp servers
- Mark messages as read
Expand Down
25 changes: 25 additions & 0 deletions src/Message/ButtonReply/Button.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Netflie\WhatsAppCloudApi\Message\ButtonReply;

class Button
{
private $id;
private $title;

public function __construct(string $id, string $title)
{
$this->id = $id;
$this->title = $title;
}

public function id(): string
{
return $this->id;
}

public function title(): string
{
return $this->title;
}
}
30 changes: 30 additions & 0 deletions src/Message/ButtonReply/ButtonAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Netflie\WhatsAppCloudApi\Message\ButtonReply;

class ButtonAction
{
private $buttons;

public function __construct(array $buttons)
{
$this->buttons = $buttons;
}

public function buttons(): array
{
$buttonActions = [];

foreach ($this->buttons as $button) {
$buttonActions[] = [
"type" => "reply",
"reply" => [
"id" => $button->id(),
"title" => $button->title(),
],
];
}

return $buttonActions;
}
}
48 changes: 48 additions & 0 deletions src/Message/ButtonReplyMessage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace Netflie\WhatsAppCloudApi\Message;

use Netflie\WhatsAppCloudApi\Message\ButtonReply\ButtonAction;

class ButtonReplyMessage extends Message
{
protected string $type = 'button';

private ?string $header;

private string $body;

private ?string $footer;

private ButtonAction $action;

public function __construct(string $to, string $body, ButtonAction $action, ?string $header = null, ?string $footer = null, ?string $reply_to = null)
{
$this->body = $body;
$this->action = $action;
$this->header = $header;
$this->footer = $footer;

parent::__construct($to, $reply_to);
}

public function header(): ?string
{
return $this->header;
}

public function body(): string
{
return $this->body;
}

public function action(): ButtonAction
{
return $this->action;
}

public function footer(): ?string
{
return $this->footer;
}
}
42 changes: 42 additions & 0 deletions src/Request/MessageRequest/RequestButtonReplyMessage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace Netflie\WhatsAppCloudApi\Request\MessageRequest;

use Netflie\WhatsAppCloudApi\Request\MessageRequest;

class RequestButtonReplyMessage extends MessageRequest
{
public function body(): array
{
$body = [
'messaging_product' => $this->message->messagingProduct(),
'recipient_type' => $this->message->recipientType(),
'to' => $this->message->to(),
'type' => 'interactive',
'interactive' => [
'type' => 'button',
'body' => ['text' => $this->message->body()],
'action' => ['buttons' => $this->message->action()->buttons()],
],
];

if ($this->message->header()) {
$body['interactive']['header'] = [
'type' => 'text',
'text' => $this->message->header(),
];
}

if ($this->message->footer()) {
$body['interactive']['footer'] = [
'text' => $this->message->footer(),
];
}

if ($this->message->replyTo()) {
$body['context']['message_id'] = $this->message->replyTo();
}

return $body;
}
}
22 changes: 22 additions & 0 deletions src/WhatsAppCloudApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Netflie\WhatsAppCloudApi;

use Netflie\WhatsAppCloudApi\Message\ButtonReply\ButtonAction;
use Netflie\WhatsAppCloudApi\Message\Contact\ContactName;
use Netflie\WhatsAppCloudApi\Message\Contact\Phone;
use Netflie\WhatsAppCloudApi\Message\Media\MediaID;
Expand Down Expand Up @@ -288,6 +289,27 @@ public function sendList(string $to, string $header, string $body, string $foote
return $this->client->sendMessage($request);
}

public function sendButton(string $to, string $body, ButtonAction $action, ?string $header = null, ?string $footer = null): Response
{
$message = new Message\ButtonReplyMessage(
$to,
$body,
$action,
$header,
$footer,
$this->reply_to
);

$request = new Request\MessageRequest\RequestButtonReplyMessage(
$message,
$this->app->accessToken(),
$this->app->fromPhoneNumberId(),
$this->timeout
);

return $this->client->sendMessage($request);
}

/**
* Upload a media file (image, audio, video...) to Facebook servers.
*
Expand Down
25 changes: 25 additions & 0 deletions tests/Integration/WhatsAppCloudApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Netflie\WhatsAppCloudApi\Tests\Integration;

use Netflie\WhatsAppCloudApi\Message\ButtonReply\Button;
use Netflie\WhatsAppCloudApi\Message\ButtonReply\ButtonAction;
use Netflie\WhatsAppCloudApi\Message\Contact\ContactName;
use Netflie\WhatsAppCloudApi\Message\Contact\Phone;
use Netflie\WhatsAppCloudApi\Message\Contact\PhoneType;
Expand Down Expand Up @@ -258,6 +260,29 @@ public function test_send_list()
$this->assertEquals(false, $response->isError());
}

public function test_send_reply_buttons()
{
$buttonRows = [
new Button('button-1', 'Yes'),
new Button('button-2', 'No'),
new Button('button-3', 'Not Now'),
];
$buttonAction = new ButtonAction($buttonRows);
$header = 'RATE US';
$footer = 'Please choose an option';

$response = $this->whatsapp_app_cloud_api->sendButton(
WhatsAppCloudApiTestConfiguration::$to_phone_number_id,
'Would you like to rate us?',
$buttonAction,
$header,
$footer
);

$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');
Expand Down
73 changes: 73 additions & 0 deletions tests/Unit/WhatsAppCloudApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
use Netflie\WhatsAppCloudApi\Client;
use Netflie\WhatsAppCloudApi\Http\ClientHandler;
use Netflie\WhatsAppCloudApi\Http\RawResponse;
use Netflie\WhatsAppCloudApi\Message\ButtonReply\Button;
use Netflie\WhatsAppCloudApi\Message\ButtonReply\ButtonAction;
use Netflie\WhatsAppCloudApi\Message\Contact\ContactName;
use Netflie\WhatsAppCloudApi\Message\Contact\Phone;
use Netflie\WhatsAppCloudApi\Message\Contact\PhoneType;
Expand Down Expand Up @@ -897,6 +899,77 @@ public function test_send_list()
$this->assertEquals(false, $response->isError());
}

public function test_send_reply_buttons()
{
$to = $this->faker->phoneNumber;
$url = $this->buildMessageRequestUri();
$reply_to = $this->faker->uuid;

$buttonRows = [
['id' => $this->faker->uuid, 'title' => $this->faker->text(10)],
['id' => $this->faker->uuid, 'title' => $this->faker->text(10)],
['id' => $this->faker->uuid, 'title' => $this->faker->text(10)],
];
$buttonAction = ['buttons' => []];

foreach ($buttonRows as $button) {
$buttonAction['buttons'][] = [
'type' => 'reply',
'reply' => $button,
];
}

$message = $this->faker->text(50);
$header = $this->faker->text(50);
$footer = $this->faker->text(50);

$body = [
'messaging_product' => 'whatsapp',
'recipient_type' => 'individual',
'to' => $to,
'type' => 'interactive',
'interactive' => [
'type' => 'button',
'body' => ['text' => $message],
'action' => $buttonAction,
'header' => ['type' => 'text', 'text' => $header],
'footer' => ['text' => $footer],
],
'context' => [
'message_id' => $reply_to,
],
];
$headers = [
'Authorization' => 'Bearer ' . $this->access_token,
];

$this->client_handler
->postJsonData($url, $body, $headers, Argument::type('int'))
->shouldBeCalled()
->willReturn(new RawResponse($headers, $this->successfulMessageNodeResponse(), 200));

$actionButtons = [];

foreach ($buttonRows as $button) {
$actionButtons[] = new Button($button['id'], $button['title']);
}

$response = $this->whatsapp_app_cloud_api
->replyTo($reply_to)
->sendButton(
$to,
$message,
new ButtonAction($actionButtons),
$header,
$footer
);

$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_upload_media()
{
$url = $this->buildMediaRequestUri();
Expand Down

0 comments on commit 67e3043

Please sign in to comment.