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.
Files changed (45) 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 +41 -0
  5. data/CLAUDE.md +124 -0
  6. data/CONVENTIONS.md +36 -0
  7. data/README.md +61 -43
  8. data/claudekit.json +11 -0
  9. data/docs/rubrics/rdoc.md +169 -0
  10. data/lib/line/message/builder/actions/message.rb +52 -31
  11. data/lib/line/message/builder/actions/postback.rb +63 -33
  12. data/lib/line/message/builder/actions/uri.rb +139 -0
  13. data/lib/line/message/builder/actions.rb +6 -3
  14. data/lib/line/message/builder/base.rb +92 -67
  15. data/lib/line/message/builder/container.rb +64 -69
  16. data/lib/line/message/builder/context.rb +55 -80
  17. data/lib/line/message/builder/flex/actionable.rb +53 -32
  18. data/lib/line/message/builder/flex/box.rb +366 -79
  19. data/lib/line/message/builder/flex/bubble.rb +78 -51
  20. data/lib/line/message/builder/flex/builder.rb +47 -36
  21. data/lib/line/message/builder/flex/button.rb +96 -48
  22. data/lib/line/message/builder/flex/carousel.rb +57 -29
  23. data/lib/line/message/builder/flex/icon.rb +152 -0
  24. data/lib/line/message/builder/flex/image.rb +103 -42
  25. data/lib/line/message/builder/flex/partial.rb +58 -55
  26. data/lib/line/message/builder/flex/position.rb +187 -100
  27. data/lib/line/message/builder/flex/separator.rb +84 -0
  28. data/lib/line/message/builder/flex/size.rb +67 -47
  29. data/lib/line/message/builder/flex/span.rb +184 -0
  30. data/lib/line/message/builder/flex/text.rb +210 -54
  31. data/lib/line/message/builder/flex.rb +31 -26
  32. data/lib/line/message/builder/quick_reply.rb +174 -4
  33. data/lib/line/message/builder/text.rb +70 -3
  34. data/lib/line/message/builder/version.rb +1 -1
  35. data/lib/line/message/builder.rb +16 -13
  36. data/lib/line/message/rspec/matchers/have_flex_bubble.rb +1 -1
  37. data/lib/line/message/rspec/matchers/have_flex_component.rb +26 -5
  38. data/lib/line/message/rspec/matchers/have_flex_message.rb +1 -1
  39. data/lib/line/message/rspec/matchers/have_flex_separator.rb +20 -0
  40. data/lib/line/message/rspec/matchers/have_quick_reply.rb +1 -1
  41. data/lib/line/message/rspec/matchers/have_text_message.rb +1 -1
  42. data/lib/line/message/rspec/matchers.rb +1 -0
  43. data/llm.txt +367 -45
  44. data/release-please-config.json +3 -1
  45. metadata +12 -3
@@ -3,57 +3,69 @@
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
18
- # Line::Message::Builder.with do |root|
19
- # root.text "Select your favorite food:"
20
- # root.quick_reply do |qr|
17
+ # == Example
18
+ #
19
+ # Line::Message::Builder.with do
20
+ # text "Select your favorite food:"
21
+ # quick_reply do
21
22
  # # When this button is tapped, the user sends "Pizza"
22
- # qr.button action: :message, label: "Pizza", text: "Pizza"
23
+ # button action: :message, label: "Pizza", text: "Pizza"
23
24
  # # When this button is tapped, the user sends "Sushi"
24
- # qr.button action: :message, label: "Sushi", text: "Sushi"
25
+ # button action: :message, label: "Sushi", text: "Sushi"
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,
@@ -4,61 +4,84 @@ module Line
4
4
  module Message
5
5
  module Builder
6
6
  module Actions
7
- # Represents a "postback action" for LINE messages.
7
+ # Represents a postback action for LINE messages.
8
8
  #
9
9
  # A postback action sends a postback event to your bot's webhook when a
10
10
  # button associated with this action is tapped. The event contains the
11
- # specified `data` payload. Optionally, `displayText` can be provided,
11
+ # specified +data+ payload. Optionally, +display_text+ can be provided,
12
12
  # which will be shown in the chat as a message from the user.
13
13
  #
14
14
  # This action is useful for triggering specific backend logic or flows
15
15
  # without necessarily displaying a message in the chat, or for displaying
16
16
  # a different message than the data payload.
17
17
  #
18
- # @example Creating a postback action for a quick reply button
19
- # Line::Message::Builder.with do |root|
20
- # root.text "What do you want to do?"
21
- # root.quick_reply do |qr|
22
- # qr.button action: :postback,
23
- # label: "Track Order",
24
- # data: "action=track_order&order_id=123",
25
- # display_text: "I want to track my order."
18
+ # == Example
19
+ #
20
+ # Line::Message::Builder.with do
21
+ # text "What do you want to do?"
22
+ # quick_reply do
23
+ # button action: :postback,
24
+ # label: "Track Order",
25
+ # data: "action=track_order&order_id=123",
26
+ # display_text: "I want to track my order."
26
27
  # end
27
28
  # end
28
29
  #
29
- # @see https://developers.line.biz/en/reference/messaging-api/#postback-action
30
+ # See also:
31
+ # - https://developers.line.biz/en/reference/messaging-api/#postback-action
30
32
  class Postback < Line::Message::Builder::Base
31
- # @!attribute [r] data
32
- # @return [String] The data payload to be sent in the postback event
33
- # to the webhook. This is a required attribute. Max 300 characters.
33
+ # The data payload to be sent in the postback event to the webhook.
34
+ # This is a required attribute. Max 300 characters.
34
35
  attr_reader :data
35
36
 
36
- # Defines an optional `label` for the action.
37
+ # :method: label
38
+ # :call-seq:
39
+ # label() -> String or nil
40
+ # label(value) -> String or nil
41
+ #
42
+ # Sets or gets the label for the action.
43
+ #
37
44
  # The label is recommended by LINE for accessibility. For some message
38
45
  # types (e.g., buttons), the button's label itself is used.
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
- # Defines an optional `displayText` for the action.
51
+ # :method: display_text
52
+ # :call-seq:
53
+ # display_text() -> String or nil
54
+ # display_text(value) -> String or nil
55
+ #
56
+ # Sets or gets the display text for the action.
57
+ #
46
58
  # This is the text that will be displayed in the chat as a message from
47
59
  # the user when the action is performed. If not set, no message is displayed.
48
60
  #
49
- # @!method display_text(value = nil)
50
- # @param value [String, nil] The text to display in the chat. Max 300 characters.
51
- # @return [String, nil] The current display text.
61
+ # [value]
62
+ # The text to display in the chat (max 300 characters)
52
63
  option :display_text, default: nil
53
64
 
54
65
  # Initializes a new Postback action.
55
66
  #
56
- # @param data [String] The data to be sent in the postback event. This is required.
57
- # @param context [Object, nil] An optional context object.
58
- # @param options [Hash] Options for the action, including `:label` and `:display_text`.
59
- # @param block [Proc, nil] An optional block for instance_eval.
60
- # @raise [RequiredError] if `data` is nil. (This check is done in `to_h`
61
- # but `data` is conceptually required on initialization).
67
+ # [data]
68
+ # The data to be sent in the postback event (required)
69
+ # [context]
70
+ # An optional context object (default: +nil+)
71
+ # [options]
72
+ # Options for the action, including +:label+ and +:display_text+
73
+ #
74
+ # Raises RequiredError if +data+ is +nil+ (this check is done in +to_h+
75
+ # but +data+ is conceptually required on initialization).
76
+ #
77
+ # == Example
78
+ #
79
+ # postback = Postback.new(
80
+ # "action=buy&item=123",
81
+ # context: view_context,
82
+ # label: "Buy Now",
83
+ # display_text: "I want to buy this item"
84
+ # )
62
85
  def initialize(data, context: nil, **options, &)
63
86
  @data = data
64
87
 
@@ -67,9 +90,16 @@ module Line
67
90
 
68
91
  # Converts the Postback action object to a hash suitable for the LINE Messaging API.
69
92
  #
70
- # @return [Hash] A hash representing the postback action.
71
- # Includes `:type`, `:label` (if set), `:data`, and `:displayText` (if set).
72
- # @raise [RequiredError] if `data` is nil.
93
+ # Returns a hash representing the postback action, including +:type+, +:label+
94
+ # (if set), +:data+, and +:displayText+ (if set).
95
+ #
96
+ # Raises RequiredError if +data+ is +nil+.
97
+ #
98
+ # == Example
99
+ #
100
+ # postback = Postback.new("action=track", label: "Track Order")
101
+ # postback.to_h
102
+ # # => { type: "postback", label: "Track Order", data: "action=track" }
73
103
  def to_h
74
104
  raise RequiredError, "data is required" if data.nil?
75
105
 
@@ -80,7 +110,7 @@ module Line
80
110
 
81
111
  private
82
112
 
83
- def to_api
113
+ def to_api # :nodoc:
84
114
  {
85
115
  type: "postback",
86
116
  label: label,
@@ -89,7 +119,7 @@ module Line
89
119
  }.compact
90
120
  end
91
121
 
