ruby-whatsapp 0.6.1 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 65b698016d0bde6643f240f8e78fc598c3ad7bd2f69a0ec6e001d02f2601e565
4
- data.tar.gz: 99d27c447f3b17c55bfc4f4f916d1a22a4fcd5572e2bc5d96ef4f7a737463ae1
3
+ metadata.gz: 5c33c221aee102d5b25468617f808a4f91c2e54a5659922576cd542dff802458
4
+ data.tar.gz: 10d24cb87f52e82ba182b4360bd25c6e2ae1fe9b8bb78d4d6141c17b2dc6c91f
5
5
  SHA512:
6
- metadata.gz: 57d5e745fa4255d5bb6125111ad18059b9325c6121eaa1b41482fc9b318e230e2d801cde7e760a4c7fe37922aa8c72fd0a38143f2b7daed91921fdeef98a8707
7
- data.tar.gz: df83a3dd120820a8b3ca71986ed5d41bd66487805a1e0fcf5be4ca478be7c0d2aac97ce2b0726e58c438988629de41e213dff093b1db5e3e099c78b73b5ab9d9
6
+ metadata.gz: bd104f12c9ec44b4b07e5912f18e98ae4646a4eb1f51869b27dcc978b76ee06d385e81a6d41ce449b96460f08e0d2ddfb56b4d57ce410d3493f45e243f71883c
7
+ data.tar.gz: 79366a3af17543676a403b43b23e2df31b5c4219f2b440a2a438053ee8fa651f6513651e85b237693f30749afe085879d948c828a6090337c5e14508398ba7a3
data/CHANGELOG.md CHANGED
@@ -1,4 +1,19 @@
1
- ## [0.6.1]
1
+ ## [0.6.2] - 2026-10-22
2
+
3
+ ### Fixed
4
+
5
+ - **A single-section list message no longer needs a section title.** Meta requires
6
+ `sections[].title` only when a list has more than one section, but
7
+ `Interactive::ListButtons::Section` demanded one always — `title:` was a required
8
+ keyword with a presence validation — so a valid single-section list without a title
9
+ could not be built. `Section` now takes `title:` as optional (still max 24 characters)
10
+ and omits the key from the payload when it is absent, and `ListButtons` enforces Meta's
11
+ actual rule: with two or more sections, every one must have a title, otherwise it fails
12
+ with "Sections must each have a title when there is more than one section". A blank
13
+ title (`""` or whitespace) is treated as absent — omitted from a single section, and
14
+ counted as missing when there are several — rather than sent as an empty heading.
15
+
16
+ ## [0.6.1] - 2026-10-21
2
17
 
3
18
  ### Added
4
19
 
