Skip to content

feat: add media header support for button reply, template, and CTA URL messages#235

Open
Vishwaraj123 wants to merge 3 commits intonetflie:developmentfrom
Vishwaraj123:main
Open

feat: add media header support for button reply, template, and CTA URL messages#235
Vishwaraj123 wants to merge 3 commits intonetflie:developmentfrom
Vishwaraj123:main

Conversation

@Vishwaraj123
Copy link
Copy Markdown

@Vishwaraj123 Vishwaraj123 commented Dec 13, 2025

Adds media support for Button Reply, Template, and CTA URL message types.
This includes new frontend components and corresponding request handlers to process and store these messages.

  • New message components added
  • Backend handlers updated to accept new message formats
  • No breaking changes to existing flows

@Vishwaraj123 Vishwaraj123 changed the title feat: add support for button reply, template, and CTA URL messages feat: add media header support for button reply, template, and CTA URL messages Dec 13, 2025
@aalbarca aalbarca requested a review from Copilot February 27, 2026 09:49
@aalbarca aalbarca changed the base branch from main to development February 27, 2026 09:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds richer header/media support to interactive Button Reply messages and CTA URL headers, plus extends template requests to support an additional “marketing messages” endpoint and a carousel component.

Changes:

  • Add new header value objects for Button Reply (text/image/video/document) and CTA URL (video/document).
  • Update request/message building to accept header objects for button replies and append template carousel components.
  • Add optional /marketing_messages endpoint support for template sending via a new $use_mm_lite flag.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/WhatsAppCloudApi.php Extends sendTemplate() with $use_mm_lite and updates sendButton() to accept header objects (or strings mapped to TextHeader).
src/Request/MessageRequest.php Adds use_mm_lite flag and switches node path to /marketing_messages when enabled.
src/Request/MessageRequest/RequestTemplateMessage.php Appends carousel data into template.components.
src/Message/TemplateMessage.php Exposes carousel() data from template components.
src/Message/Template/Component.php Adds storage/accessor for carousel component data.
src/Request/MessageRequest/RequestButtonReplyMessage.php Uses message-provided header body and marks request class final.
src/Message/ButtonReplyMessage.php Changes button message header type to an object-backed header and marks message class final.
src/Message/ButtonReply/Header.php Introduces abstract base for Button Reply headers.
src/Message/ButtonReply/TextHeader.php Implements text header body for Button Reply.
src/Message/ButtonReply/ImageHeader.php Implements image header body for Button Reply (MediaID-based).
src/Message/ButtonReply/VideoHeader.php Implements video header body for Button Reply (MediaID-based).
src/Message/ButtonReply/DocumentHeader.php Implements document header body for Button Reply (MediaID + filename).
src/Message/CtaUrl/VideoHeader.php Adds CTA URL video header (link-based).
src/Message/CtaUrl/DocumentHeader.php Adds CTA URL document header (MediaID + filename).
src/WebHook/Notification/Support/Referral.php Removes ctwa_clid from referral support object.
src/WebHook/Notification/MessageNotificationFactory.php Stops passing ctwa_clid when constructing Referral.
README.md Documents new header options for CTA URL and Button Reply messages.
Comments suppressed due to low confidence (1)

