Skip to content

Commit

Permalink
Merge pull request #208 from netflie/multi-product-message
Browse files Browse the repository at this point in the history
Add Multi Products
  • Loading branch information
aalbarca authored Aug 28, 2024
2 parents 8e98f7a + 906d0cd commit 3c3aea9
Show file tree
Hide file tree
Showing 9 changed files with 379 additions and 0 deletions.
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,49 @@ $whatsapp_cloud_api->sendButton(
);
```

### Send Multi Product Message
```php
<?php

use Netflie\WhatsAppCloudApi\WhatsAppCloudApi;
use Netflie\WhatsAppCloudApi\Message\MultiProduct\Row;
use Netflie\WhatsAppCloudApi\Message\MultiProduct\Section;
use Netflie\WhatsAppCloudApi\Message\MultiProduct\Action;

$rows_section_1 = [
new Row('<product-sku-id>'),
new Row('<product-sku-id>'),
// etc
];

$rows_section_2 = [
new Row('<product-sku-id>'),
new Row('<product-sku-id>'),
new Row('<product-sku-id>'),
// etc
];

$sections = [
new Section('Section 1', $rows_section_1),
new Section('Section 2', $rows_section_2),
];

$action = new Action($sections);
$catalog_id = '<catalog-id>';
$header = 'Grocery Collections';
$body = 'Hello! Thanks for your interest. Here\'s what we can offer you under our grocery collection. Thank you for shopping with us.';
$footer = 'Subject to T&C';