@@ -116,7 +116,7 @@ Whatsapp::Messages.send_interactive!(
116
116
  | --- | --- |
117
117
  | `button` | Required, max **20** characters — the label that opens the list |
118
118
  | `sections` | **1–10** sections |
119
- | `sections[].title` | Required, max **24** characters |
119
+ | `sections[].title` | Required only when there is **more than one** section, max **24** characters. A blank title counts as absent and is omitted |
120
120
  | `sections[].rows` | **1–10** rows |
121
121
  | `rows[].id` | Required, max **200** characters |
122
122
  | `rows[].title` | Required, max **24** characters |
@@ -136,6 +136,25 @@ Whatsapp::Messages::Interactive.new(
136
136
  # description: "Strong & short" }] }] } } }
137
137
  ```
138
138
 
139
+ A list with a single section can leave its title out, and the `title` key is then
140
+ omitted from the payload. Once there are two or more sections, each one needs a title:
141
+
142
+ ```ruby
143
+ Whatsapp::Messages::Interactive.new(
144
+ to: "+15551234567", type: :list_buttons, body: "Pick a time slot",
145
+ action: { button: "Slots", sections: [
146
+ { rows: [{ id: "9am", title: "09:00" }, { id: "2pm", title: "14:00" }] },
147
+ ] }
148
+ ).serialize
149
+ # => { ..., interactive: { type: "list", body: { text: "Pick a time slot" },
150
+ # action: { button: "Slots",
151
+ # sections: [{ rows: [{ id: "9am", title: "09:00" },
152
+ # { id: "2pm", title: "14:00" }] }] } } }
153
+
154
+ # Two sections, one untitled:
155
+ # => ActiveModel::ValidationError: Sections must each have a title when there is more than one section
156
+ ```
157
+
139
158
  A tap arrives back as a webhook `Message::Interactive` with
140
159
  `interactive_type == "list_reply"`.
141
160
 
@@ -14,21 +14,26 @@ module Whatsapp
14
14
  end
15
15
 
16
16
  # @!attribute [rw] title
17
- # @return [String]
17
+ # @return [String, nil]
18
18
  attr_accessor :title
19
19
 
20
20
  # @!attribute [rw] rows
21
21
  # @return [Array<Hash>]
22
22
  attr_accessor :rows
23
23
 
24
- validates :title, presence: true, length: { maximum: Defaults::MAX_TITLE_LENGTH }
24
+ # Optional here: Meta requires a title only when the list has more than one
25
+ # section, which a lone Section cannot see — {ListButtons} enforces that rule.
26
+ validates :title, length: { maximum: Defaults::MAX_TITLE_LENGTH }, allow_nil: true
25
27
  validates :rows, presence: true, length: { minimum: Defaults::MIN_ROWS_LENGTH, maximum: Defaults::MAX_ROWS_LENGTH }
26
28
 
27
- # @param title [String] The title of the section.
29
+ # A blank title (`""` or whitespace) is treated as absent, so it is omitted from
30
+ # the payload rather than sent as an empty heading.
28
31
  # @param rows [Array<Hash>] The rows in the section.
32
+ # @param title [String, nil] The title of the section. Required only when the list
33
+ # has more than one section (enforced by {ListButtons}).
29
34
  # @raise [ActiveModel::ValidationError] if validation fails.
30
- def initialize(title:, rows:)
31
- @title = title
35
+ def initialize(rows:, title: nil)
36
+ @title = title.presence
32
37
  @rows = rows
33
38
 
34
39
  validate!
@@ -47,7 +52,7 @@ module Whatsapp
47
52
  {
48
53
  title:,
49
54
  rows: serialized_rows,
50
- }
55
+ }.compact
51
56
  end
52
57
 
53
58
  private
@@ -23,6 +23,7 @@ module Whatsapp
23
23
  validates :button, presence: true, length: { maximum: Defaults::MAX_BUTTON_LENGTH }
24
24
  validates :sections, presence: true, length: { minimum: Defaults::MIN_SECTIONS_COUNT,
25
25
  maximum: Defaults::MAX_SECTIONS_COUNT, }
26
+ validate :validate_section_titles
26
27
 
27
28
  # @param button [String] The text for the list button.
28
29
  # @param sections [Array<Hash>] The sections of the list button.
@@ -52,6 +53,17 @@ module Whatsapp
52
53
 
53
54
  private
54
55
 
56
+ # Meta requires `sections[].title` only once a list has more than one section, so
57
+ # {Section} leaves it optional and the rule lives here, where the count is known.
58
+ # A blank title counts as missing, matching {Section}, which omits it.
59
+ # @return [void]
60
+ def validate_section_titles
61
+ return if sections.blank? || sections.size <= 1
62
+ return if sections.all? { |section| section[:title].present? }
63
+
64
+ errors.add(:sections, "must each have a title when there is more than one section")
65
+ end
66
+
55
67
  # @return [Array<Hash>] Serialized sections.
56
68
  # @raise [ActiveModel::ValidationError] if validation fails.
57
69
  def serialized_sections
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Whatsapp
4
- VERSION = "0.6.1"
4
+ VERSION = "0.6.2"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-whatsapp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Raniery