Module: Whatsapp::MessageTemplates::Example

Defined in:
lib/ruby/whatsapp/message_templates/example.rb

Overview

Builds the example payload Meta requires alongside any component text that contains placeholders.

This exists because the key name of that payload changes with both the component and the template's parameter format — four combinations that are easy to get wrong and are a common source of template rejections:

       | POSITIONAL                    | NAMED
---------+-------------------------------+--------------------------------
header   | header_text: ["Sale"]         | header_text_named_params: [...]
body     | body_text: [["a", "b"]]       | body_text_named_params: [...]

Note the asymmetry: header_text is a flat array while body_text is an array of arrays. Meta documents no reason for it; it just is.

Callers may pass a plain Array (positional), a Hash of name => example (named), Meta's own [{param_name:, example:}] array, or a fully-built payload hash copied verbatim out of Meta's docs — all four are accepted so pasting a known- good example from the API reference works without translation. Source: https://developers.facebook.com/docs/whatsapp/business-management-api/message-templates/components/

Constant Summary collapse

ROLES =

Maps a component role to its example key for each parameter format.

{
  header: { positional: :header_text, named: :header_text_named_params },
  body: { positional: :body_text, named: :body_text_named_params },
}.freeze
BUILT_KEYS =

Keys that mean "the caller already built this payload, pass it through". header_handle is included because media headers carry an asset handle here rather than text parameters.

(ROLES.values.flat_map(&:values) + [:header_handle]).freeze
NESTED_ROLES =

Roles whose positional example is nested one level deeper.

[:body].freeze

Class Method Summary collapse

Class Method Details

.count(role:, parameter_format:, values:) ⇒ Integer

The number of example values supplied, whatever shape they arrived in.

Used by components to check the example count against the placeholder count without needing to know which of the four shapes the caller used.

Returns:

  • (Integer)


64
65
66
67
68
69
70
71
72
73
# File 'lib/ruby/whatsapp/message_templates/example.rb', line 64

def count(role:, parameter_format:, values:)
  payload = serialize(role:, parameter_format:, values:)
  return 0 if payload.nil?

  key, value = payload.first
  return value.size if key.to_s.end_with?("named_params")
  return Array(value.first).size if NESTED_ROLES.any? { |r| ROLES[r][:positional] == key }

  value.size
end

.serialize(role:, parameter_format:, values:) ⇒ Hash?

Returns The example payload, or nil when there are no values.

Parameters:

  • role (Symbol)

    :header or :body.

  • parameter_format (String, Symbol, nil)
  • values (Array, Hash, String, nil)

    the example value(s).

Returns:

  • (Hash, nil)

    The example payload, or nil when there are no values.

Raises:

  • (ArgumentError)

    if the role is unknown or the values do not match the parameter format.



47
48
49
50
51
52
53
54
55
56
57
# File 'lib/ruby/whatsapp/message_templates/example.rb', line 47

def serialize(role:, parameter_format:, values:)
  keys = keys_for(role)
  return if blank_value?(values)
  return symbolize(values) if built?(values)

  if ParameterFormats.named?(parameter_format)
    { keys[:named] => named_params(values) }
  else
    { keys[:positional] => positional_values(role, values) }
  end
end