src/WhatsAppCloudApi.php:369

  • sendButton() now accepts an untyped $header but only supports string|null|ButtonReply\\Header at runtime. Add a PHPDoc @param with the supported types and update the exception message to use ButtonHeader::class (or similar) instead of a hard-coded class string, to avoid drift during refactors.
    public function sendButton(string $to, string $body, ButtonAction $action, $header = null, ?string $footer = null): Response
    {
        if (is_string($header)) {
            $header = new TextHeader($header);
        }

        if (!$header instanceof ButtonHeader && $header !== null) {
            throw new InvalidMessage('Header must be instance of Netflie\WhatsAppCloudApi\Message\ButtonReply\Header if not left null');
        }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +47 to +50
if ($this->message->carousel()) {
$carousel = $this->message->carousel();
$body['template']['components'][] = $carousel;
}
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RequestTemplateMessage::body() now appends carousel data into template.components, but there are no unit tests covering the new carousel behavior (including how it should be shaped/merged into components). Please add/update tests to lock in the expected request payload when a carousel is present.

Copilot uses AI. Check for mistakes.
use Netflie\WhatsAppCloudApi\Request\MessageRequest;

class RequestButtonReplyMessage extends MessageRequest
final class RequestButtonReplyMessage extends MessageRequest
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class is changed to final, which is a backwards-incompatible change for any consumers extending it. If there’s no strong need to prevent inheritance, consider leaving it non-final (or documenting this as a major-version change).

Suggested change
final class RequestButtonReplyMessage extends MessageRequest
class RequestButtonReplyMessage extends MessageRequest

Copilot uses AI. Check for mistakes.
Comment on lines 8 to 33
@@ -26,9 +27,9 @@ public function __construct(string $to, string $body, ButtonAction $action, ?str
parent::__construct($to, $reply_to);
}

public function header(): ?string
public function header(): ?array
{
return $this->header;
return $this->header ? $this->header->getBody() : null;
}
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description claims “No breaking changes”, but this diff removes public API surface (e.g., Referral::ctwaClid() and changes ButtonReplyMessage public signatures/types). Please either restore backwards compatibility or update the PR description/changelog to reflect the breaking changes.

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +25
protected $use_mm_lite;

public function __construct(Message $message, string $access_token, string $from_phone_number_id, ?int $timeout = null)
public function __construct(Message $message, string $access_token, string $from_phone_number_id, ?int $timeout = null, $use_mm_lite = false)
{
$this->message = $message;
$this->from_phone_number_id = $from_phone_number_id;
$this->use_mm_lite = $use_mm_lite;
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$use_mm_lite is stored as an untyped property/parameter, so non-boolean truthy values (e.g. the string "false") will still switch the node path to /marketing_messages. Since this flag controls the endpoint, it should be strictly typed as bool (property and constructor param) and/or explicitly cast to bool when assigned.

Copilot uses AI. Check for mistakes.
Comment thread src/WhatsAppCloudApi.php
Comment on lines 123 to +136
* @link https://developers.facebook.com/docs/whatsapp/api/messages/message-templates#supported-languages See language codes supported.
* @return Response
*
* @throws Response\ResponseException
*/
public function sendTemplate(string $to, string $template_name, string $language = 'en_US', ?Component $components = null): Response
public function sendTemplate(string $to, string $template_name, string $language = 'en_US', ?Component $components = null, $use_mm_lite = false): Response
{
$message = new Message\TemplateMessage($to, $template_name, $language, $components, $this->reply_to);
$request = new Request\MessageRequest\RequestTemplateMessage(
$message,
$this->app->accessToken(),
$this->app->fromPhoneNumberId(),
$this->timeout
$this->timeout,
$use_mm_lite
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sendTemplate() introduces $use_mm_lite without a bool type and without documenting it in the PHPDoc. Because this ultimately changes the request endpoint, please type it as bool and document what it does (when to use /marketing_messages vs /messages).

Copilot uses AI. Check for mistakes.
Comment on lines 8 to 33
@@ -26,9 +27,9 @@ public function __construct(string $to, string $body, ButtonAction $action, ?str
parent::__construct($to, $reply_to);
}

public function header(): ?string
public function header(): ?array
{
return $this->header;
return $this->header ? $this->header->getBody() : null;
}
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ButtonReplyMessage is now final, its constructor changes $header from ?string to ?Header, and header() changes its return type from ?string to ?array. These are backwards-incompatible changes for any consumers instantiating/extending this message directly (and contradict the PR note about “No breaking changes”). Consider keeping the previous API (or adding new methods/types and deprecating the old ones) instead of changing the public signature/return types.

Copilot uses AI. Check for mistakes.
Comment on lines 20 to 32
@@ -30,8 +28,7 @@ public function __construct(
string $body,
string $media_type,
string $media_url,
string $thumbnail_url,
string $ctwa_clid
string $thumbnail_url
) {
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Referral drops the ctwa_clid constructor parameter and removes the ctwaClid() accessor. This is a breaking change for webhook consumers relying on that referral field. If the platform no longer sends ctwa_clid, consider keeping the property/accessor as nullable (or deprecating first) rather than removing it outright.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants