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.
- checksums.yaml +4 -4
- data/.release-please-manifest.json +1 -1
- data/.rubocop.yml +5 -0
- data/CHANGELOG.md +20 -0
- data/CLAUDE.md +124 -0
- data/README.md +24 -16
- data/claudekit.json +11 -0
- data/docs/rubrics/rdoc.md +169 -0
- data/lib/line/message/builder/actions/message.rb +47 -26
- data/lib/line/message/builder/actions/postback.rb +56 -26
- 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 +55 -60
- data/lib/line/message/builder/context.rb +51 -72
- data/lib/line/message/builder/flex/actionable.rb +53 -32
- data/lib/line/message/builder/flex/box.rb +342 -79
- data/lib/line/message/builder/flex/bubble.rb +73 -46
- data/lib/line/message/builder/flex/builder.rb +39 -28
- data/lib/line/message/builder/flex/button.rb +90 -42
- data/lib/line/message/builder/flex/carousel.rb +48 -20
- data/lib/line/message/builder/flex/icon.rb +152 -0
- data/lib/line/message/builder/flex/image.rb +95 -33
- data/lib/line/message/builder/flex/partial.rb +47 -49
- data/lib/line/message/builder/flex/position.rb +187 -100
- data/lib/line/message/builder/flex/separator.rb +49 -6
- data/lib/line/message/builder/flex/size.rb +67 -47
- data/lib/line/message/builder/flex/span.rb +106 -32
- data/lib/line/message/builder/flex/text.rb +166 -54
- data/lib/line/message/builder/flex.rb +26 -23
- 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 +14 -11
- data/lib/line/message/rspec/matchers/have_flex_bubble.rb +1 -1
- data/lib/line/message/rspec/matchers/have_flex_component.rb +16 -6
- data/lib/line/message/rspec/matchers/have_flex_message.rb +1 -1
- data/lib/line/message/rspec/matchers/have_flex_separator.rb +1 -1
- 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/llm.txt +276 -35
- data/release-please-config.json +3 -1
- metadata +9 -3
|
@@ -4,18 +4,19 @@ module Line
|
|
|
4
4
|
module Message
|
|
5
5
|
module Builder
|
|
6
6
|
module Actions
|
|
7
|
-
# Represents a
|
|
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
|
|
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
|
-
#
|
|
18
|
+
# == Example
|
|
19
|
+
#
|
|
19
20
|
# Line::Message::Builder.with do
|
|
20
21
|
# text "What do you want to do?"
|
|
21
22
|
# quick_reply do
|
|
@@ -26,39 +27,61 @@ module Line
|
|
|
26
27
|
# end
|
|
27
28
|
# end
|
|
28
29
|
#
|
|
29
|
-
#
|
|
30
|
+
# See also:
|
|
31
|
+
# - https://developers.line.biz/en/reference/messaging-api/#postback-action
|
|
30
32
|
class Postback < Line::Message::Builder::Base
|
|
31
|
-
#
|
|
32
|
-
#
|
|
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
|
-
#
|
|
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
|
-
#
|
|
41
|
-
#
|
|
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
|
+
# :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
|
-
#
|
|
50
|
-
#
|
|
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
|
-
#
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
#
|
|
60
|
-
#
|
|
61
|
-
#
|
|
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
|
-
#
|
|
71
|
-
#
|
|
72
|
-
#
|
|
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
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
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
|
|
@@ -3,53 +3,49 @@
|
|
|
3
3
|
module Line
|
|
4
4
|
module Message
|
|
5
5
|
module Builder
|
|
6
|
-
# The
|
|
7
|
-
# within the
|
|
6
|
+
# The Base class serves as the foundation for all message builder classes
|
|
7
|
+
# within the Line::Message::Builder DSL. It provides core functionality
|
|
8
8
|
# for defining options, handling initialization, and delegating method calls
|
|
9
9
|
# to a context object.
|
|
10
10
|
#
|
|
11
11
|
# This class is not typically used directly but is inherited by specific
|
|
12
|
-
# message type builders (e.g.,
|
|
12
|
+
# message type builders (e.g., Text, Flex::Builder).
|
|
13
13
|
class Base
|
|
14
14
|
class << self
|
|
15
|
-
#
|
|
16
|
-
# @!parse extend ClassMethods
|
|
17
|
-
def inherited(subclass)
|
|
15
|
+
def inherited(subclass) # :nodoc:
|
|
18
16
|
super
|
|
19
17
|
subclass.extend ClassMethods
|
|
20
18
|
end
|
|
21
19
|
end
|
|
22
20
|
|
|
23
|
-
# The
|
|
24
|
-
# inherits from
|
|
21
|
+
# The ClassMethods module is automatically extended by any class that
|
|
22
|
+
# inherits from Base. It provides class-level methods for defining
|
|
25
23
|
# DSL options and configurations.
|
|
26
24
|
module ClassMethods
|
|
27
|
-
|
|
28
|
-
# using the {option} method.
|
|
29
|
-
#
|
|
30
|
-
# @return [Array<Symbol>] A list of defined option names.
|
|
31
|
-
# @!visibility private
|
|
32
|
-
def options
|
|
25
|
+
def options # :nodoc:
|
|
33
26
|
@options ||= []
|
|
34
27
|
end
|
|
35
28
|
|
|
36
29
|
# Defines a new option for the builder class.
|
|
30
|
+
#
|
|
37
31
|
# This method dynamically creates an instance method on the builder class
|
|
38
|
-
# with the given
|
|
32
|
+
# with the given name. When this instance method is called:
|
|
39
33
|
# - Without arguments, it returns the current value of the option, or
|
|
40
|
-
# the
|
|
41
|
-
# - With an argument, it sets the value of the option. If a
|
|
34
|
+
# the default value if not set.
|
|
35
|
+
# - With an argument, it sets the value of the option. If a validator
|
|
42
36
|
# is provided, the value is validated before being set.
|
|
43
37
|
#
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
#
|
|
38
|
+
# [name]
|
|
39
|
+
# The name of the option to define. This will also be the name of the
|
|
40
|
+
# generated instance method.
|
|
41
|
+
# [default]
|
|
42
|
+
# The default value for the option if not explicitly set.
|
|
43
|
+
# [validator]
|
|
44
|
+
# An optional validator object that must respond to +valid!+ method.
|
|
45
|
+
# If the value is invalid, the validator should raise an error.
|
|
46
|
+
#
|
|
47
|
+
# == Example
|
|
48
|
+
#
|
|
53
49
|
# class MyBuilder < Base
|
|
54
50
|
# option :color, default: "red"
|
|
55
51
|
# option :size, validator: SizeValidator.new
|
|
@@ -74,24 +70,39 @@ module Line
|
|
|
74
70
|
end
|
|
75
71
|
end
|
|
76
72
|
|
|
73
|
+
# The context object used for method delegation.
|
|
74
|
+
#
|
|
75
|
+
# When methods are called on the builder that it doesn't respond to,
|
|
76
|
+
# they are delegated to this context object if it responds to them.
|
|
77
|
+
# This allows accessing helper methods and variables from the surrounding
|
|
78
|
+
# environment within the builder DSL.
|
|
77
79
|
attr_reader :context
|
|
78
80
|
|
|
79
81
|
# Initializes a new instance of a builder class.
|
|
80
82
|
#
|
|
81
|
-
#
|
|
82
|
-
# Methods not defined in the builder
|
|
83
|
-
# if it responds to them. This allows
|
|
84
|
-
# accessing data from the surrounding environment
|
|
85
|
-
#
|
|
86
|
-
#
|
|
87
|
-
#
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
# is
|
|
83
|
+
# [context]
|
|
84
|
+
# An optional external context object. Methods not defined in the builder
|
|
85
|
+
# will be delegated to this context if it responds to them. This allows
|
|
86
|
+
# for using helper methods or accessing data from the surrounding environment
|
|
87
|
+
# within the builder DSL.
|
|
88
|
+
# [options]
|
|
89
|
+
# A hash of options to set on the builder instance. These options are
|
|
90
|
+
# typically defined using the +option+ method in the builder class.
|
|
91
|
+
# [block]
|
|
92
|
+
# An optional block that is instance-eval'd within the new builder instance.
|
|
93
|
+
# This is the primary way the DSL is used to define message content.
|
|
94
|
+
#
|
|
95
|
+
# == Example
|
|
96
|
+
#
|
|
97
|
+
# builder = MyBuilder.new(context: view_context) do
|
|
98
|
+
# text "Hello from context"
|
|
99
|
+
# end
|
|
91
100
|
def initialize(context: nil, **options, &block)
|
|
92
101
|
@context = context
|
|
93
102
|
@quick_reply = nil
|
|
94
103
|
|
|
104
|
+
validate_options!(options)
|
|
105
|
+
|
|
95
106
|
self.class.options.each do |option|
|
|
96
107
|
send(option, options[option]) if options.key?(option)
|
|
97
108
|
end
|
|
@@ -100,15 +111,17 @@ module Line
|
|
|
100
111
|
end
|
|
101
112
|
|
|
102
113
|
# Defines a quick reply for the message.
|
|
114
|
+
#
|
|
103
115
|
# A quick reply consists of a set of buttons that are displayed along
|
|
104
116
|
# with the message, allowing users to make quick responses.
|
|
105
117
|
#
|
|
106
|
-
# The provided block is executed in the context of a new
|
|
118
|
+
# The provided block is executed in the context of a new QuickReply
|
|
107
119
|
# instance, where you can define the quick reply buttons.
|
|
108
120
|
#
|
|
109
|
-
#
|
|
110
|
-
#
|
|
111
|
-
#
|
|
121
|
+
# :yields: quick_reply
|
|
122
|
+
#
|
|
123
|
+
# == Example
|
|
124
|
+
#
|
|
112
125
|
# text_message do
|
|
113
126
|
# text "Please choose an option:"
|
|
114
127
|
# quick_reply do
|
|
@@ -120,34 +133,11 @@ module Line
|
|
|
120
133
|
@quick_reply = QuickReply.new(context: context, &)
|
|
121
134
|
end
|
|
122
135
|
|
|
123
|
-
|
|
124
|
-
# checking if the context object can respond to it.
|
|
125
|
-
# This is part of Ruby's mechanism for `method_missing` and is used
|
|
126
|
-
# here to enable delegation to the `context` object.
|
|
127
|
-
#
|
|
128
|
-
# @param method_name [Symbol] The name of the method.
|
|
129
|
-
# @param include_private [Boolean] Whether to include private methods
|
|
130
|
-
# in the search.
|
|
131
|
-
# @return [Boolean] `true` if the builder or its context can respond to
|
|
132
|
-
# the method, `false` otherwise.
|
|
133
|
-
# @!visibility private
|
|
134
|
-
def respond_to_missing?(method_name, include_private = false)
|
|
136
|
+
def respond_to_missing?(method_name, include_private = false) # :nodoc:
|
|
135
137
|
context.respond_to?(method_name, include_private) || super
|
|
136
138
|
end
|
|
137
139
|
|
|
138
|
-
|
|
139
|
-
# `context` object. If the `context` object responds to the method,
|
|
140
|
-
# it is called. Otherwise, it behaves like the standard `method_missing`.
|
|
141
|
-
# This allows the DSL to feel more integrated with the surrounding code
|
|
142
|
-
# by making methods from the `context` directly available within the
|
|
143
|
-
# builder block.
|
|
144
|
-
#
|
|
145
|
-
# @param method_name [Symbol] The name of the missing method.
|
|
146
|
-
# @param ... [Object] Arguments passed to the method.
|
|
147
|
-
# @raise [NoMethodError] If neither the builder nor the context can
|
|
148
|
-
# handle the method call.
|
|
149
|
-
# @!visibility private
|
|
150
|
-
def method_missing(method_name, ...)
|
|
140
|
+
def method_missing(method_name, ...) # :nodoc:
|
|
151
141
|
if context.respond_to?(method_name)
|
|
152
142
|
context.public_send(method_name, ...)
|
|
153
143
|
else
|
|
@@ -155,6 +145,20 @@ module Line
|
|
|
155
145
|
end
|
|
156
146
|
end
|
|
157
147
|
|
|
148
|
+
# Converts the builder to a hash representation.
|
|
149
|
+
#
|
|
150
|
+
# The format of the hash depends on the mode (API or SDK v2) determined
|
|
151
|
+
# by the builder's configuration. Subclasses must implement +to_api+ and
|
|
152
|
+
# +to_sdkv2+ methods to provide the actual conversion logic.
|
|
153
|
+
#
|
|
154
|
+
# [return]
|
|
155
|
+
# A hash representation of the message in the appropriate format.
|
|
156
|
+
#
|
|
157
|
+
# == Example
|
|
158
|
+
#
|
|
159
|
+
# builder = Text.new { text "Hello" }
|
|
160
|
+
# builder.to_h
|
|
161
|
+
# # => { type: "text", text: "Hello" }
|
|
158
162
|
def to_h
|
|
159
163
|
return to_sdkv2 if sdkv2?
|
|
160
164
|
|
|
@@ -163,11 +167,32 @@ module Line
|
|
|
163
167
|
|
|
164
168
|
private
|
|
165
169
|
|
|
166
|
-
|
|
170
|
+
# Rejects options the builder does not declare.
|
|
171
|
+
#
|
|
172
|
+
# An undeclared option is almost always a typo or a property the LINE API
|
|
173
|
+
# spells differently. Ignoring it produces a message that is silently
|
|
174
|
+
# missing the styling that was asked for, which nothing downstream can
|
|
175
|
+
# detect, so it is refused here instead.
|
|
176
|
+
#
|
|
177
|
+
# [options]
|
|
178
|
+
# The hash of options passed to the constructor
|
|
179
|
+
#
|
|
180
|
+
# Raises ValidationError listing the unknown option and the ones this
|
|
181
|
+
# builder accepts.
|
|
182
|
+
def validate_options!(options) # :nodoc:
|
|
183
|
+
unknown = options.keys - self.class.options
|
|
184
|
+
return if unknown.empty?
|
|
185
|
+
|
|
186
|
+
raise ValidationError,
|
|
187
|
+
"Unknown option: #{unknown.join(", ")} for #{self.class}. " \
|
|
188
|
+
"Allowed options are: #{self.class.options.join(", ")}"
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def to_api # :nodoc:
|
|
167
192
|
raise NotImplementedError, "#{self.class} must implement #to_api"
|
|
168
193
|
end
|
|
169
194
|
|
|
170
|
-
def to_sdkv2
|
|
195
|
+
def to_sdkv2 # :nodoc:
|
|
171
196
|
raise NotImplementedError, "#{self.class} must implement #to_sdkv2"
|
|
172
197
|
end
|
|
173
198
|
end
|