slack-ruby-bot 0.12.0 → 0.13.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/.gitignore +3 -2
- data/.rubocop.yml +14 -1
- data/.rubocop_todo.yml +13 -36
- data/.travis.yml +7 -5
- data/CHANGELOG.md +9 -0
- data/DEPLOYMENT.md +61 -5
- data/Dangerfile +2 -0
- data/Gemfile +10 -3
- data/LICENSE.md +1 -1
- data/README.md +78 -10
- data/Rakefile +2 -0
- data/TUTORIAL.md +23 -0
- data/UPGRADING.md +8 -0
- data/examples/inventory/Gemfile +2 -0
- data/examples/inventory/inventorybot.rb +5 -1
- data/examples/market/Gemfile +4 -3
- data/examples/market/marketbot.rb +22 -15
- data/examples/minimal/Gemfile +2 -0
- data/examples/minimal/pongbot.rb +2 -0
- data/examples/weather/Gemfile +2 -0
- data/examples/weather/weatherbot.rb +2 -0
- data/lib/config/application.rb +4 -2
- data/lib/config/boot.rb +2 -0
- data/lib/config/environment.rb +3 -1
- data/lib/initializers/giphy.rb +2 -0
- data/lib/initializers/giphy_client.rb +2 -0
- data/lib/slack-ruby-bot.rb +3 -1
- data/lib/slack-ruby-bot/about.rb +3 -1
- data/lib/slack-ruby-bot/app.rb +2 -0
- data/lib/slack-ruby-bot/bot.rb +2 -0
- data/lib/slack-ruby-bot/client.rb +7 -4
- data/lib/slack-ruby-bot/commands.rb +2 -0
- data/lib/slack-ruby-bot/commands/about.rb +2 -0
- data/lib/slack-ruby-bot/commands/base.rb +12 -1
- data/lib/slack-ruby-bot/commands/help.rb +9 -7
- data/lib/slack-ruby-bot/commands/hi.rb +2 -0
- data/lib/slack-ruby-bot/commands/support/attrs.rb +2 -0
- data/lib/slack-ruby-bot/commands/support/help.rb +4 -0
- data/lib/slack-ruby-bot/commands/support/match.rb +4 -3
- data/lib/slack-ruby-bot/commands/unknown.rb +2 -0
- data/lib/slack-ruby-bot/config.rb +3 -0
- data/lib/slack-ruby-bot/hooks.rb +2 -0
- data/lib/slack-ruby-bot/hooks/hello.rb +22 -3
- data/lib/slack-ruby-bot/hooks/hook_support.rb +2 -0
- data/lib/slack-ruby-bot/hooks/message.rb +5 -2
- data/lib/slack-ruby-bot/hooks/set.rb +3 -1
- data/lib/slack-ruby-bot/mvc.rb +2 -0
- data/lib/slack-ruby-bot/mvc/controller/base.rb +4 -3
- data/lib/slack-ruby-bot/mvc/model/base.rb +2 -0
- data/lib/slack-ruby-bot/mvc/mvc.rb +2 -0
- data/lib/slack-ruby-bot/mvc/view/base.rb +2 -0
- data/lib/slack-ruby-bot/rspec.rb +3 -1
- data/lib/slack-ruby-bot/rspec/support/bots_for_tests.rb +2 -0
- data/lib/slack-ruby-bot/rspec/support/slack-ruby-bot/it_behaves_like_a_slack_bot.rb +2 -0
- data/lib/slack-ruby-bot/rspec/support/slack-ruby-bot/not_respond.rb +3 -5
- data/lib/slack-ruby-bot/rspec/support/slack-ruby-bot/respond_with_error.rb +3 -5
- data/lib/slack-ruby-bot/rspec/support/slack-ruby-bot/respond_with_slack_message.rb +16 -13
- data/lib/slack-ruby-bot/rspec/support/slack-ruby-bot/respond_with_slack_messages.rb +27 -18
- data/lib/slack-ruby-bot/rspec/support/slack-ruby-bot/start_typing.rb +32 -0
- data/lib/slack-ruby-bot/rspec/support/slack_api_key.rb +2 -0
- data/lib/slack-ruby-bot/rspec/support/slack_ruby_bot_configure.rb +2 -0
- data/lib/slack-ruby-bot/rspec/support/spec_helpers.rb +2 -0
- data/lib/slack-ruby-bot/rspec/support/vcr.rb +2 -0
- data/lib/slack-ruby-bot/server.rb +2 -0
- data/lib/slack-ruby-bot/support/loggable.rb +2 -0
- data/lib/slack-ruby-bot/version.rb +3 -1
- data/lib/slack_ruby_bot.rb +2 -0
- data/screenshots/create-app.png +0 -0
- data/slack-ruby-bot.gemspec +5 -2
- data/spec/slack-ruby-bot/app_spec.rb +2 -0
- data/spec/slack-ruby-bot/client_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/about_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/aliases_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/attachment_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/bot_message_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/bot_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/commands_command_classes_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/commands_permitted_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/commands_precedence_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/commands_regexp_escape_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/commands_regexp_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/commands_spaces_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/commands_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/commands_with_block_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/commands_with_expression_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/direct_messages_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/empty_text_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/help_spec.rb +15 -13
- data/spec/slack-ruby-bot/commands/hi_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/match_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/message_loop_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/nil_message_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/not_implemented_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/operators_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/operators_with_block_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/scan_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/send_gif_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/send_message_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/send_message_with_gif_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/support/attrs_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/support/help_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/support/match_spec.rb +2 -0
- data/spec/slack-ruby-bot/commands/unknown_spec.rb +2 -0
- data/spec/slack-ruby-bot/config_spec.rb +2 -0
- data/spec/slack-ruby-bot/hooks/hello_spec.rb +51 -0
- data/spec/slack-ruby-bot/hooks/hook_support_spec.rb +2 -0
- data/spec/slack-ruby-bot/hooks/message_spec.rb +3 -1
- data/spec/slack-ruby-bot/hooks/set_spec.rb +2 -0
- data/spec/slack-ruby-bot/initializers/giphy_client_spec.rb +2 -0
- data/spec/slack-ruby-bot/initializers/giphy_spec.rb +2 -0
- data/spec/slack-ruby-bot/mvc/controller/controller_to_command_spec.rb +2 -0
- data/spec/slack-ruby-bot/rspec/respond_with_error_spec.rb +2 -0
- data/spec/slack-ruby-bot/rspec/respond_with_slack_message_spec.rb +20 -0
- data/spec/slack-ruby-bot/rspec/respond_with_slack_messages_spec.rb +36 -0
- data/spec/slack-ruby-bot/rspec/start_typing_spec.rb +36 -0
- data/spec/slack-ruby-bot/server_spec.rb +2 -0
- data/spec/slack-ruby-bot/support/loggable_spec.rb +2 -0
- data/spec/slack-ruby-bot/version_spec.rb +2 -0
- data/spec/spec_helper.rb +2 -0
- metadata +12 -8
- data/screenshots/register-bot.png +0 -0
data/TUTORIAL.md
CHANGED
|
@@ -36,6 +36,10 @@ end
|
|
|
36
36
|
|
|
37
37
|
Run `bundle install` to get all the gems.
|
|
38
38
|
|
|
39
|
+
##### Passenger
|
|
40
|
+
|
|
41
|
+
To use passenger standalone change `gem 'puma'` to `gem 'passenger'`
|
|
42
|
+
|
|
39
43
|
#### Application
|
|
40
44
|
|
|
41
45
|
Create a folder called `slack-mathbot` and inside of it create `bot.rb`.
|
|
@@ -141,6 +145,25 @@ Create a `Procfile` which `foreman` will use when you run the `foreman start` co
|
|
|
141
145
|
web: bundle exec puma -p $PORT
|
|
142
146
|
```
|
|
143
147
|
|
|
148
|
+
#### Passenger
|
|
149
|
+
|
|
150
|
+
If you want to use passenger locally change it to:
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
web: bundle exec passenger -p $PORT
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Add the following folders to your project root: 'tmp/', 'log/', 'public/'
|
|
157
|
+
Passenger will automatically save the local logs to these folders.
|
|
158
|
+
|
|
159
|
+
Optional: Change the port in a `Passenger.json`
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
{
|
|
163
|
+
"port": "1234"
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
144
167
|
### Run the Bot
|
|
145
168
|
|
|
146
169
|
Run `foreman start`. Your bot should be running.
|
data/UPGRADING.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
Upgrading SlackRubyBot
|
|
2
2
|
======================
|
|
3
3
|
|
|
4
|
+
### Upgrading to >= 0.13.0
|
|
5
|
+
|
|
6
|
+
#### Minimum Ruby Version
|
|
7
|
+
|
|
8
|
+
Ruby 2.3 or later is now required.
|
|
9
|
+
|
|
10
|
+
See [#246](https://github.com/slack-ruby/slack-ruby-bot/pull/246) for more information.
|
|
11
|
+
|
|
4
12
|
### Upgrading to >= 0.12.0
|
|
5
13
|
|
|
6
14
|
#### Remove any references to `SlackRubyBot::Server#restart!`
|
data/examples/inventory/Gemfile
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'slack-ruby-bot'
|
|
2
4
|
require 'sqlite3'
|
|
3
5
|
|
|
@@ -56,6 +58,7 @@ class InventoryController < SlackRubyBot::MVC::Controller::Base
|
|
|
56
58
|
def notify_admin
|
|
57
59
|
row = _row.first
|
|
58
60
|
return if row[:quantity].to_i.zero?
|
|
61
|
+
|
|
59
62
|
view.email_admin("Inventory item #{row[:name]} needs to be refilled.")
|
|
60
63
|
view.say(channel: data.channel, text: "Administrator notified via email to refill #{row[:name]}.")
|
|
61
64
|
end
|
|
@@ -93,6 +96,7 @@ class InventoryModel < SlackRubyBot::MVC::Model::Base
|
|
|
93
96
|
count = 0
|
|
94
97
|
count += 1 while results.next
|
|
95
98
|
return if count < 4
|
|
99
|
+
|
|
96
100
|
add_item "'Audi',3,52642"
|
|
97
101
|
add_item "'Mercedes',1,57127"
|
|
98
102
|
add_item "'Skoda',5,9000"
|
|
@@ -241,7 +245,7 @@ class InventoryBot < SlackRubyBot::Bot
|
|
|
241
245
|
view = InventoryView.new
|
|
242
246
|
@controller = InventoryController.new(model, view)
|
|
243
247
|
@controller.class.command_class.routes.each do |route|
|
|
244
|
-
|
|
248
|
+
warn route.inspect
|
|
245
249
|
end
|
|
246
250
|
end
|
|
247
251
|
|
data/examples/market/Gemfile
CHANGED
|
@@ -1,24 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'iex-ruby-client'
|
|
1
4
|
require 'slack-ruby-bot'
|
|
2
|
-
require 'yahoo-finance'
|
|
3
5
|
|
|
4
6
|
SlackRubyBot::Client.logger.level = Logger::WARN
|
|
5
7
|
|
|
6
8
|
class MarketBot < SlackRubyBot::Bot
|
|
7
9
|
scan(/([A-Z]{2,5}+)/) do |client, data, stocks|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
10
|
+
stocks.each do |stock|
|
|
11
|
+
begin
|
|
12
|
+
quote = IEX::Resources::Quote.get(stock.first)
|
|
13
|
+
|
|
14
|
+
client.web_client.chat_postMessage(
|
|
15
|
+
channel: data.channel,
|
|
16
|
+
as_user: true,
|
|
17
|
+
attachments: [
|
|
18
|
+
{
|
|
19
|
+
fallback: "#{quote.company_name} (#{quote.symbol}): $#{quote.latest_price}",
|
|
20
|
+
title: "#{quote.company_name} (#{quote.symbol})",
|
|
21
|
+
text: "$#{quote.latest_price} (#{quote.change_percent})",
|
|
22
|
+
color: quote.change.to_f > 0 ? '#00FF00' : '#FF0000'
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
)
|
|
26
|
+
rescue IEX::Errors::SymbolNotFoundError
|
|
27
|
+
logger.warn "no stock found for symbol #{stock}"
|
|
28
|
+
end
|
|
22
29
|
end
|
|
23
30
|
end
|
|
24
31
|
end
|
data/examples/minimal/Gemfile
CHANGED
data/examples/minimal/pongbot.rb
CHANGED
data/examples/weather/Gemfile
CHANGED
data/lib/config/application.rb
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..'))
|
|
2
4
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
3
5
|
|
|
4
6
|
require 'boot'
|
|
5
7
|
|
|
6
|
-
Dir[File.expand_path('
|
|
8
|
+
Dir[File.expand_path('../initializers', __dir__) + '/**/*.rb'].sort.each do |file|
|
|
7
9
|
require file
|
|
8
10
|
end
|
|
9
11
|
|
|
10
|
-
require File.expand_path('
|
|
12
|
+
require File.expand_path('application', __dir__)
|
|
11
13
|
|
|
12
14
|
require 'slack_ruby_bot'
|
data/lib/config/boot.rb
CHANGED
data/lib/config/environment.rb
CHANGED
data/lib/initializers/giphy.rb
CHANGED
data/lib/slack-ruby-bot.rb
CHANGED
data/lib/slack-ruby-bot/about.rb
CHANGED
data/lib/slack-ruby-bot/app.rb
CHANGED
data/lib/slack-ruby-bot/bot.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module SlackRubyBot
|
|
2
4
|
class Client < Slack::RealTime::Client
|
|
3
5
|
include Loggable
|
|
@@ -31,11 +33,12 @@ module SlackRubyBot
|
|
|
31
33
|
|
|
32
34
|
def send_gifs?
|
|
33
35
|
return false unless defined?(Giphy)
|
|
36
|
+
|
|
34
37
|
send_gifs.nil? ? SlackRubyBot::Config.send_gifs? : send_gifs
|
|
35
38
|
end
|
|
36
39
|
|
|
37
40
|
def name
|
|
38
|
-
SlackRubyBot.config.user ||
|
|
41
|
+
SlackRubyBot.config.user || self.self&.name
|
|
39
42
|
end
|
|
40
43
|
|
|
41
44
|
def url
|
|
@@ -51,9 +54,9 @@ module SlackRubyBot
|
|
|
51
54
|
if keywords && send_gifs?
|
|
52
55
|
gif = begin
|
|
53
56
|
Giphy.random(keywords)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
rescue StandardError => e
|
|
58
|
+
logger.warn "Giphy.random: #{e.message}"
|
|
59
|
+
nil
|
|
57
60
|
end
|
|
58
61
|
end
|
|
59
62
|
text = [text, gif && gif.image_url.to_s].compact.join("\n")
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative 'support/match'
|
|
2
4
|
require_relative 'support/help'
|
|
3
5
|
|
|
@@ -55,24 +57,30 @@ module SlackRubyBot
|
|
|
55
57
|
finalize_routes!
|
|
56
58
|
expression, text = parse(client, data)
|
|
57
59
|
return false unless expression || data.attachments
|
|
60
|
+
|
|
58
61
|
routes.each_pair do |route, options|
|
|
59
62
|
match_method = options[:match_method]
|
|
60
63
|
case match_method
|
|
61
64
|
when :match
|
|
62
65
|
next unless expression
|
|
66
|
+
|
|
63
67
|
match = route.match(expression)
|
|
64
68
|
match ||= route.match(text) if text
|
|
65
69
|
next unless match
|
|
66
70
|
next if match.names.include?('bot') && !client.name?(match['bot'])
|
|
71
|
+
|
|
67
72
|
match = Support::Match.new(match)
|
|
68
73
|
when :scan
|
|
69
74
|
next unless expression
|
|
75
|
+
|
|
70
76
|
match = expression.scan(route)
|
|
71
77
|
next unless match.any?
|
|
72
78
|
when :attachment
|
|
73
79
|
next unless data.attachments && !data.attachments.empty?
|
|
80
|
+
|
|
74
81
|
match, attachment, field = match_attachments(data, route, options[:fields_to_scan])
|
|
75
82
|
next unless match
|
|
83
|
+
|
|
76
84
|
match = Support::Match.new(match, attachment, field)
|
|
77
85
|
end
|
|
78
86
|
call_command(client, data, match, options[:block])
|
|
@@ -122,6 +130,7 @@ module SlackRubyBot
|
|
|
122
130
|
text = data.text
|
|
123
131
|
return text unless direct_message?(data) && message_from_another_user?(data)
|
|
124
132
|
return text if message_begins_with_bot_mention?(text, client.names)
|
|
133
|
+
|
|
125
134
|
["#{client.name} #{text}", text]
|
|
126
135
|
end
|
|
127
136
|
|
|
@@ -139,7 +148,8 @@ module SlackRubyBot
|
|
|
139
148
|
end
|
|
140
149
|
|
|
141
150
|
def finalize_routes!
|
|
142
|
-
return if routes
|
|
151
|
+
return if routes&.any?
|
|
152
|
+
|
|
143
153
|
command command_name_from_class
|
|
144
154
|
end
|
|
145
155
|
|
|
@@ -148,6 +158,7 @@ module SlackRubyBot
|
|
|
148
158
|
data.attachments.each do |attachment|
|
|
149
159
|
fields_to_scan.each do |field|
|
|
150
160
|
next unless attachment[field]
|
|
161
|
+
|
|
151
162
|
match = route.match(attachment[field])
|
|
152
163
|
return match, attachment, field if match
|
|
153
164
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module SlackRubyBot
|
|
2
4
|
module Commands
|
|
3
5
|
class Help < Base
|
|
@@ -24,16 +26,16 @@ module SlackRubyBot
|
|
|
24
26
|
def general_text
|
|
25
27
|
bot_desc = Support::Help.instance.bot_desc_and_commands
|
|
26
28
|
other_commands_descs = Support::Help.instance.other_commands_descs
|
|
27
|
-
|
|
28
|
-
#{bot_desc.join("\n")}
|
|
29
|
+
<<~TEXT
|
|
30
|
+
#{bot_desc.join("\n")}
|
|
29
31
|
|
|
30
|
-
*Other commands:*
|
|
31
|
-
#{other_commands_descs.join("\n")}
|
|
32
|
+
*Other commands:*
|
|
33
|
+
#{other_commands_descs.join("\n")}
|
|
32
34
|
|
|
33
|
-
For getting description of the command use: *help <command>*
|
|
35
|
+
For getting description of the command use: *help <command>*
|
|
34
36
|
|
|
35
|
-
For more information see https://github.com/slack-ruby/slack-ruby-bot, please.
|
|
36
|
-
TEXT
|
|
37
|
+
For more information see https://github.com/slack-ruby/slack-ruby-bot, please.
|
|
38
|
+
TEXT
|
|
37
39
|
end
|
|
38
40
|
end
|
|
39
41
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'singleton'
|
|
2
4
|
require_relative 'attrs'
|
|
3
5
|
|
|
@@ -34,12 +36,14 @@ module SlackRubyBot
|
|
|
34
36
|
help_attrs = find_command_help_attrs(unescaped_name)
|
|
35
37
|
return "There's no command *#{unescaped_name}*" unless help_attrs
|
|
36
38
|
return "There's no description for command *#{unescaped_name}*" if help_attrs.command_long_desc.blank?
|
|
39
|
+
|
|
37
40
|
"#{command_name_and_desc(help_attrs)}\n\n#{help_attrs.command_long_desc}"
|
|
38
41
|
end
|
|
39
42
|
|
|
40
43
|
def find_command_help_attrs(name)
|
|
41
44
|
help_attrs = commands_help_attrs.find { |k| k.command_name == name }
|
|
42
45
|
return help_attrs if help_attrs
|
|
46
|
+
|
|
43
47
|
commands_help_attrs.each { |k| k.commands.each { |c| return c if c.command_name == name } }
|
|
44
48
|
nil
|
|
45
49
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module SlackRubyBot
|
|
2
4
|
module Commands
|
|
3
5
|
module Support
|
|
@@ -9,9 +11,8 @@ module SlackRubyBot
|
|
|
9
11
|
attr_reader :attachment, :attachment_field
|
|
10
12
|
|
|
11
13
|
def initialize(match_data, attachment = nil, attachment_field = nil)
|
|
12
|
-
unless match_data.is_a? MatchData
|
|
13
|
-
|
|
14
|
-
end
|
|
14
|
+
raise ArgumentError, 'match_data should be a type of MatchData' unless match_data.is_a? MatchData
|
|
15
|
+
|
|
15
16
|
@match_data = match_data
|
|
16
17
|
@attachment = attachment
|
|
17
18
|
@attachment_field = attachment_field
|