$whatsapp_cloud_api->sendMultiProduct(
'<destination-phone-number>',
$catalog_id,
$action,
$header,
$body,
$footer // optional
);
```

### Replying messages

You can reply a previous sent message:
Expand Down Expand Up @@ -458,6 +501,7 @@ Fields list: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/b
- Send Contacts
- Send Lists
- Send Buttons
- Send Multi Product Message
- Upload media resources to WhatsApp servers
- Download media resources from WhatsApp servers
- Mark messages as read
Expand Down
27 changes: 27 additions & 0 deletions src/Message/MultiProduct/Action.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Netflie\WhatsAppCloudApi\Message\MultiProduct;

final class Action
{
protected array $sections;

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

public function sections(): array
{
$result = [];

foreach ($this->sections as $section) {
$result[] = [
'title' => $section->title(),
'product_items' => $section->rows(),
];
}

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

namespace Netflie\WhatsAppCloudApi\Message\MultiProduct;

final class Row
{
protected string $product_retailer_id;

public function __construct(string $product_retailer_id)
{
$this->product_retailer_id = $product_retailer_id;
}

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

namespace Netflie\WhatsAppCloudApi\Message\MultiProduct;

final class Section
{
protected string $title;

protected array $rows;

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

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

public function rows(): array
{
$result = [];

foreach ($this->rows as $row) {
$result[] = [
'product_retailer_id' => $row->product_retailer_id(),
];
}

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

namespace Netflie\WhatsAppCloudApi\Message;

use Netflie\WhatsAppCloudApi\Message\MultiProduct\Action;

final class MultiProductMessage extends Message
{
/**
* {@inheritdoc}
*/
protected string $type = 'product_list';

private string $header;

private string $body;

private int $catalog_id;

private ?string $footer;

private Action $action;

/**
* {@inheritdoc}
*/
public function __construct(string $to, int $catalog_id, Action $action, string $header, string $body, ?string $footer, ?string $reply_to)
{
$this->header = $header;
$this->body = $body;
$this->catalog_id = $catalog_id;
$this->footer = $footer;
$this->action = $action;

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

public function header(): array
{
return [
'type' => 'text',
'text' => $this->header,
];
}

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

public function catalog_id(): int
{
return $this->catalog_id;
}

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

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

namespace Netflie\WhatsAppCloudApi\Request\MessageRequest;

use Netflie\WhatsAppCloudApi\Request\MessageRequest;

final class RequestMultiProductMessage extends MessageRequest
{
/**
* {@inheritdoc}
*/
public function body(): array
{
$body = [
'messaging_product' => $this->message->messagingProduct(),
'recipient_type' => $this->message->recipientType(),
'to' => $this->message->to(),
'type' => 'interactive',
'interactive' => [
'type' => $this->message->type(),
'header' => $this->message->header(),
'body' => ['text' => $this->message->body()],
'action' => [
'catalog_id' => $this->message->catalog_id(),
'sections' => $this->message->sections(),
],
],
];

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

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

return $body;
}
}
28 changes: 28 additions & 0 deletions src/WhatsAppCloudApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Netflie\WhatsAppCloudApi\Message\Contact\Phone;
use Netflie\WhatsAppCloudApi\Message\CtaUrl\Header;
use Netflie\WhatsAppCloudApi\Message\Media\MediaID;
use Netflie\WhatsAppCloudApi\Message\MultiProduct\Action as MultiProductAction;
use Netflie\WhatsAppCloudApi\Message\OptionsList\Action;
use Netflie\WhatsAppCloudApi\Message\Template\Component;

Expand Down Expand Up @@ -395,6 +396,33 @@ public function uploadMedia(string $file_path): Response
return $this->client->uploadMedia($request);
}

/**
* Sends a message with multiple products to a user.
*
* @param string $to The WhatsApp ID or phone number for the person you want to send a message to.
* @param int $catalog_id The ID of the catalog where the products are located.
* @param MultiProductAction $action The contents of the catalog products to be sent.
* @param string $header The header of the message.
* @param string $body The body of the message.
* @param string|null $footer The footer of the message.
*
* @return Response The response object containing the result of the API request.
*
* @throws Response\ResponseException If the API request fails.
*/
public function sendMultiProduct(string $to, int $catalog_id, MultiProductAction $action, string $header, string $body, ?string $footer = '')
{
$message = new Message\MultiProductMessage($to, $catalog_id, $action, $header, $body, $footer, $this->reply_to);
$request = new Request\MessageRequest\RequestMultiProductMessage(
$message,
$this->app->accessToken(),
$this->app->fromPhoneNumberId(),
$this->timeout
);

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

/**
* Download a media file (image, audio, video...) from Facebook servers.
*
Expand Down
43 changes: 43 additions & 0 deletions tests/Integration/WhatsAppCloudApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
use Netflie\WhatsAppCloudApi\Message\CtaUrl\TitleHeader;
use Netflie\WhatsAppCloudApi\Message\Media\LinkID;
use Netflie\WhatsAppCloudApi\Message\Media\MediaObjectID;
use Netflie\WhatsAppCloudApi\Message\MultiProduct\Action as MultiProductAction;
use Netflie\WhatsAppCloudApi\Message\MultiProduct\Row as MultiProductRow;
use Netflie\WhatsAppCloudApi\Message\MultiProduct\Section as MultiProductSection;
use Netflie\WhatsAppCloudApi\Message\OptionsList\Action;
use Netflie\WhatsAppCloudApi\Message\OptionsList\Row;
use Netflie\WhatsAppCloudApi\Message\OptionsList\Section;
Expand Down Expand Up @@ -304,6 +307,46 @@ public function test_send_catalog_message()
$this->assertEquals(false, $response->isError());
}

public function test_send_multi_product()
{
$this->markTestIncomplete(
'This test should send a real catalog ID and product SKU ID.'
);

$rows_section_1 = [
new MultiProductRow('<product-sku-id>'),
// can add more
];

$rows_section_2 = [
new MultiProductRow('<product-sku-id>'),
// can add more
];

$sections = [
new MultiProductSection('Section 1', $rows_section_1),
new MultiProductSection('Section 2', $rows_section_2),
];

$action = new MultiProductAction($sections);
$catalog_id = '<catalog-id>';
$header = 'Grocery Collections';
$body = 'Hello! Thanks for your interest. Here\'s what we can offer you under our grocery collection. Thank you for shopping with us.';
$footer = 'Subject to T&C';

$response = $this->whatsapp_app_cloud_api->sendMultiProduct(
WhatsAppCloudApiTestConfiguration::$to_phone_number_id,
$catalog_id,
$action,
$header,
$body,
$footer // optional
);

$this->assertEquals(200, $response->httpStatusCode());
$this->assertEquals(false, $response->isError());
}

public function test_send_reply_buttons()
{
$buttonRows = [
Expand Down
Loading

0 comments on commit 3c3aea9

Please sign in to comment.