line-message-builder 0.9.0 → 0.10.0

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.release-please-manifest.json +1 -1
  3. data/.rubocop.yml +5 -0
  4. data/CHANGELOG.md +20 -0
  5. data/CLAUDE.md +124 -0
  6. data/README.md +24 -16
  7. data/claudekit.json +11 -0
  8. data/docs/rubrics/rdoc.md +169 -0
  9. data/lib/line/message/builder/actions/message.rb +47 -26
  10. data/lib/line/message/builder/actions/postback.rb +56 -26
  11. data/lib/line/message/builder/actions/uri.rb +139 -0
  12. data/lib/line/message/builder/actions.rb +6 -3
  13. data/lib/line/message/builder/base.rb +92 -67
  14. data/lib/line/message/builder/container.rb +55 -60
  15. data/lib/line/message/builder/context.rb +51 -72
  16. data/lib/line/message/builder/flex/actionable.rb +53 -32
  17. data/lib/line/message/builder/flex/box.rb +342 -79
  18. data/lib/line/message/builder/flex/bubble.rb +73 -46
  19. data/lib/line/message/builder/flex/builder.rb +39 -28
  20. data/lib/line/message/builder/flex/button.rb +90 -42
  21. data/lib/line/message/builder/flex/carousel.rb +48 -20
  22. data/lib/line/message/builder/flex/icon.rb +152 -0
  23. data/lib/line/message/builder/flex/image.rb +95 -33
  24. data/lib/line/message/builder/flex/partial.rb +47 -49
  25. data/lib/line/message/builder/flex/position.rb +187 -100
  26. data/lib/line/message/builder/flex/separator.rb +49 -6
  27. data/lib/line/message/builder/flex/size.rb +67 -47
  28. data/lib/line/message/builder/flex/span.rb +106 -32
  29. data/lib/line/message/builder/flex/text.rb +166 -54
  30. data/lib/line/message/builder/flex.rb +26 -23
  31. data/lib/line/message/builder/quick_reply.rb +174 -4
  32. data/lib/line/message/builder/text.rb +70 -3
  33. data/lib/line/message/builder/version.rb +1 -1
  34. data/lib/line/message/builder.rb +14 -11
  35. data/lib/line/message/rspec/matchers/have_flex_bubble.rb +1 -1
  36. data/lib/line/message/rspec/matchers/have_flex_component.rb +16 -6
  37. data/lib/line/message/rspec/matchers/have_flex_message.rb +1 -1
  38. data/lib/line/message/rspec/matchers/have_flex_separator.rb +1 -1
  39. data/lib/line/message/rspec/matchers/have_quick_reply.rb +1 -1
  40. data/lib/line/message/rspec/matchers/have_text_message.rb +1 -1
  41. data/llm.txt +276 -35
  42. data/release-please-config.json +3 -1
  43. metadata +9 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e0b31fce5c00d5f47ade90df479d30b79361f73e3e08852e10f4f90996de5bb9
4
- data.tar.gz: 6a72a291942bd3f7448f5a294da49dd3321424d5dad057745590e4b96b1a1abb
3
+ metadata.gz: 5da58bf9e4dc340ba666cb7074f3c43c1c1bb71db5fbd9e65229064e414720d5
4
+ data.tar.gz: 0aed8988bdbd8b5273eeedcff427f62f8a4be6a68a9b8935d9cf0792b0b0cdff
5
5
  SHA512:
6
- metadata.gz: bb358c2a18903395e07bfc878d3befe2048ad23c5d68b4e5cd23e17e1914bb300f7a692858a68f9c71daa3630b1f30761ab5fc603887296c1d1cffd4964b7414
7
- data.tar.gz: 342237372588844319052e9be35b1014024f5f93552f99699137f19a5abf7f341bd03eda306f4f2c5d181c50f257f47fdf5f0a7899cc2093312a91d4cd42667f
6
+ metadata.gz: 867683533deec71a69b0019bc40b6abffa81fad98cab36da0c2f6f298f2c80b50f863700b88634a7bc5c66fa62ed53781782e24654aa5f427181ccb2c9dd4929
7
+ data.tar.gz: 8d4e59936aa354b5a2f29d21285dd449cf033ec7b6cc7b7c19fb32b3098b84bb9317a86f2998fa4dc4a5c70e837a2f0ef9a07027fbd57be691eb3e907dc4a8c2
@@ -1 +1 @@
1
- {".":"0.9.0"}
1
+ {".":"0.10.0"}
data/.rubocop.yml CHANGED
@@ -14,3 +14,8 @@ Style/StringLiterals:
14
14
 
15
15
  Style/StringLiteralsInInterpolation:
16
16
  EnforcedStyle: double_quotes
17
+
18
+ # RSpec matchers often return booleans but shouldn't be named with '?'
19
+ Naming/PredicateMethod:
20
+ Exclude:
21
+ - 'lib/line/message/rspec/**/*'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.10.0](https://github.com/elct9620/line-message-builder/compare/v0.9.0...v0.10.0) (2026-08-18)
4
+
5
+
6
+ ### ⚠ BREAKING CHANGES
7
+
8
+ * **builder:** passing an option a component does not declare now raises ValidationError instead of being ignored.
9
+ * **flex:** Flex buttons no longer accept padding, padding_all, padding_top, padding_bottom, padding_start or padding_end. Apply padding to the surrounding box instead.
10
+
11
+ ### Features
12
+
13
+ * **actions:** add uri action ([d5fdb26](https://github.com/elct9620/line-message-builder/commit/d5fdb261014e927c58b5ae16e29c2b46d934b758))
14
+ * **builder:** reject options a component does not declare ([0e236b3](https://github.com/elct9620/line-message-builder/commit/0e236b35ee9a562d031c474e23dc819055fdea4d))
15
+ * **flex:** add box appearance properties and gradient background ([809e84a](https://github.com/elct9620/line-message-builder/commit/809e84a1faf6d84c15a20964c5fd78ab43907ead))
16
+ * **flex:** add button color and scaling, drop padding ([2ef15fd](https://github.com/elct9620/line-message-builder/commit/2ef15fd09b2a441fb2f17c938497861906570f83))
17
+ * **flex:** add icon component ([cbd1eda](https://github.com/elct9620/line-message-builder/commit/cbd1edacbef8a377b3c7ad72059833915f1ea010))
18
+ * **flex:** add image background_color and animated ([c7f2102](https://github.com/elct9620/line-message-builder/commit/c7f21028640a47d171823e0d047e2c228f5c9844))
19
+ * **flex:** add separator margin and color ([073c039](https://github.com/elct9620/line-message-builder/commit/073c0391d2a1092b0c4886588123491fa260b946))
20
+ * **flex:** add span style ([ef80a4b](https://github.com/elct9620/line-message-builder/commit/ef80a4b8236bef920cc87af7cf051dd3dff5044a))
21
+ * **flex:** add text weight, max_lines, style, decoration and scaling ([d6a83b4](https://github.com/elct9620/line-message-builder/commit/d6a83b41415e95e69cf746d5d628d48dcefb8390))
22
+
3
23
  ## [0.9.0](https://github.com/elct9620/line-message-builder/compare/v0.8.0...v0.9.0) (2025-06-03)
4
24
 
5
25
 
data/CLAUDE.md ADDED
@@ -0,0 +1,124 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Repository Overview
6
+
7
+ This is a Ruby gem that provides a Domain Specific Language (DSL) for building LINE messaging API messages. The gem allows developers to construct complex Flex Messages, text messages, and quick replies using an intuitive Ruby syntax.
8
+
9
+ ## Development Commands
10
+
11
+ ### Testing
12
+ - `rake spec` or `bundle exec rspec` - Run all tests
13
+ - `bundle exec rspec spec/specific_file_spec.rb` - Run a specific test file
14
+ - `bundle exec rspec spec/specific_file_spec.rb:123` - Run test at specific line
15
+
16
+ ### Code Quality
17
+ - `rake rubocop` or `bundle exec rubocop` - Run RuboCop linter
18
+ - `bundle exec rubocop --autocorrect` - Auto-fix RuboCop violations where possible
19
+ - `rake` - Run both tests and RuboCop (default task)
20
+
21
+ ### Build and Release
22
+ - `bundle exec rake install` - Install gem locally
23
+ - `bundle exec rake build` - Build the gem
24
+ - `bundle exec rake release` - Release new version (creates git tag and pushes to RubyGems)
25
+
26
+ ### Console
27
+ - `bin/console` - Interactive console with the gem loaded
28
+
29
+ ## Architecture
30
+
31
+ ### Core Components
32
+
33
+ **Main Builder (`lib/line/message/builder.rb`)**
34
+ - Entry point for the DSL using `Line::Message::Builder.with`
35
+ - Handles context binding and message collection
36
+ - Supports both regular mode and SDK v2 mode
37
+
38
+ **Base Classes**
39
+ - `Builder::Base` - Foundation for all builder components
40
+ - `Builder::Container` - Base for components that can contain other components
41
+ - `Builder::Context` - Manages variable access and method delegation
42
+
43
+ **Message Types**
44
+ - `Builder::Text` - Simple text messages with quick reply support
45
+ - `Builder::Flex` - Complex flex messages with rich layouts
46
+
47
+ **Flex Components (`lib/line/message/builder/flex/`)**
48
+ - `Bubble` - Main flex container
49
+ - `Carousel` - Collection of bubbles
50
+ - `Box` - Layout container (horizontal/vertical/baseline)
51
+ - `Text` - Text component with span support
52
+ - `Span` - Inline text styling within text components
53
+ - `Button` - Interactive buttons
54
+ - `Image` - Image components
55
+ - `Separator` - Visual separators
56
+
57
+ **Actions (`lib/line/message/builder/actions/`)**
58
+ - `Message` - Send text message action
59
+ - `Postback` - Send postback data action
60
+
61
+ **Quick Replies**
62
+ - `QuickReply` - Container for quick reply buttons
63
+
64
+ **Partials**
65
+ - `Flex::Partial` - Base class for reusable flex components
66
+
67
+ ### Key Patterns
68
+
69
+ **DSL Design**: The gem uses Ruby's block evaluation (`instance_eval`) to create a clean DSL where methods like `text`, `box`, `button` are available directly within builder blocks.
70
+
71
+ **Context Handling**: The builder accepts a context object (like Rails' `view_context`) and delegates unknown methods to it, enabling access to helpers and variables.
72
+
73
+ **Validation**: Components validate their properties using the `validators/` classes to ensure LINE API compatibility.
74
+
75
+ **Testing Strategy**: Uses feature-style tests that build complete messages and verify their structure, rather than unit tests of individual methods.
76
+
77
+ ## Coding Conventions
78
+
79
+ ### DSL Usage
80
+ ```ruby
81
+ # Preferred - clean DSL syntax
82
+ Line::Message::Builder.with do
83
+ flex alt_text: "Hello" do
84
+ bubble do
85
+ body do
86
+ text "Content"
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ # Avoid - explicit block parameters
93
+ Line::Message::Builder.with do |builder|
94
+ builder.flex alt_text: "Hello" do
95
+ # ...
96
+ end
97
+ end
98
+ ```
99
+
100
+ ### RSpec Testing
101
+ - Write feature tests using the full DSL as the test subject
102
+ - Use `subject { builder.build }` pattern
103
+ - Prefer `it { is_expected.to ... }` over `expect(subject)...`
104
+ - One assertion per example
105
+ - Test message structure, not implementation details
106
+
107
+ ### Code Style
108
+ - Follow standard Ruby naming conventions (snake_case, CamelCase, UPPER_SNAKE_CASE)
109
+ - No explanatory comments - code should be self-documenting
110
+ - Use RDoc for API documentation only
111
+
112
+ ## RSpec Matchers
113
+
114
+ The gem provides custom RSpec matchers for testing LINE messages:
115
+ - `have_line_text_message` - Match text messages
116
+ - `have_line_flex_message` - Match flex messages
117
+ - `have_line_flex_bubble` - Match flex bubbles
118
+ - `have_line_flex_component` - Match specific flex components
119
+
120
+ Include with: `require "line/message/rspec"`
121
+
122
+ ## LLM Integration
123
+
124
+ The repository includes `llm.txt` with comprehensive DSL documentation for AI assistants. This file contains detailed examples and API references for all supported LINE message types and components.
data/README.md CHANGED
@@ -42,7 +42,7 @@ You can get it from [http://aotoki.me/line-message-builder/llm.txt](http://aotok
42
42
  ### Builder
43
43
 
44
44
  ```ruby
45
- builder = Line::MessageBuilder::Builder.with do
45
+ builder = Line::Message::Builder.with do
46
46
  text "Hello, world!"
47
47
  end
48
48
 
@@ -50,13 +50,13 @@ pp builder.build
50
50
  # => [{ type: "text", text: "Hello, world!" }]
51
51
 
52
52
  puts builder.to_json
53
- # => "[{\"type\":\"text",\"text\":\"Hello, world!\"}"
53
+ # => "[{\"type\":\"text\",\"text\":\"Hello, world!\"}]"
54
54
  ```
55
55
 
56
56
  To use with [line-bot-sdk-ruby](https://github.com/line/line-bot-sdk-ruby) v2, you can set mode to `sdkv2`:
57
57
 
58
58
  ```ruby
59
- builder = Line::MessageBuilder::Builder.with(mode: :sdkv2) do
59
+ builder = Line::Message::Builder.with(mode: :sdkv2) do
60
60
  text "Hello, world!"
61
61
  end
62
62
  ```
@@ -70,7 +70,7 @@ context = OpenStruct.new(
70
70
  name: "John Doe",
71
71
  )
72
72
 
73
- builder = Line::MessageBuilder::Builder.with(context) do
73
+ builder = Line::Message::Builder.with(context) do
74
74
  text "Hello, #{name}!"
75
75
  end
76
76
 
@@ -78,14 +78,14 @@ pp builder.build
78
78
  # => [{ type: "text", text: "Hello, John Doe!" }]
79
79
 
80
80
  puts builder.to_json
81
- # => "[{\"type\":\"text\",\"text\":\"Hello, John Doe!\"}"
81
+ # => "[{\"type\":\"text\",\"text\":\"Hello, John Doe!\"}]"
82
82
  ```
83
83
 
84
84
  For Rails, you can use `view_context` to make `Builder` to access Rails helpers.
85
85
 
86
86
  ```ruby
87
87
  # app/controllers/line_controller.rb
88
- builder = Line::MessageBuilder::Builder.with(view_context) do
88
+ builder = Line::Message::Builder.with(view_context) do
89
89
  text "Anything you want?" do
90
90
  quick_reply do
91
91
  message "Yes", label: "Yes", image_url: image_url("yes.png")
@@ -105,7 +105,7 @@ context = ActionView::Base.new(
105
105
  ActionController::Base.new,
106
106
  )
107
107
 
108
- builder = Line::MessageBuilder::Builder.with(context) do
108
+ builder = Line::Message::Builder.with(context) do
109
109
  text "Anything you want?" do
110
110
  quick_reply do
111
111
  message "Yes", label: "Yes", image_url: image_url("yes.png")
@@ -132,7 +132,7 @@ class CardPartial < Line::Message::Builder::Flex::Partial
132
132
  end
133
133
  end
134
134
 
135
- builder = Line::MessageBuilder::Builder.with do
135
+ builder = Line::Message::Builder.with do
136
136
  carousel do
137
137
  3.times do |i|
138
138
  bubble do
@@ -154,7 +154,7 @@ class CardPartial < Line::Message::Builder::Flex::Partial
154
154
  end
155
155
  end
156
156
 
157
- builder = Line::MessageBuilder::Builder.with do
157
+ builder = Line::Message::Builder.with do
158
158
  carousel do
159
159
  3.times do |i|
160
160
  bubble do
@@ -180,6 +180,7 @@ end
180
180
  | `have_line_flex_button` | Match a flex message with button |
181
181
  | `have_line_flex_box` | Match a flex message with box |
182
182
  | `have_line_flex_separator` | Match a flex message with separator |
183
+ | `have_line_flex_icon` | Match a flex message with icon |
183
184
 
184
185
 
185
186
  Add `line/message/rspec` to your `spec_helper.rb` or `rails_helper.rb`:
@@ -200,7 +201,7 @@ Then the matchers are available in your specs:
200
201
 
201
202
  ```ruby
202
203
  let(:builder) do
203
- Line::MessageBuilder::Builder.with do
204
+ Line::Message::Builder.with do
204
205
  text "Hello, world!"
205
206
  text "Nice to meet you!"
206
207
  end
@@ -261,7 +262,7 @@ end
261
262
  | ----------- | --------- |
262
263
  | Postback | 🚧 |
263
264
  | Message | ✅ |
264
- | Uri | |
265
+ | Uri | |
265
266
  | Datetime | ❌ |
266
267
  | Camera | ❌ |
267
268
  | CameraRoll | ❌ |
@@ -275,16 +276,23 @@ end
275
276
  | --------- | --------- |
276
277
  | Bubble | 🚧 |
277
278
  | Carousel | ✅ |
278
- | Box | 🚧 |
279
- | Button | 🚧 |
280
- | Image | 🚧 |
279
+ | Box | |
280
+ | Button | |
281
+ | Image | |
281
282
  | Video | ❌ |
282
- | Icon | |
283
+ | Icon | 🚧 |
283
284
  | Text | 🚧 |
284
- | Span | |
285
+ | Span | 🚧 |
285
286
  | Separator | ✅ |
286
287
  | Filler | ❌ Deprecated |
287
288
 
289
+ Text, Span and Icon are marked partial only because their `size` option accepts
290
+ the `none`–`xxl` keywords and pixel values, while LINE also defines `xxs` and
291
+ `3xl`–`5xl`. Every other property of these components is supported.
292
+
293
+ Bubble is missing `direction` and a bubble-level action. Postback is missing
294
+ `inputOption` and `fillInText`.
295
+
288
296
  ## Development
289
297
 
290
298
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/claudekit.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "rubric": {
3
+ "rules": [
4
+ {
5
+ "name": "RDoc",
6
+ "pattern": "lib/.*\\.rb$",
7
+ "path": "docs/rubrics/rdoc.md"
8
+ }
9
+ ]
10
+ }
11
+ }
@@ -0,0 +1,169 @@
1
+ # RDoc Documentation Rubric
2
+
3
+ This document outlines the criteria for evaluating the quality of RDoc documentation in Ruby code. We assert at least 80% of the criteria must be met to pass.
4
+
5
+ ## Criteria
6
+
7
+ ### Proper RDoc Syntax Usage (1 point)
8
+
9
+ > Enforce correct RDoc markup syntax and avoid YARD-style tags that are not compatible with RDoc
10
+
11
+ ```ruby
12
+ ##
13
+ # The Base class serves as the foundation for all message builder classes
14
+ # within the Line::Message::Builder DSL. It provides core functionality
15
+ # for defining options, handling initialization, and delegating method calls
16
+ # to a context object.
17
+ #
18
+ # == Example
19
+ #
20
+ # class MyBuilder < Base
21
+ # option :color, default: "red"
22
+ # end
23
+ #
24
+ # builder = MyBuilder.new
25
+ # puts builder.color # => "red"
26
+ ```
27
+
28
+ - Use RDoc directives: `:method:`, `:call-seq:`, `:nodoc:`, `:yields:` (not YARD `@param`, `@return`, `@see` tags)
29
+ - Use `==` for major sections (h2), `===` for subsections (h3)
30
+ - Use `[param_name]` for parameter documentation with 2-space indented descriptions
31
+ - Use `+code+` for method names and identifiers, `<code>:symbol</code>` for symbols and string literals
32
+ - Reference external documentation with links: `{Link Text}[URL]`
33
+ - Use `-` for unordered lists
34
+ - Consult [RDoc Markup Reference](https://ruby.github.io/rdoc/RDoc/MarkupReference.html) for details
35
+
36
+ ### Complete Class and Module Documentation (1 point)
37
+
38
+ > Every public class and module must have comprehensive documentation including purpose, usage, and cross-references
39
+
40
+ ```ruby
41
+ # The Text class provides a builder for creating simple text messages
42
+ # in the LINE Messaging API. Text messages are the most basic message type,
43
+ # consisting of plain text content with optional quick reply buttons and
44
+ # quote tokens for replying to specific messages.
45
+ #
46
+ # Text messages support:
47
+ # - Plain text content (up to 5,000 characters)
48
+ # - Quick reply buttons for user interaction
49
+ # - Quote tokens to reply to specific messages in a conversation
50
+ #
51
+ # == Example: Basic text message
52
+ #
53
+ # Line::Message::Builder.with do
54
+ # text "Hello, world!"
55
+ # end
56
+ #
57
+ # See also:
58
+ # - QuickReply
59
+ # - https://developers.line.biz/en/reference/messaging-api/#text-message
60
+ class Text < Base
61
+ ```
62
+
63
+ - Classes must have a purpose statement (what it represents/does)
64
+ - Include feature list using bullet points for complex components
65
+ - Provide at least one complete usage example with proper context
66
+ - Include "See also:" section with related classes and external API documentation links
67
+ - For mixin modules, document what functionality they add to including classes
68
+
69
+ ### Method Documentation with Parameters and Returns (1 point)
70
+
71
+ > All public methods must document their purpose, parameters, and return values clearly
72
+
73
+ ```ruby
74
+ # Defines a new option for the builder class.
75
+ #
76
+ # This method dynamically creates an instance method on the builder class
77
+ # with the given name. When this instance method is called without arguments,
78
+ # it returns the current value; with an argument, it sets the value.
79
+ #
80
+ # [name]
81
+ # The name of the option to define. This will also be the name of the
82
+ # generated instance method.
83
+ # [default]
84
+ # The default value for the option if not explicitly set.
85
+ # [validator]
86
+ # An optional validator object that must respond to +valid!+ method.
87
+ # If the value is invalid, the validator should raise an error.
88
+ #
89
+ # [return]
90
+ # The dynamically created method name as a symbol
91
+ #
92
+ # == Example
93
+ #
94
+ # class MyBuilder < Base
95
+ # option :color, default: "red"
96
+ # option :size, validator: SizeValidator.new
97
+ # end
98
+ def option(name, default: nil, validator: nil)
99
+ ```
100
+
101
+ - Document method purpose in the first paragraph
102
+ - Use `[param_name]` format for each parameter with 2-space indented description
103
+ - Document optional parameters and their default values
104
+ - Include `[block]` documentation if the method accepts a block
105
+ - Use `[return]` label to describe return value for non-obvious returns
106
+ - Use `:nodoc:` directive for private methods and internal implementations
107
+
108
+ ### Dynamic Method Documentation with :method: Directive (1 point)
109
+
110
+ > Dynamically defined methods must be documented using RDoc's :method: and :call-seq: directives
111
+
112
+ ```ruby
113
+ # :method: quote_token
114
+ # :call-seq:
115
+ # quote_token() -> String or nil
116
+ # quote_token(value) -> String
117
+ #
118
+ # Sets or gets the quote token for replying to a specific message.
119
+ #
120
+ # Quote tokens allow your bot to quote and reply to a specific message
121
+ # in the conversation. When set, the original message being replied to
122
+ # will be displayed above the new message.
123
+ #
124
+ # [value]
125
+ # The quote token string obtained from a webhook event
126
+ option :quote_token, default: nil
127
+ ```
128
+
129
+ - Use `:method:` directive to document dynamically defined methods (e.g., from `option`, `attr_accessor`)
130
+ - Use `:call-seq:` to show both getter and setter signatures
131
+ - Show return types using arrow notation: `method_name() -> Type or nil`
132
+ - Document both forms: getter (no arguments) and setter (with argument)
133
+ - Place directive immediately before the line that defines the method
134
+ - Include parameter documentation using `[param_name]` format
135
+
136
+ ### Progressive Examples with Real-World Usage (1 point)
137
+
138
+ > Documentation must include runnable examples that progress from simple to complex use cases
139
+
140
+ ```ruby
141
+ # == Example: Basic text message
142
+ #
143
+ # Line::Message::Builder.with do
144
+ # text "Hello, world!"
145
+ # end
146
+ #
147
+ # === Example: Text with quick reply
148
+ #
149
+ # Line::Message::Builder.with do
150
+ # text "Choose an option:" do
151
+ # quick_reply do
152
+ # button action: :message, label: "Yes", text: "I agree"
153
+ # button action: :message, label: "No", text: "I disagree"
154
+ # end
155
+ # end
156
+ # end
157
+ ```
158
+
159
+ - Provide at least one complete, executable example for public classes
160
+ - Use descriptive example headings: `== Example: Description`
161
+ - Show full DSL context (e.g., `Line::Message::Builder.with do ... end`)
162
+ - Use `===` for sub-examples or variations
163
+ - Include output comments using `# =>` notation where helpful
164
+ - Progress from simple to complex examples
165
+ - Indent code blocks with 2 spaces
166
+
167
+ ## Scoring
168
+
169
+ Each criterion is worth 1 point and is awarded only when fully satisfied. A score below 80% (4 out of 5 points) indicates insufficient documentation quality.
@@ -3,18 +3,19 @@
3
3
  module Line
4
4
  module Message
5
5
  module Builder
6
- # The `Actions` module serves as a namespace for action objects that can be
6
+ # The Actions module serves as a namespace for action objects that can be
7
7
  # associated with various LINE message components, such as buttons in
8
8
  # quick replies or imagemaps. Each class within this module represents a
9
9
  # specific type of action a user can perform.
10
10
  module Actions
11
- # Represents a "message action" for LINE messages.
11
+ # Represents a message action for LINE messages.
12
12
  #
13
13
  # A message action sends a specified text message to the chat from the user
14
14
  # when a button associated with this action is tapped. It's commonly used
15
15
  # in quick replies or other interactive message components.
16
16
  #
17
- # @example Creating a message action for a quick reply button
17
+ # == Example
18
+ #
18
19
  # Line::Message::Builder.with do
19
20
  # text "Select your favorite food:"
20
21
  # quick_reply do
@@ -25,35 +26,46 @@ module Line
25
26
  # end
26
27
  # end
27
28
  #
28
- # @see https://developers.line.biz/en/reference/messaging-api/#message-action
29
+ # See also:
30
+ # - https://developers.line.biz/en/reference/messaging-api/#message-action
29
31
  class Message < Line::Message::Builder::Base
30
- # @!attribute [r] text
31
- # @return [String] The text that is sent as a message from the user
32
- # when the action is performed. This is a required attribute.
32
+ # The text that is sent as a message from the user when the action
33
+ # is performed. This is a required attribute.
33
34
  attr_reader :text
34
35
 
35
- # Defines an optional `label` for the action.
36
+ # :method: label
37
+ # :call-seq:
38
+ # label() -> String or nil
39
+ # label(value) -> String
40
+ #
41
+ # Sets or gets the optional label for the action.
42
+ #
36
43
  # The label is recommended by LINE for accessibility purposes, but it's
37
44
  # not displayed in all LINE versions. For some message types like buttons,
38
45
  # the label of the button itself is used as the action's label.
39
46
  #
40
- # @!method label(value = nil)
41
- # @param value [String, nil] The label text for the action.
42
- # @return [String, nil] The current label text.
47
+ # [value]
48
+ # The label text for the action
43
49
  option :label, default: nil
44
50
 
45
51
  # Initializes a new Message action.
46
52
  #
47
- # @param text [String] The text to be sent when the action is performed.
48
- # This is a required parameter.
49
- # @param context [Object, nil] An optional context object for resolving
50
- # method calls within a block, if one is provided.
51
- # @param options [Hash] A hash of options to set instance variables.
52
- # Can include `:label`.
53
- # @param block [Proc, nil] An optional block to be instance-eval'd.
54
- # While available, it's not commonly used for simple actions like this.
55
- # @raise [RequiredError] if `text` is nil. (This check is done in `to_h`
56
- # but `text` is conceptually required on initialization).
53
+ # [text]
54
+ # The text to be sent when the action is performed (required)
55
+ # [context]
56
+ # An optional context object for resolving method calls within a block
57
+ # [options]
58
+ # A hash of options to set instance variables (can include +:label+)
59
+ # [block]
60
+ # An optional block to be instance-eval'd (not commonly used for simple actions)
61
+ #
62
+ # Raises RequiredError if +text+ is nil (this check is done in +to_h+
63
+ # but text is conceptually required on initialization).
64
+ #
65
+ # == Example
66
+ #
67
+ # action = Message.new("Hello, world!")
68
+ # action = Message.new("Pizza", label: "Select Pizza")
57
69
  def initialize(text, context: nil, **options, &)
58
70
  @text = text
59
71
 
@@ -63,9 +75,18 @@ module Line
63
75
  # Converts the Message action object to a hash suitable for the LINE
64
76
  # Messaging API.
65
77
  #
66
- # @return [Hash] A hash representing the message action.
67
- # Includes `:type`, `:label` (if set), and `:text`.
68
- # @raise [RequiredError] if `text` is nil.
78
+ # The returned hash includes +:type+, +:label+ (if set), and +:text+.
79
+ #
80
+ # Raises RequiredError if +text+ is nil.
81
+ #
82
+ # == Example
83
+ #
84
+ # action = Message.new("Pizza")
85
+ # action.to_h
86
+ # # => { type: "message", text: "Pizza" }
87
+ #
88
+ # [return]
89
+ # A hash representing the message action
69
90
  def to_h
70
91
  raise RequiredError, "text is required" if text.nil?
71
92
 
@@ -76,7 +97,7 @@ module Line
76
97
 
77
98
  private
78
99
 
79
- def to_api
100
+ def to_api # :nodoc:
80
101
  {
81
102
  type: "message",
82
103
  label: label,
@@ -84,7 +105,7 @@ module Line
84
105
  }.compact
85
106
  end
86
107
 
87
- def to_sdkv2
108
+ def to_sdkv2 # :nodoc:
88
109
  {
89
110
  type: "message",
90
111
  label: label,