92
- def to_sdkv2
122
+ def to_sdkv2 # :nodoc:
93
123
  {
94
124
  type: "postback",
95
125
  label: label,
@@ -0,0 +1,139 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Line
4
+ module Message
5
+ module Builder
6
+ module Actions
7
+ # Represents a URI action for LINE messages.
8
+ #
9
+ # A URI action opens the given URI when the component it is attached to is
10
+ # tapped. Unlike Postback, it needs no webhook handling, which makes it the
11
+ # action to reach for when a component should simply link somewhere.
12
+ #
13
+ # The available schemes are +http+, +https+, +line+ and +tel+.
14
+ #
15
+ # A separate URI can be opened on desktop by setting +alt_uri_desktop+,
16
+ # which maps to the <code>altUri.desktop</code> property. When it is set,
17
+ # LINE for macOS and Windows ignores +uri+. This is supported in Flex
18
+ # Messages but has no effect in a quick reply.
19
+ #
20
+ # == Example: Linking a Flex button to a web page
21
+ #
22
+ # Line::Message::Builder.with do
23
+ # flex alt_text: "Event" do
24
+ # bubble do
25
+ # footer do
26
+ # button style: :primary do
27
+ # uri "https://example.com/event", label: "View event"
28
+ # end
29
+ # end
30
+ # end
31
+ # end
32
+ # end
33
+ #
34
+ # === Example: Opening a different page on desktop
35
+ #
36
+ # uri "https://example.com/mobile",
37
+ # label: "Open",
38
+ # alt_uri_desktop: "https://example.com/desktop"
39
+ #
40
+ # See also:
41
+ # - https://developers.line.biz/en/reference/messaging-api/#uri-action
42
+ class Uri < Line::Message::Builder::Base
43
+ # The URI opened when the action is performed. This is a required
44
+ # attribute. Max 1000 characters.
45
+ attr_reader :uri
46
+
47
+ # :method: label
48
+ # :call-seq:
49
+ # label() -> String or nil
50
+ # label(value) -> String or nil
51
+ #
52
+ # Sets or gets the label for the action.
53
+ #
54
+ # [value]
55
+ # The label text for the action
56
+ option :label, default: nil
57
+
58
+ # :method: alt_uri_desktop
59
+ # :call-seq:
60
+ # alt_uri_desktop() -> String or nil
61
+ # alt_uri_desktop(value) -> String or nil
62
+ #
63
+ # Sets or gets the URI opened on LINE for macOS and Windows, mapping to
64
+ # the <code>altUri.desktop</code> property. Has no effect in a quick reply.
65
+ #
66
+ # [value]
67
+ # The desktop URI (max 1000 characters)
68
+ option :alt_uri_desktop, default: nil
69
+
70
+ # Initializes a new Uri action.
71
+ #
72
+ # [uri]
73
+ # The URI to open when the action is performed (required)
74
+ # [context]
75
+ # An optional context object (default: +nil+)
76
+ # [options]
77
+ # Options for the action, including +:label+ and +:alt_uri_desktop+
78
+ # [block]
79
+ # An optional block to be instance-eval'd
80
+ #
81
+ # == Example
82
+ #
83
+ # Uri.new("https://example.com", label: "Open")
84
+ def initialize(uri, context: nil, **options, &)
85
+ @uri = uri
86
+
87
+ super(context: context, **options, &)
88
+ end
89
+
90
+ # Converts the Uri action object to a hash suitable for the LINE
91
+ # Messaging API.
92
+ #
93
+ # Raises RequiredError if +uri+ is +nil+.
94
+ #
95
+ # == Example
96
+ #
97
+ # Uri.new("https://example.com", label: "Open").to_h
98
+ # # => { type: "uri", label: "Open", uri: "https://example.com" }
99
+ #
100
+ # [return]
101
+ # A hash representing the URI action
102
+ def to_h
103
+ raise RequiredError, "uri is required" if uri.nil?
104
+
105
+ return to_sdkv2 if context.sdkv2?
106
+
107
+ to_api
108
+ end
109
+
110
+ private
111
+
112
+ def to_api # :nodoc:
113
+ {
114
+ type: "uri",
115
+ label: label,
116
+ uri: uri,
117
+ altUri: alt_uri
118
+ }.compact
119
+ end
120
+
121
+ def to_sdkv2 # :nodoc:
122
+ {
123
+ type: "uri",
124
+ label: label,
125
+ uri: uri,
126
+ alt_uri: alt_uri
127
+ }.compact
128
+ end
129
+
130
+ def alt_uri # :nodoc:
131
+ return if alt_uri_desktop.nil?
132
+
133
+ { desktop: alt_uri_desktop }
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
@@ -18,12 +18,15 @@ module Line
18
18
  # and consistent way to create and manage different types of interactive
19
19
  # elements in messages.
20
20
  #
21
- # @see Line::Message::Builder::Actions::Message
22
- # @see Line::Message::Builder::Actions::Postback
23
- # @see https://developers.line.biz/en/reference/messaging-api/#action-objects
21
+ # See also:
22
+ # - Actions::Message
23
+ # - Actions::Postback
24
+ # - Actions::Uri
25
+ # - https://developers.line.biz/en/reference/messaging-api/#action-objects
24
26
  module Actions
25
27
  require_relative "actions/message"
26
28
  require_relative "actions/postback"
29
+ require_relative "actions/uri"
27
30
  end
28
31
  end
29
32
  end