line-message-builder 0.8.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.
- checksums.yaml +4 -4
- data/.release-please-manifest.json +1 -1
- data/.rubocop.yml +5 -0
- data/CHANGELOG.md +41 -0
- data/CLAUDE.md +124 -0
- data/CONVENTIONS.md +36 -0
- data/README.md +61 -43
- data/claudekit.json +11 -0
- data/docs/rubrics/rdoc.md +169 -0
- data/lib/line/message/builder/actions/message.rb +52 -31
- data/lib/line/message/builder/actions/postback.rb +63 -33
- data/lib/line/message/builder/actions/uri.rb +139 -0
- data/lib/line/message/builder/actions.rb +6 -3
- data/lib/line/message/builder/base.rb +92 -67
- data/lib/line/message/builder/container.rb +64 -69
- data/lib/line/message/builder/context.rb +55 -80
- data/lib/line/message/builder/flex/actionable.rb +53 -32
- data/lib/line/message/builder/flex/box.rb +366 -79
- data/lib/line/message/builder/flex/bubble.rb +78 -51
- data/lib/line/message/builder/flex/builder.rb +47 -36
- data/lib/line/message/builder/flex/button.rb +96 -48
- data/lib/line/message/builder/flex/carousel.rb +57 -29
- data/lib/line/message/builder/flex/icon.rb +152 -0
- data/lib/line/message/builder/flex/image.rb +103 -42
- data/lib/line/message/builder/flex/partial.rb +58 -55
- data/lib/line/message/builder/flex/position.rb +187 -100
- data/lib/line/message/builder/flex/separator.rb +84 -0
- data/lib/line/message/builder/flex/size.rb +67 -47
- data/lib/line/message/builder/flex/span.rb +184 -0
- data/lib/line/message/builder/flex/text.rb +210 -54
- data/lib/line/message/builder/flex.rb +31 -26
- data/lib/line/message/builder/quick_reply.rb +174 -4
- data/lib/line/message/builder/text.rb +70 -3
- data/lib/line/message/builder/version.rb +1 -1
- data/lib/line/message/builder.rb +16 -13
- data/lib/line/message/rspec/matchers/have_flex_bubble.rb +1 -1
- data/lib/line/message/rspec/matchers/have_flex_component.rb +26 -5
- data/lib/line/message/rspec/matchers/have_flex_message.rb +1 -1
- data/lib/line/message/rspec/matchers/have_flex_separator.rb +20 -0
- data/lib/line/message/rspec/matchers/have_quick_reply.rb +1 -1
- data/lib/line/message/rspec/matchers/have_text_message.rb +1 -1
- data/lib/line/message/rspec/matchers.rb +1 -0
- data/llm.txt +367 -45
- data/release-please-config.json +3 -1
- metadata +12 -3
data/llm.txt
CHANGED
|
@@ -2,6 +2,49 @@
|
|
|
2
2
|
|
|
3
3
|
This document provides a comprehensive guide on using the Line Message Builder DSL to construct various types of LINE messages.
|
|
4
4
|
|
|
5
|
+
## Project Status
|
|
6
|
+
|
|
7
|
+
**Current State:** Production-ready Ruby gem with comprehensive Flex Message support. Consult the Component Support Status below before using a property — anything not listed is not implemented, and an undeclared option raises.
|
|
8
|
+
|
|
9
|
+
### Recent Major Updates
|
|
10
|
+
- **Unknown options now raise**: passing an option a component does not declare raises `ValidationError` instead of being silently dropped
|
|
11
|
+
- **URI action**: link a component to a web page without a webhook
|
|
12
|
+
- **Icon component**: icon-and-text pairs inside a baseline box
|
|
13
|
+
- **Text styling**: `weight`, `max_lines`, `style`, `decoration`, `scaling`
|
|
14
|
+
- **Box appearance**: background colour, border, corner radius and linear gradients
|
|
15
|
+
- **Button `color` and `scaling`**; Button no longer accepts `padding` (LINE defines none)
|
|
16
|
+
- **Image `background_color` and `animated`**; **Span `style`**; **Separator `margin` and `color`**
|
|
17
|
+
|
|
18
|
+
### Component Support Status
|
|
19
|
+
|
|
20
|
+
Anything not listed as supported below is not implemented. There is no raw-hash
|
|
21
|
+
escape hatch — an undeclared option raises.
|
|
22
|
+
|
|
23
|
+
- **Text Messages**: supported, with Quick Reply
|
|
24
|
+
- **Flex Containers**: Bubble, Carousel
|
|
25
|
+
- **Flex Components**: Box, Text, Span, Button, Image, Icon, Separator
|
|
26
|
+
- **Actions**: `message`, `postback`, `uri`
|
|
27
|
+
- **Quick Replies**: supported (`message`, `postback`, `uri`)
|
|
28
|
+
- **Partials**: supported
|
|
29
|
+
- **RSpec Matchers**: text, flex message, bubble, box, text, button, image, icon, span, separator, quick reply
|
|
30
|
+
|
|
31
|
+
**Not supported yet**: the `video` component; `Bubble#direction` and a bubble-level
|
|
32
|
+
action; the Datetime Picker, Camera, Camera Roll, Location, Rich Menu Switch and
|
|
33
|
+
Clipboard actions.
|
|
34
|
+
|
|
35
|
+
**Deliberately not supported**: the `filler` component — LINE has deprecated it.
|
|
36
|
+
Use the spacing properties of each component instead.
|
|
37
|
+
|
|
38
|
+
## Installation and Setup
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Add to Gemfile
|
|
42
|
+
bundle add line-message-builder
|
|
43
|
+
|
|
44
|
+
# Or install directly
|
|
45
|
+
gem install line-message-builder
|
|
46
|
+
```
|
|
47
|
+
|
|
5
48
|
## Basic Usage
|
|
6
49
|
|
|
7
50
|
To start building messages, use the `Line::Message::Builder.with` method. This method accepts an optional context object and a block where you define your messages.
|
|
@@ -15,9 +58,72 @@ end
|
|
|
15
58
|
|
|
16
59
|
# The `messages` variable will now hold an array of LINE message objects.
|
|
17
60
|
# You can convert them to JSON for sending to the LINE API:
|
|
18
|
-
|
|
61
|
+
json_output = messages.to_json
|
|
62
|
+
|
|
63
|
+
# For LINE Bot SDK v2 compatibility:
|
|
64
|
+
messages = Line::Message::Builder.with(mode: :sdkv2) do
|
|
65
|
+
text "Hello World!"
|
|
66
|
+
end
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Coding Style
|
|
70
|
+
|
|
71
|
+
When using the `Line::Message::Builder` DSL, following is recommended:
|
|
72
|
+
|
|
73
|
+
```ruby
|
|
74
|
+
Line::Message::Builder.with do
|
|
75
|
+
flex alt_text: "Hello, World!" do
|
|
76
|
+
bubble do
|
|
77
|
+
header do
|
|
78
|
+
text "Welcome to LINE Messaging API"
|
|
79
|
+
end
|
|
80
|
+
body do
|
|
81
|
+
text "This is a sample message."
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
DO NOT use `do |container|` syntax as following:
|
|
89
|
+
|
|
90
|
+
```ruby
|
|
91
|
+
Line::Message::Builder.with do |builder|
|
|
92
|
+
builder.flex alt_text: "Hello, World!" do
|
|
93
|
+
builder.bubble do
|
|
94
|
+
builder.header do
|
|
95
|
+
builder.text "Welcome to LINE Messaging API"
|
|
96
|
+
end
|
|
97
|
+
builder.body do
|
|
98
|
+
builder.text "This is a sample message."
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
19
103
|
```
|
|
20
104
|
|
|
105
|
+
### Unknown Options Raise
|
|
106
|
+
|
|
107
|
+
Every component accepts only the options it declares. Passing anything else
|
|
108
|
+
raises `Line::Message::Builder::ValidationError`, naming the offending option and
|
|
109
|
+
listing the ones that component accepts:
|
|
110
|
+
|
|
111
|
+
```ruby
|
|
112
|
+
text "Title", colour: "#FF0000"
|
|
113
|
+
# => Line::Message::Builder::ValidationError:
|
|
114
|
+
# Unknown option: colour for Line::Message::Builder::Flex::Text.
|
|
115
|
+
# Allowed options are: wrap, line_spacing, color, weight, max_lines, ...
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
This is deliberate. A misspelled or unsupported property used to be dropped in
|
|
119
|
+
silence, producing a message that was missing the styling that was asked for
|
|
120
|
+
while every check downstream reported success. Read the error, correct the
|
|
121
|
+
option name against the list it prints, and rebuild.
|
|
122
|
+
|
|
123
|
+
Two consequences worth remembering:
|
|
124
|
+
- There is no `action:` option on any component. Declare actions inside the block.
|
|
125
|
+
- A `button` has no `label` option. The label belongs to its action.
|
|
126
|
+
|
|
21
127
|
### Context
|
|
22
128
|
|
|
23
129
|
The builder can accept a context object. Methods called within the builder block will first attempt to resolve against this context object. This allows for dynamic message content based on your application's data.
|
|
@@ -79,40 +185,69 @@ You can also include emojis in text messages. A `quick_reply` can be attached (s
|
|
|
79
185
|
|
|
80
186
|
Actions define what happens when a user interacts with a button or a tappable area in a message. They are used in Flex Message components (like buttons, or even entire boxes/images) and Quick Reply buttons.
|
|
81
187
|
|
|
82
|
-
|
|
188
|
+
**An action is declared inside the component's block, not passed as an `action:` keyword.** No component accepts an `action:` option; writing one raises `ValidationError`.
|
|
189
|
+
|
|
190
|
+
Three action types are supported: `message`, `postback` and `uri`.
|
|
83
191
|
|
|
84
192
|
### Message Action
|
|
85
193
|
Sends a text message from the user's perspective.
|
|
86
|
-
-
|
|
87
|
-
- `
|
|
194
|
+
- First argument: (String, Required) The text message to be sent when tapped.
|
|
195
|
+
- `label`: (String, Optional) The text displayed on the button.
|
|
88
196
|
|
|
89
197
|
```ruby
|
|
90
|
-
#
|
|
91
|
-
button
|
|
198
|
+
# In a Flex component — declared inside the block
|
|
199
|
+
button do
|
|
200
|
+
message "Hello there!", label: "Say Hello"
|
|
201
|
+
end
|
|
92
202
|
|
|
93
|
-
#
|
|
94
|
-
# For quick reply, the first argument to `message` is the text to be sent.
|
|
203
|
+
# In a Quick Reply — label is required here
|
|
95
204
|
quick_reply do
|
|
96
|
-
message "Yes, please!", label: "Yes"
|
|
205
|
+
message "Yes, please!", label: "Yes"
|
|
97
206
|
end
|
|
98
207
|
```
|
|
99
208
|
|
|
100
209
|
### Postback Action
|
|
101
|
-
Sends a postback event to your bot's webhook.
|
|
102
|
-
-
|
|
103
|
-
- `
|
|
104
|
-
- `display_text`: (String, Optional) Text displayed in the chat as if the user had typed it
|
|
210
|
+
Sends a postback event to your bot's webhook. Useful for triggering backend logic without displaying a message in the chat. A postback whose event your webhook does not handle is a dead button.
|
|
211
|
+
- First argument: (String, Required) The data string sent in the postback event.
|
|
212
|
+
- `label`: (String, Optional) The text displayed on the button.
|
|
213
|
+
- `display_text`: (String, Optional) Text displayed in the chat as if the user had typed it.
|
|
105
214
|
|
|
106
215
|
```ruby
|
|
107
|
-
#
|
|
108
|
-
button
|
|
216
|
+
# In a Flex component
|
|
217
|
+
button do
|
|
218
|
+
postback "action=add_item&item_id=101", label: "Add to Cart", display_text: "Added to cart!"
|
|
219
|
+
end
|
|
109
220
|
|
|
110
|
-
#
|
|
221
|
+
# In a Quick Reply
|
|
111
222
|
quick_reply do
|
|
112
223
|
postback "action=view_profile", label: "View Profile"
|
|
113
224
|
end
|
|
114
225
|
```
|
|
115
|
-
|
|
226
|
+
|
|
227
|
+
### URI Action
|
|
228
|
+
Opens a URI when tapped. Needs no webhook handling, so this is the action to use for linking a card to a web page.
|
|
229
|
+
- First argument: (String, Required) The URI to open. Schemes `http`, `https`, `line`, `tel`. Max 1000 characters.
|
|
230
|
+
- `label`: (String, Optional in Flex, Required in Quick Reply) The text displayed on the button.
|
|
231
|
+
- `alt_uri_desktop`: (String, Optional) A different URI opened on LINE for macOS and Windows. Maps to `altUri.desktop`. Has no effect in a Quick Reply.
|
|
232
|
+
|
|
233
|
+
```ruby
|
|
234
|
+
# In a Flex component
|
|
235
|
+
button style: :primary do
|
|
236
|
+
uri "https://example.com/event", label: "View event"
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# Opening a different page on desktop
|
|
240
|
+
button do
|
|
241
|
+
uri "https://example.com/mobile", label: "Open", alt_uri_desktop: "https://example.com/desktop"
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# In a Quick Reply
|
|
245
|
+
quick_reply do
|
|
246
|
+
uri "tel:+81312345678", label: "Call us"
|
|
247
|
+
end
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
The remaining LINE action types (Datetime Picker, Camera, Camera Roll, Location, Rich Menu Switch, Clipboard) are **not yet supported**. There is no raw-hash escape hatch.
|
|
116
251
|
|
|
117
252
|
## Quick Replies
|
|
118
253
|
|
|
@@ -206,7 +341,9 @@ flex alt_text: "Recipe Card" do
|
|
|
206
341
|
end
|
|
207
342
|
end
|
|
208
343
|
footer do
|
|
209
|
-
button
|
|
344
|
+
button style: :primary do
|
|
345
|
+
uri "https://example.com/recipe", label: "View Recipe"
|
|
346
|
+
end
|
|
210
347
|
end
|
|
211
348
|
end
|
|
212
349
|
end
|
|
@@ -232,13 +369,29 @@ A `box` arranges other components.
|
|
|
232
369
|
- Sizing:
|
|
233
370
|
- `width`, `max_width`, `height`, `max_height`: (String, Optional) Pixel or percentage strings (e.g., `'100px'`, `'50%'`).
|
|
234
371
|
- `flex`: (Integer, Optional) Flex factor determining how much space this box takes relative to siblings.
|
|
235
|
-
-
|
|
372
|
+
- Appearance:
|
|
373
|
+
- `background_color`: (String, Optional) Hex colour, alpha channel allowed (e.g., `'#RRGGBBAA'`).
|
|
374
|
+
- `border_color`: (String, Optional) Hex colour of the border.
|
|
375
|
+
- `border_width`: (Symbol or String, Optional) `:none`, `:light`, `:normal`, `:medium`, `:"semi-bold"`, `:bold`, or a pixel value.
|
|
376
|
+
- `corner_radius`: (Symbol or String, Optional) `:none`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`, or a pixel value.
|
|
377
|
+
- `background_angle`, `background_start_color`, `background_end_color`: (String, Optional) A linear gradient. Setting any one of them makes all three required, otherwise a `RequiredError` is raised.
|
|
378
|
+
- `background_center_color`, `background_center_position`: (String, Optional) An intermediate colour stop, e.g. `'#00FF00'` at `'30%'`.
|
|
379
|
+
- Tappable: declare an action inside the block to make the whole box tappable.
|
|
236
380
|
|
|
237
381
|
```ruby
|
|
238
|
-
box layout: :vertical, spacing: :md, padding_all: :lg
|
|
382
|
+
box layout: :vertical, spacing: :md, padding_all: :lg do
|
|
383
|
+
message "Box tapped!", label: "Open"
|
|
239
384
|
text "Item 1"
|
|
240
385
|
text "Item 2"
|
|
241
386
|
end
|
|
387
|
+
|
|
388
|
+
# A rounded card with a gradient background
|
|
389
|
+
box layout: :vertical, corner_radius: :lg, padding_all: :lg,
|
|
390
|
+
background_angle: "90deg",
|
|
391
|
+
background_start_color: "#3F51B5",
|
|
392
|
+
background_end_color: "#2196F3" do
|
|
393
|
+
text "Gradient card", color: "#FFFFFF", weight: :bold
|
|
394
|
+
end
|
|
242
395
|
```
|
|
243
396
|
|
|
244
397
|
#### Text Component
|
|
@@ -248,35 +401,65 @@ Displays text.
|
|
|
248
401
|
- `wrap`: (Boolean, Optional) `true` to allow text to wrap. Default `false`.
|
|
249
402
|
- `line_spacing`: (String, Optional) Spacing between lines, e.g., `'4px'`, `'1.5em'`.
|
|
250
403
|
- `color`: (String, Optional) Hex color code (e.g., `'#RRGGBB'`, `'#RRGGBBAA'`).
|
|
404
|
+
- `weight`: (Symbol, Optional) `:regular` (default) or `:bold`.
|
|
405
|
+
- `style`: (Symbol, Optional) `:normal` (default) or `:italic`.
|
|
406
|
+
- `decoration`: (Symbol, Optional) `:none` (default), `:underline` or `:"line-through"`. A decoration set here cannot be overridden by a nested span.
|
|
407
|
+
- `max_lines`: (Integer, Optional) Truncate after this many lines with an ellipsis. `0` (default) shows the whole text.
|
|
408
|
+
- `scaling`: (Boolean, Optional) `true` to follow the reader's LINE font size setting. Nested spans scale too.
|
|
251
409
|
- Layout:
|
|
252
410
|
- `align`: (Symbol, Optional) Horizontal alignment of the text. Valid values: `:start`, `:center`, `:end`.
|
|
253
411
|
- `gravity`: (Symbol, Optional) Vertical alignment of the text within its allocated space. Valid values: `:top`, `:center`, `:bottom`.
|
|
254
412
|
- `margin`: (Symbol or String, Optional) Margin around the text component. Valid keywords: `:none`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`. Also accepts pixel values (e.g., `'10px'`).
|
|
255
413
|
- Sizing:
|
|
256
|
-
- `size`: (Symbol or String, Optional) Font size.
|
|
257
|
-
- `weight`: (Symbol, Optional) Font weight. Valid values: `:regular`, `:bold`.
|
|
414
|
+
- `size`: (Symbol or String, Optional) Font size. Accepted keywords: `:none`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`, or a pixel value (e.g., `'16px'`). Note: LINE also defines `:xxs` and `:3xl`–`:5xl`, but this gem does not accept them yet.
|
|
258
415
|
- `flex`: (Integer, Optional) Flex factor.
|
|
259
416
|
- `adjust_mode`: (Symbol, Optional) How text adjusts when it overflows. Valid value: `:shrink_to_fit` (reduces font size).
|
|
260
|
-
-
|
|
417
|
+
- Tappable: declare an action inside the block.
|
|
418
|
+
- `span`: Within a Text component, you can add Span components to style parts of the text differently.
|
|
261
419
|
|
|
262
420
|
```ruby
|
|
263
|
-
|
|
421
|
+
# Simple text component
|
|
422
|
+
text "Special Offer!", size: :xl, weight: :bold, color: "#FF0000", align: :center
|
|
423
|
+
|
|
424
|
+
# Truncating a long body
|
|
425
|
+
text article_body, wrap: true, max_lines: 3
|
|
426
|
+
|
|
427
|
+
# Making the text tappable
|
|
428
|
+
text "See details" do
|
|
429
|
+
postback "offer_details", label: "Details"
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
# Text with spans for different styling of segments
|
|
433
|
+
text "Welcome to our service:" do
|
|
434
|
+
span "Special ", color: "#FF0000"
|
|
435
|
+
span "Offer", weight: :bold
|
|
436
|
+
span "!", decoration: :underline
|
|
437
|
+
end
|
|
264
438
|
```
|
|
265
439
|
|
|
266
440
|
#### Button Component
|
|
267
|
-
An actionable button.
|
|
268
|
-
- `action`: (Action Object, **Required**) Defines the action performed on tap. See Actions section.
|
|
441
|
+
An actionable button. **The action is declared inside the block and is required.** The button's visible text comes from the action's `label`; a button has no `label` option of its own.
|
|
269
442
|
- `style`: (Symbol, Optional) Visual style of the button. Valid values: `:primary`, `:secondary`, `:link`. Default is `:link`.
|
|
443
|
+
- `color`: (String, Optional) Hex colour. Text colour when `style` is `:link`, background colour when `:primary` or `:secondary`.
|
|
270
444
|
- `height`: (Symbol, Optional) Height of the button. Valid values: `:sm`, `:md`. Default is `:md`.
|
|
445
|
+
- `scaling`: (Boolean, Optional) `true` to follow the reader's LINE font size setting.
|
|
271
446
|
- Layout:
|
|
272
447
|
- `gravity`: (Symbol, Optional) Vertical alignment if the box containing it has extra space. Valid values: `:top`, `:center`, `:bottom`.
|
|
273
448
|
- `margin`: (Symbol or String, Optional) Margin around the button. Valid keywords: `:none`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`. Also accepts pixel values (e.g., `'10px'`).
|
|
274
449
|
- Sizing:
|
|
275
450
|
- `flex`: (Integer, Optional) Flex factor.
|
|
276
451
|
- `adjust_mode`: (Symbol, Optional) How the button adjusts its content. Valid value: `:shrink_to_fit`.
|
|
452
|
+
- **No padding**: LINE defines no padding properties for a button. Pad the surrounding box instead.
|
|
277
453
|
|
|
278
454
|
```ruby
|
|
279
|
-
button
|
|
455
|
+
button style: :primary, color: "#1DB446" do
|
|
456
|
+
postback "action=confirm_order", label: "Confirm"
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
# Linking to a web page
|
|
460
|
+
button style: :link do
|
|
461
|
+
uri "https://example.com/event", label: "View event"
|
|
462
|
+
end
|
|
280
463
|
```
|
|
281
464
|
|
|
282
465
|
#### Image Component
|
|
@@ -285,6 +468,8 @@ Displays an image.
|
|
|
285
468
|
- Styling:
|
|
286
469
|
- `aspect_ratio`: (String, Optional) Aspect ratio as `"width:height"`, e.g., `"1:1"`, `"16:9"`, `"4:3"`.
|
|
287
470
|
- `aspect_mode`: (Symbol, Optional) How the image fits the `aspect_ratio`. Valid values: `:cover` (default, crops to fill) or `:fit` (fits within, may letterbox).
|
|
471
|
+
- `background_color`: (String, Optional) Hex colour shown behind the image.
|
|
472
|
+
- `animated`: (Boolean, Optional) `true` plays an APNG. At most 10 animated images per message; frames over 300 KB are not played.
|
|
288
473
|
- Layout:
|
|
289
474
|
- `align`: (Symbol, Optional) Horizontal alignment of the image. Valid values: `:start`, `:center`, `:end`.
|
|
290
475
|
- `gravity`: (Symbol, Optional) Vertical alignment of the image. Valid values: `:top`, `:center`, `:bottom`.
|
|
@@ -292,29 +477,95 @@ Displays an image.
|
|
|
292
477
|
- Sizing:
|
|
293
478
|
- `size`: (Symbol or String, Optional) Size of the image. Valid keywords: `:xxs`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`, `:3xl`, `:4xl`, `:5xl`, `:full`. Also accepts pixel or percentage strings (e.g. `'100px'`, `'50%'`).
|
|
294
479
|
- `flex`: (Integer, Optional) Flex factor.
|
|
295
|
-
-
|
|
480
|
+
- Tappable: declare an action inside the block.
|
|
296
481
|
|
|
297
482
|
```ruby
|
|
298
|
-
image "https://example.com/product_image.png", size: :full, aspect_ratio: "1:1", aspect_mode: :cover
|
|
483
|
+
image "https://example.com/product_image.png", size: :full, aspect_ratio: "1:1", aspect_mode: :cover
|
|
484
|
+
|
|
485
|
+
# Making the image tappable
|
|
486
|
+
image "https://example.com/product_image.png", size: :full do
|
|
487
|
+
uri "https://example.com/product", label: "View product"
|
|
488
|
+
end
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
#### Icon Component
|
|
492
|
+
An `icon` renders a small graphic that decorates the text beside it — rating stars, labelled metadata rows. **It can only be used inside a box whose `layout` is `:baseline`.** An icon takes no action and no `flex`.
|
|
493
|
+
|
|
494
|
+
- `url`: (String, Required) URL of the icon image (HTTPS).
|
|
495
|
+
- `size`: (Symbol or String, Optional) Icon width. Same keywords as text size. Default `:md`.
|
|
496
|
+
- `aspect_ratio`: (String, Optional) `"width:height"`, default `"1:1"`.
|
|
497
|
+
- `scaling`: (Boolean, Optional) `true` to follow the reader's LINE font size setting.
|
|
498
|
+
- `margin`, `position`, `offset_top`, `offset_bottom`, `offset_start`, `offset_end`: as for other components.
|
|
499
|
+
|
|
500
|
+
```ruby
|
|
501
|
+
box layout: :baseline do
|
|
502
|
+
icon "https://example.com/star_on.png", size: :sm
|
|
503
|
+
icon "https://example.com/star_on.png", size: :sm
|
|
504
|
+
icon "https://example.com/star_off.png", size: :sm
|
|
505
|
+
text "3.0", size: :sm, margin: :md
|
|
506
|
+
end
|
|
299
507
|
```
|
|
300
508
|
|
|
301
|
-
####
|
|
509
|
+
#### Span Component
|
|
510
|
+
Spans are used within a Text component to apply different styling to specific portions of text. They cannot be used directly within boxes or other containers; they must be placed inside a Text component block.
|
|
302
511
|
|
|
303
|
-
|
|
512
|
+
- `text`: (String, Required) The text content of the span.
|
|
513
|
+
- Styling:
|
|
514
|
+
- `color`: (String, Optional) Hex color code (e.g., `'#RRGGBB'`, `'#RRGGBBAA'`).
|
|
515
|
+
- `size`: (Symbol or String, Optional) Font size. Accepted keywords: `:none`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`, or a pixel value (e.g., `'16px'`).
|
|
516
|
+
- `weight`: (Symbol, Optional) Font weight. Valid values: `:regular`, `:bold`.
|
|
517
|
+
- `style`: (Symbol, Optional) `:normal` (default) or `:italic`.
|
|
518
|
+
- `decoration`: (Symbol, Optional) Text decoration. Valid values: `:none`, `:underline`, `:"line-through"`. Ignored when the surrounding text sets its own `decoration`.
|
|
519
|
+
|
|
520
|
+
Spans also support helper methods to easily apply common styles:
|
|
521
|
+
- `bold!`: Sets the weight to `:bold`.
|
|
522
|
+
- `italic!`: Sets the style to `:italic`.
|
|
523
|
+
- `underline!`: Sets the decoration to `:underline`.
|
|
524
|
+
- `line_through!`: Sets the decoration to `:line-through`.
|
|
304
525
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
526
|
+
```ruby
|
|
527
|
+
# Basic span usage
|
|
528
|
+
text "This message contains:" do
|
|
529
|
+
span "colored", color: "#FF0000"
|
|
530
|
+
span " and "
|
|
531
|
+
span "bold", weight: :bold
|
|
532
|
+
span " text."
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
# Using helper methods
|
|
536
|
+
text "This message has:" do
|
|
537
|
+
span "underlined" do
|
|
538
|
+
underline!
|
|
539
|
+
end
|
|
540
|
+
span " and "
|
|
541
|
+
span "bold" do
|
|
542
|
+
bold!
|
|
312
543
|
end
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
544
|
+
span " text."
|
|
545
|
+
end
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
#### Separator Component
|
|
549
|
+
A `separator` draws a horizontal line to create visual separation between components. LINE defines exactly three properties for it; nothing else is accepted.
|
|
550
|
+
|
|
551
|
+
- `margin`: (Symbol or String, Optional) Space before the line. Keywords `:none`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:xxl`, or a pixel value.
|
|
552
|
+
- `color`: (String, Optional) Hex colour of the line.
|
|
553
|
+
|
|
554
|
+
```ruby
|
|
555
|
+
box layout: :vertical do
|
|
556
|
+
text "Section 1"
|
|
557
|
+
separator margin: :xl, color: "#F0F0F0"
|
|
558
|
+
text "Section 2"
|
|
559
|
+
end
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
#### Spacers
|
|
563
|
+
Create space between components using:
|
|
564
|
+
- `spacing` property on a parent `box` container.
|
|
565
|
+
- `margin` property on individual components (e.g., `text "Hello", margin: :xl`).
|
|
566
|
+
- An empty `box` with a defined `flex` value or `height`/`width` (e.g., `box height: "30px"`).
|
|
567
|
+
|
|
568
|
+
Do not reach for a `filler` component — LINE has deprecated it and this gem does not provide one.
|
|
318
569
|
|
|
319
570
|
### Flex Message Partials
|
|
320
571
|
|
|
@@ -329,7 +580,9 @@ Partials allow you to define reusable segments of Flex Message layouts. This is
|
|
|
329
580
|
# which are made available from the `assigns` hash passed to `partial!`.
|
|
330
581
|
box layout: :vertical do
|
|
331
582
|
text title_text, weight: :bold # 'title_text' from assigns
|
|
332
|
-
button
|
|
583
|
+
button do # 'button_label' from assigns
|
|
584
|
+
message "Action for #{title_text}", label: button_label
|
|
585
|
+
end
|
|
333
586
|
end
|
|
334
587
|
end
|
|
335
588
|
end
|
|
@@ -353,4 +606,73 @@ Partials allow you to define reusable segments of Flex Message layouts. This is
|
|
|
353
606
|
```
|
|
354
607
|
Inside the partial, variables passed via `partial!` (e.g., `title_text`, `button_label`) are accessible as methods.
|
|
355
608
|
|
|
356
|
-
|
|
609
|
+
## RSpec Testing Support
|
|
610
|
+
|
|
611
|
+
The gem includes comprehensive RSpec matchers for testing LINE messages:
|
|
612
|
+
|
|
613
|
+
```ruby
|
|
614
|
+
# Include in spec_helper.rb or rails_helper.rb
|
|
615
|
+
require "line/message/rspec"
|
|
616
|
+
|
|
617
|
+
# Configure in RSpec
|
|
618
|
+
RSpec.configure do |config|
|
|
619
|
+
config.include Line::Message::RSpec::Matchers
|
|
620
|
+
end
|
|
621
|
+
|
|
622
|
+
# Available matchers
|
|
623
|
+
describe "LINE Messages" do
|
|
624
|
+
let(:builder) do
|
|
625
|
+
Line::Message::Builder.with do
|
|
626
|
+
text "Hello World!"
|
|
627
|
+
flex alt_text: "Greeting" do
|
|
628
|
+
bubble do
|
|
629
|
+
body { text "Welcome!" }
|
|
630
|
+
end
|
|
631
|
+
end
|
|
632
|
+
end
|
|
633
|
+
end
|
|
634
|
+
|
|
635
|
+
subject { builder.build }
|
|
636
|
+
|
|
637
|
+
it { is_expected.to have_line_text_message("Hello World!") }
|
|
638
|
+
it { is_expected.to have_line_flex_message }
|
|
639
|
+
it { is_expected.to have_line_flex_bubble }
|
|
640
|
+
it { is_expected.to have_line_flex_text("Welcome!") }
|
|
641
|
+
it { is_expected.to have_line_flex_separator }
|
|
642
|
+
it { is_expected.to have_line_flex_span }
|
|
643
|
+
it { is_expected.to have_line_flex_icon("https://example.com/star.png") }
|
|
644
|
+
|
|
645
|
+
# Works with webmock for API testing
|
|
646
|
+
it "sends correct message" do
|
|
647
|
+
expect(a_request(:post, "https://api.line.me/v2/bot/message/reply")
|
|
648
|
+
.with(body: hash_including({
|
|
649
|
+
messages: have_line_text_message(/Hello World!/)
|
|
650
|
+
}))
|
|
651
|
+
).to have_been_made.once
|
|
652
|
+
end
|
|
653
|
+
end
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
## Development and Testing
|
|
657
|
+
|
|
658
|
+
```bash
|
|
659
|
+
# Run tests
|
|
660
|
+
bundle exec rspec
|
|
661
|
+
|
|
662
|
+
# Run specific test
|
|
663
|
+
bundle exec rspec spec/line/message/builder_spec.rb
|
|
664
|
+
|
|
665
|
+
# Run linter
|
|
666
|
+
bundle exec rubocop
|
|
667
|
+
|
|
668
|
+
# Run both tests and linter
|
|
669
|
+
bundle exec rake
|
|
670
|
+
|
|
671
|
+
# Interactive console
|
|
672
|
+
bin/console
|
|
673
|
+
|
|
674
|
+
# Build and install locally
|
|
675
|
+
bundle exec rake install
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
This comprehensive guide should help in effectively using the Line Message Builder DSL. The gem is actively maintained and production-ready for building complex LINE messaging experiences. For very specific or advanced features, always refer to the official LINE Messaging API documentation for Flex Messages.
|
data/release-please-config.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"release-type": "ruby",
|
|
3
|
+
"bump-minor-pre-major": true,
|
|
3
4
|
"packages": {
|
|
4
5
|
".":{
|
|
5
6
|
"component": "line-message-builder",
|
|
6
7
|
"include-component-in-tag": false,
|
|
7
|
-
"release-type": "ruby"
|
|
8
|
+
"release-type": "ruby",
|
|
9
|
+
"bump-minor-pre-major": true
|
|
8
10
|
}
|
|
9
11
|
}
|
|
10
12
|
}
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: line-message-builder
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.10.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Aotokitsuruya
|
|
@@ -14,21 +14,26 @@ email:
|
|
|
14
14
|
- contact@aotoki.me
|
|
15
15
|
executables: []
|
|
16
16
|
extensions: []
|
|
17
|
-
extra_rdoc_files:
|
|
17
|
+
extra_rdoc_files:
|
|
18
|
+
- README.md
|
|
18
19
|
files:
|
|
19
20
|
- ".document"
|
|
20
21
|
- ".release-please-manifest.json"
|
|
21
22
|
- ".rspec"
|
|
22
23
|
- ".rubocop.yml"
|
|
23
24
|
- CHANGELOG.md
|
|
25
|
+
- CLAUDE.md
|
|
24
26
|
- CONVENTIONS.md
|
|
25
27
|
- LICENSE.txt
|
|
26
28
|
- README.md
|
|
27
29
|
- Rakefile
|
|
30
|
+
- claudekit.json
|
|
31
|
+
- docs/rubrics/rdoc.md
|
|
28
32
|
- lib/line/message/builder.rb
|
|
29
33
|
- lib/line/message/builder/actions.rb
|
|
30
34
|
- lib/line/message/builder/actions/message.rb
|
|
31
35
|
- lib/line/message/builder/actions/postback.rb
|
|
36
|
+
- lib/line/message/builder/actions/uri.rb
|
|
32
37
|
- lib/line/message/builder/base.rb
|
|
33
38
|
- lib/line/message/builder/container.rb
|
|
34
39
|
- lib/line/message/builder/context.rb
|
|
@@ -39,10 +44,13 @@ files:
|
|
|
39
44
|
- lib/line/message/builder/flex/builder.rb
|
|
40
45
|
- lib/line/message/builder/flex/button.rb
|
|
41
46
|
- lib/line/message/builder/flex/carousel.rb
|
|
47
|
+
- lib/line/message/builder/flex/icon.rb
|
|
42
48
|
- lib/line/message/builder/flex/image.rb
|
|
43
49
|
- lib/line/message/builder/flex/partial.rb
|
|
44
50
|
- lib/line/message/builder/flex/position.rb
|
|
51
|
+
- lib/line/message/builder/flex/separator.rb
|
|
45
52
|
- lib/line/message/builder/flex/size.rb
|
|
53
|
+
- lib/line/message/builder/flex/span.rb
|
|
46
54
|
- lib/line/message/builder/flex/text.rb
|
|
47
55
|
- lib/line/message/builder/quick_reply.rb
|
|
48
56
|
- lib/line/message/builder/text.rb
|
|
@@ -55,6 +63,7 @@ files:
|
|
|
55
63
|
- lib/line/message/rspec/matchers/have_flex_bubble.rb
|
|
56
64
|
- lib/line/message/rspec/matchers/have_flex_component.rb
|
|
57
65
|
- lib/line/message/rspec/matchers/have_flex_message.rb
|
|
66
|
+
- lib/line/message/rspec/matchers/have_flex_separator.rb
|
|
58
67
|
- lib/line/message/rspec/matchers/have_quick_reply.rb
|
|
59
68
|
- lib/line/message/rspec/matchers/have_text_message.rb
|
|
60
69
|
- lib/line/message/rspec/matchers/utils.rb
|
|
@@ -83,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
83
92
|
- !ruby/object:Gem::Version
|
|
84
93
|
version: '0'
|
|
85
94
|
requirements: []
|
|
86
|
-
rubygems_version:
|
|
95
|
+
rubygems_version: 4.0.16
|
|
87
96
|
specification_version: 4
|
|
88
97
|
summary: The LINE Messaging API message builder.
|
|
89
98
|
test_files: []
|