line-message-builder 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 37235cb021f9418afaad94d10737c24c596203d412f9bccf8024caaec829bc2e
4
+ data.tar.gz: 0fb0fd5faf9b3c56a8c2a08d4dc72f39fa36b540a8e5f72f57358a392b7efe11
5
+ SHA512:
6
+ metadata.gz: aac9d97a2edb4d90059f76d8716d768af138dbb411d65f3d16057da227be00ab6b8dd26af09ac96c4ee476f8b30343922b6294e9e4956155ad38f237b5fa4020
7
+ data.tar.gz: fedb66cb7216b45ba2afebe70b9acb5fd1a7fa428f9b2508601229239ac5bd4004e842324432b787dd752474805a68d9e40354b02170352cbbf3d2c4aa80d5e0
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,14 @@
1
+ plugins:
2
+ - rubocop-rake
3
+ - rubocop-rspec
4
+
5
+ AllCops:
6
+ TargetRubyVersion: 3.1
7
+ NewCops: enable
8
+ SuggestExtensions: false
9
+
10
+ Style/StringLiterals:
11
+ EnforcedStyle: double_quotes
12
+
13
+ Style/StringLiteralsInInterpolation:
14
+ EnforcedStyle: double_quotes
data/CONVENTIONS.md ADDED
@@ -0,0 +1,45 @@
1
+ # Coding Guideline
2
+
3
+ These are coding guidelines that should be followed when writing code for this gem.
4
+
5
+ ## Introduction
6
+
7
+ This gem is designed to provide DSL (Domain Specific Language) for building LINE messaging API reply messages.
8
+
9
+ ## Naming Conventions
10
+
11
+ - Use `snake_case` for method names and variable names.
12
+ - Use `CamelCase` for class names.
13
+ - Use `UPPER_SNAKE_CASE` for constants.
14
+
15
+ ## Comments
16
+
17
+ Only use comments for RDoc documentation. Do not use comments to explain anything in the code. The code should be self-explanatory. If you find yourself needing to write a comment to explain something, consider refactoring the code instead.
18
+
19
+ ## RSpec
20
+
21
+ - Write feature tests instead of unit tests, use `Line::Message::Builder` as test subject to verify the behavior of the DSL.
22
+ - Don't require any files in your spec files. RSpec will automatically require the necessary files for you.
23
+ - Each example should only have one assertion.
24
+ - Prefer `it { is_expected.to ... }` over `expect(...)` syntax.
25
+ - Use `subject` to define the object under test.
26
+ ```ruby
27
+ describe "#build" do
28
+ subject { builder.build }
29
+ end
30
+ ```
31
+ - Use `let` to override the subject if needed.
32
+ ```ruby
33
+ let(:builder) { described_class.new }
34
+ ```
35
+
36
+ - Name subject if needed.
37
+ ```ruby
38
+ subject(:builder) { described_class.new }
39
+
40
+ describe "#build" do
41
+ subject { builder.build }
42
+
43
+ it { is_expected.to be_a Array }
44
+ end
45
+ ```
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Aotokitsuruya
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # LINE Message Builder
2
+
3
+ Build LINE messages using DSL (Domain Specific Language) in Ruby.
4
+
5
+ ## Installation
6
+
7
+ Install the gem and add to the application's Gemfile by executing:
8
+
9
+ ```bash
10
+ bundle add line-message-builder
11
+ ```
12
+
13
+ If bundler is not being used to manage dependencies, install the gem by executing:
14
+
15
+ ```bash
16
+ gem install line-message-builder
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ > [!NOTE]
22
+ > Working in progress.
23
+
24
+ ### Builder
25
+
26
+ ```ruby
27
+ builder = Line::MessageBuilder::Builder.new do
28
+ text "Hello, world!"
29
+ end
30
+
31
+ pp builder.build
32
+ # => [{ type: "text", text: "Hello, world!" }]
33
+
34
+ puts builder.to_json
35
+ # => {"type":"text","text":"Hello, world!"}
36
+ ```
37
+
38
+ ### Context
39
+
40
+ The context can make `Builder` to access additional methods and variables.
41
+
42
+ ```ruby
43
+ context = OpenStruct.new(
44
+ name: "John Doe",
45
+ )
46
+
47
+ builder = Line::MessageBuilder::Builder.new(context) do
48
+ text "Hello, #{name}!"
49
+ end
50
+
51
+ pp builder.build
52
+ # => [{ type: "text", text: "Hello, John Doe!" }]
53
+
54
+ puts builder.to_json
55
+ # => {"type":"text","text":"Hello, John Doe!"}
56
+ ```
57
+
58
+ For Rails, you can use `view_context` to make `Builder` to access Rails helpers.
59
+
60
+ ```ruby
61
+ # app/controllers/line_controller.rb
62
+ builder = Line::MessageBuilder::Builder.new(view_context) do
63
+ text "Anything you want?" do
64
+ quick_reply do
65
+ action "Yes", label: "Yes", image_url: image_url("yes.png")
66
+ action "No", label: "No", image_url: image_url("no.png")
67
+ end
68
+ end
69
+ end
70
+ ```
71
+
72
+ If not in controller, you can create a `ActionView::Base` instance and pass it to `Builder`.
73
+
74
+ ```ruby
75
+ # app/presenters/line_presenter.rb
76
+ context = ActionView::Base.new(
77
+ ActionController::Base.view_paths,
78
+ {},
79
+ ActionController::Base.new,
80
+ )
81
+
82
+ builder = Line::MessageBuilder::Builder.new(context) do
83
+ text "Anything you want?" do
84
+ quick_reply do
85
+ action "Yes", label: "Yes", image_url: context.image_url("yes.png")
86
+ action "No", label: "No", image_url: context.image_url("no.png")
87
+ end
88
+ end
89
+ end
90
+ ```
91
+
92
+ ## Capabilities
93
+
94
+ ### Message Types
95
+
96
+ | Type | Supported |
97
+ | ---- | --------- |
98
+ | Text | ✅ |
99
+ | Text v2 | ❌ |
100
+ | Sticker | ❌ |
101
+ | Sticker | ❌ |
102
+ | Image | ❌ |
103
+ | Video | ❌ |
104
+ | Audio | ❌ |
105
+ | Location | ❌ |
106
+ | Imagemap | ❌ |
107
+ | Template | ❌ |
108
+ | Flex | ❌ |
109
+
110
+ ### Actions
111
+
112
+ | Action Type | Supported |
113
+ | ----------- | --------- |
114
+ | Postback | ✅ |
115
+ | Message | ✅ |
116
+ | Uri | ❌ |
117
+ | Datetime | ❌ |
118
+ | Camera | ❌ |
119
+ | CameraRoll | ❌ |
120
+ | Location | ❌ |
121
+ | Richmenu Switch | ❌ |
122
+ | Clipboard | ❌ |
123
+
124
+ ## Development
125
+
126
+ 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.
127
+
128
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
129
+
130
+ ## Contributing
131
+
132
+ Bug reports and pull requests are welcome on GitHub at https://github.com/elct9620/line-message-builder.
133
+
134
+ ## License
135
+
136
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Line
4
+ module Message
5
+ class Builder
6
+ module Actions
7
+ # The Message class is used to build message actions for quick replies.
8
+ class Message < Line::Message::Builder::Base
9
+ def initialize(text: nil, label: nil, context: nil, &)
10
+ @text = text
11
+ @label = label
12
+
13
+ super(context: context, &)
14
+ end
15
+
16
+ def label(label)
17
+ @label = label
18
+ end
19
+
20
+ def text(text)
21
+ @text = text
22
+ end
23
+
24
+ def to_h
25
+ {
26
+ type: "message",
27
+ label: @label,
28
+ text: @text
29
+ }.compact
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Line
4
+ module Message
5
+ class Builder
6
+ module Actions
7
+ # The Postback class is used to build postback actions for quick replies.
8
+ class Postback < Line::Message::Builder::Base
9
+ def initialize(data: nil, label: nil, display_text: nil, context: nil, &)
10
+ @data = data
11
+ @label = label
12
+ @display_text = display_text
13
+
14
+ super(context: context, &)
15
+ end
16
+
17
+ def label(label)
18
+ @label = label
19
+ end
20
+
21
+ def data(data)
22
+ @data = data
23
+ end
24
+
25
+ def display_text(display_text)
26
+ @display_text = display_text
27
+ end
28
+
29
+ def to_h
30
+ {
31
+ type: "postback",
32
+ label: @label,
33
+ data: @data,
34
+ displayText: @display_text
35
+ }.compact
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Line
4
+ module Message
5
+ class Builder
6
+ # The actions module contains classes for building different types of actions
7
+ module Actions
8
+ require_relative "actions/message"
9
+ require_relative "actions/postback"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Line
4
+ module Message
5
+ class Builder
6
+ # The base class to provide DSL functionality.
7
+ class Base
8
+ attr_reader :context
9
+
10
+ def initialize(context: nil, &block)
11
+ @context = context
12
+
13
+ instance_eval(&block) if ::Kernel.block_given?
14
+ end
15
+
16
+ def respond_to_missing?(method_name, include_private = false)
17
+ context.respond_to?(method_name, include_private) || super
18
+ end
19
+
20
+ def method_missing(method_name, ...)
21
+ if context.respond_to?(method_name)
22
+ context.public_send(method_name, ...)
23
+ else
24
+ super
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Line
4
+ module Message
5
+ class Builder
6
+ module QuickReply
7
+ # The Builder class is used to build quick reply buttons.
8
+ class Builder < Line::Message::Builder::Base
9
+ def initialize(context: nil, &)
10
+ @items = []
11
+
12
+ super
13
+ end
14
+
15
+ def message(text, label:, image_url: nil, &)
16
+ action(
17
+ Actions::Message.new(text: text, label: label, &).to_h,
18
+ image_url
19
+ )
20
+ end
21
+
22
+ def postback(data, label: nil, display_text: nil, image_url: nil, &)
23
+ action(
24
+ Actions::Postback.new(data: data, label: label, display_text: display_text, &).to_h,
25
+ image_url
26
+ )
27
+ end
28
+
29
+ def to_h
30
+ { items: @items.map(&:to_h) }
31
+ end
32
+
33
+ private
34
+
35
+ def action(action, image_url)
36
+ @items << {
37
+ type: "action",
38
+ imageUrl: image_url,
39
+ action: action
40
+ }.compact
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Line
4
+ module Message
5
+ class Builder
6
+ # The QuickReply allows to attach quick reply buttons to a message.
7
+ module QuickReply
8
+ require_relative "quick_reply/builder"
9
+
10
+ def quick_reply(&)
11
+ @quick_reply ||= Builder.new(context: context, &)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Line
4
+ module Message
5
+ class Builder
6
+ # Text message builder.
7
+ class Text < Base
8
+ include QuickReply
9
+
10
+ def initialize(text, context: nil, &block)
11
+ @text = text
12
+
13
+ super(context: context, &block)
14
+ end
15
+
16
+ def to_h
17
+ {
18
+ type: "text",
19
+ text: @text,
20
+ quickReply: @quick_reply&.to_h
21
+ }.compact
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Line
4
+ module Message
5
+ class Builder
6
+ VERSION = "0.1.0"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "builder/version"
4
+
5
+ module Line
6
+ module Message
7
+ # The Builder module provides a DSL for building LINE messages.
8
+ class Builder
9
+ class Error < StandardError; end
10
+
11
+ require_relative "builder/base"
12
+ require_relative "builder/actions"
13
+ require_relative "builder/quick_reply"
14
+ require_relative "builder/text"
15
+
16
+ attr_reader :context
17
+
18
+ def initialize(context = nil, &)
19
+ @messages = []
20
+ @context = context
21
+
22
+ instance_eval(&) if ::Kernel.block_given?
23
+ end
24
+
25
+ def text(text)
26
+ @messages << Text.new(text, context: context)
27
+ end
28
+
29
+ def build
30
+ @messages.map(&:to_h)
31
+ end
32
+
33
+ def to_json(*args)
34
+ build.to_json(*args)
35
+ end
36
+
37
+ def respond_to_missing?(method_name, include_private = false)
38
+ context.respond_to?(method_name, include_private) || super
39
+ end
40
+
41
+ def method_missing(method_name, ...)
42
+ if context.respond_to?(method_name)
43
+ context.public_send(method_name, ...)
44
+ else
45
+ super
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec::Matchers.define :have_line_text_message do |expected|
4
+ match do |actual|
5
+ actual.each do |message|
6
+ next unless message[:type] == "text"
7
+
8
+ return true if message[:text].match?(expected)
9
+ end
10
+
11
+ false
12
+ end
13
+
14
+ failure_message do |_actual|
15
+ "expected to find a text message matching #{expected}"
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "matchers/have_text_message"
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "line/message/rspec/matchers"
@@ -0,0 +1,10 @@
1
+ {
2
+ "release-type": "ruby",
3
+ "packages": {
4
+ ".":{
5
+ "component": "line-message-builder",
6
+ "include-component-in-tag": false,
7
+ "release-type": "ruby"
8
+ }
9
+ }
10
+ }
@@ -0,0 +1,8 @@
1
+ module Line
2
+ module Message
3
+ module Builder
4
+ VERSION: String
5
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
6
+ end
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: line-message-builder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Aotokitsuruya
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2025-04-04 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: The LINE Messaging API message builder.
14
+ email:
15
+ - contact@aotoki.me
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".rspec"
21
+ - ".rubocop.yml"
22
+ - CONVENTIONS.md
23
+ - LICENSE.txt
24
+ - README.md
25
+ - Rakefile
26
+ - lib/line/message/builder.rb
27
+ - lib/line/message/builder/actions.rb
28
+ - lib/line/message/builder/actions/message.rb
29
+ - lib/line/message/builder/actions/postback.rb
30
+ - lib/line/message/builder/base.rb
31
+ - lib/line/message/builder/quick_reply.rb
32
+ - lib/line/message/builder/quick_reply/builder.rb
33
+ - lib/line/message/builder/text.rb
34
+ - lib/line/message/builder/version.rb
35
+ - lib/line/message/rspec.rb
36
+ - lib/line/message/rspec/matchers.rb
37
+ - lib/line/message/rspec/matchers/have_text_message.rb
38
+ - release-please-config.json
39
+ - sig/line/message/builder.rbs
40
+ homepage: https://github.com/elct9620/line-message-builder
41
+ licenses:
42
+ - MIT
43
+ metadata:
44
+ homepage_uri: https://github.com/elct9620/line-message-builder
45
+ source_code_uri: https://github.com/elct9620/line-message-builder/tree/main
46
+ changelog_uri: https://github.com/elct9620/line-message-builder/blob/main/CHANGELOG.md
47
+ rubygems_mfa_required: 'true'
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 3.1.0
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubygems_version: 3.5.22
64
+ signing_key:
65
+ specification_version: 4
66
+ summary: The LINE Messaging API message builder.
67
+ test_files: []