Wax.Messages.Interactive (wax v1.1.4)

Interactive Messages

Important

Interactive messages of type catalog_message is not supported for lack of documentation on the Cloud API site. They can be added in the future.

TODO: Implement multi-product interactive messages

Summary

Functions

Creates a new interactive object

Sets the body of the Interactive message

Adds a list of buttons to the Interactive message

Sets the footer of the Interactive message

Sets the header of the Interactive message

Adds a list to the Interactive message

Adds a product to the Interactive message

Validates an Interactive struct

Types

t()

@type t() :: %Wax.Messages.Interactive{
  action: term(),
  body: map(),
  footer: map(),
  header: Wax.Messages.Interactive.Header.t(),
  type: type()
}

type()

@type type() :: :button | :list | :product | :product_list | :flow

Functions

new()

@spec new() :: t()

Creates a new interactive object

put_body(interactive, content)

@spec put_body(t(), String.t()) :: t()

Sets the body of the Interactive message

put_button_action(interactive, buttons)

@spec put_button_action(t(), [button_title :: String.t()]) :: t()

Adds a list of buttons to the Interactive message

The buttons argument is expected to be a list of strings where each element will be the title (content) of the button.

A max of 3 buttons can be sent.

put_flow_action(interactive, flow_cta, flow_identifier, optional_params \\ %{})

@spec put_flow_action(t(), String.t(), {:id | :name, String.t()}, map()) :: t()

Sets the message action to a Flow

Note on Flow type messages

As for 2025-07-21 the Whatsapp Cloud API documentation says all fields for Flow messages appear directly on the Action object and this is incorrect as it can be seen on the examples of the same documentation.

This is the example given:

curl -X  POST 'https://graph.facebook.com/v23.0/FROM_PHONE_NUMBER/messages' -H 'Authorization: Bearer ACCESS_TOKEN' -H 'Content-Type: application/json' -d '{
 "messaging_product": "whatsapp",
 "recipient_type": "individual",
 "to": "PHONE_NUMBER",
 "type": "interactive",
 "interactive" : {
  "type": "flow",
  "header": {
    "type": "text",
    "text": "Flow message header"
  },
  "body": {
    "text": "Flow message body"
  },
  "footer": {
    "text": "Flow message footer"
  },
  "action": {
    "name": "flow",
    "parameters": {
      "flow_message_version": "3",
      "flow_id": "<FLOW_ID>", // Or flow_name
      "flow_cta": "Book!",
     }
    }
   }
  }
}'

These fields have to be sent between:

  • name: The only thing that appears on the docs about this field is an example with a fixed string "flow"
  • parameters: Here is where the flow ID, name and other values have to be sent

put_footer(interactive, content)

@spec put_footer(t(), String.t()) :: t()

Sets the footer of the Interactive message

The footer content cannot be more than 60 characters

put_header(interactive, type, content, sub_text \\ nil)

@spec put_header(
  t(),
  Wax.Messages.Interactive.Header.type(),
  String.t() | Media.t(),
  String.t() | nil
) ::
  t()

Sets the header of the Interactive message

put_list_action(interactive, button_text, sections)

Adds a list to the Interactive message

The sections argument requires a list of %Section{} structs that can be constructed using the Wax.Messages.Interactive.Section module

put_product_action(interactive, catalog_id, product_retailer_id)

@spec put_product_action(t(), String.t(), String.t()) :: t()

Adds a product to the Interactive message

The product ID has to be a valid ID from your catalog only containing digits.

validate(interactive)

@spec validate(t()) :: :ok | {:error, String.t()}

Validates an Interactive struct