fluent-plugin-slack 0.6.2 → 0.6.3
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/.travis.yml +2 -1
- data/CHANGELOG.md +6 -0
- data/README.md +4 -3
- data/VERSION +1 -1
- data/lib/fluent/plugin/out_buffered_slack.rb +1 -0
- data/lib/fluent/plugin/out_slack.rb +86 -5
- data/test/plugin/test_out_slack.rb +24 -0
- metadata +3 -3
- data/lib/fluent/plugin/out_buffered_slack.rb +0 -265
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e77ab7baa0827ff765699dcc93878a07fb4b672
|
4
|
+
data.tar.gz: 69e2477beb5f8e394493b773f14ba92430927750
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2bd4b7b25d6a3c63bca594121120cf29a5679bbcb77e295d9f245ced3a80061458ed1d6028c67cbf0f159ae6cdf13ee190764f84b9ae7d7219507fc275d409f3
|
7
|
+
data.tar.gz: dd44cbe50f10718b5c5dcdc0fba0e0b9d570db7c82b636e200142be75ea8736ad3d8bbc2f885e785654328894be76c4571ac6635f7c2d9c2ed421d6cbe6d6019
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -10,7 +10,7 @@ $ fluent-gem install fluent-plugin-slack
|
|
10
10
|
|
11
11
|
```apache
|
12
12
|
<match slack>
|
13
|
-
type slack
|
13
|
+
@type slack
|
14
14
|
webhook_url https://hooks.slack.com/services/XXX/XXX/XXX
|
15
15
|
channel general
|
16
16
|
username sowasowa
|
@@ -29,7 +29,7 @@ fluent_logger.post('slack', {
|
|
29
29
|
|
30
30
|
```apache
|
31
31
|
<match slack>
|
32
|
-
type slack
|
32
|
+
@type slack
|
33
33
|
slackbot_url https://xxxx.slack.com/services/hooks/slackbot?token=XXXXXXXXX
|
34
34
|
channel general
|
35
35
|
flush_interval 60s
|
@@ -46,7 +46,7 @@ fluent_logger.post('slack', {
|
|
46
46
|
|
47
47
|
```apache
|
48
48
|
<match slack>
|
49
|
-
type slack
|
49
|
+
@type slack
|
50
50
|
token xoxb-XXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXX
|
51
51
|
channel general
|
52
52
|
username sowasowa
|
@@ -83,6 +83,7 @@ fluent_logger.post('slack', {
|
|
83
83
|
|message_keys|keys used to format messages|message|
|
84
84
|
|auto_channels_create|Create channels if not exist. Not available for Incoming Webhook mode (since Incoming Webhook is specific to a channel). A web api `token` for Normal User is required (Bot User can not create channels. See https://api.slack.com/bot-users)|false|
|
85
85
|
|https_proxy|https proxy url such as `https://proxy.foo.bar:443`|nil|
|
86
|
+
|verbose_fallback|Originally, only `title` is used for the fallback which is the message shown on popup if `title` is given. If this option is set to be `true`, messages are also included to the fallback attribute|false|
|
86
87
|
|
87
88
|
`fluent-plugin-slack` uses `SetTimeKeyMixin` and `SetTagKeyMixin`, so you can also use:
|
88
89
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.3
|
@@ -0,0 +1 @@
|
|
1
|
+
out_slack.rb
|
@@ -5,38 +5,113 @@ module Fluent
|
|
5
5
|
Fluent::Plugin.register_output('buffered_slack', self) # old version compatiblity
|
6
6
|
Fluent::Plugin.register_output('slack', self)
|
7
7
|
|
8
|
+
# For fluentd v0.12.16 or earlier
|
9
|
+
class << self
|
10
|
+
unless method_defined?(:desc)
|
11
|
+
def desc(description)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
8
16
|
include SetTimeKeyMixin
|
9
17
|
include SetTagKeyMixin
|
10
18
|
|
11
19
|
config_set_default :include_time_key, true
|
12
20
|
config_set_default :include_tag_key, true
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
21
|
+
|
22
|
+
desc <<-DESC
|
23
|
+
Incoming Webhook URI (Required for Incoming Webhook mode).
|
24
|
+
See: https://api.slack.com/incoming-webhooks
|
25
|
+
DESC
|
26
|
+
config_param :webhook_url, :string, default: nil
|
27
|
+
desc <<-DESC
|
28
|
+
Slackbot URI (Required for Slackbot mode).
|
29
|
+
See https://api.slack.com/slackbot.
|
30
|
+
NOTE: most of optional parameters such as `username`, `color`, `icon_emoji`,
|
31
|
+
`icon_url`, and `title` are not available for this mode, but Desktop Notification
|
32
|
+
via Highlight Words works with only this mode.
|
33
|
+
DESC
|
34
|
+
config_param :slackbot_url, :string, default: nil
|
35
|
+
desc <<-DESC
|
36
|
+
Token for Web API (Required for Web API mode). See: https://api.slack.com/web.
|
37
|
+
DESC
|
38
|
+
config_param :token, :string, default: nil
|
39
|
+
desc "Name of bot."
|
17
40
|
config_param :username, :string, default: nil
|
41
|
+
desc <<-DESC
|
42
|
+
Color to use such as `good` or `bad`.
|
43
|
+
See Color section of https://api.slack.com/docs/attachments.
|
44
|
+
NOTE: This parameter must not be specified to receive Desktop Notification
|
45
|
+
via Mentions in cases of Incoming Webhook and Slack Web API.
|
46
|
+
DESC
|
18
47
|
config_param :color, :string, default: nil
|
48
|
+
desc <<-DESC
|
49
|
+
Emoji to use as the icon.
|
50
|
+
Either of `icon_emoji` or `icon_url` can be specified.
|
51
|
+
DESC
|
19
52
|
config_param :icon_emoji, :string, default: nil
|
53
|
+
desc <<-DESC
|
54
|
+
Url to an image to use as the icon.
|
55
|
+
Either of `icon_emoji` or `icon_url` can be specified.
|
56
|
+
DESC
|
20
57
|
config_param :icon_url, :string, default: nil
|
58
|
+
desc "Enable formatting. See: https://api.slack.com/docs/formatting."
|
21
59
|
config_param :mrkdwn, :bool, default: true
|
60
|
+
desc <<-DESC
|
61
|
+
Find and link channel names and usernames.
|
62
|
+
NOTE: This parameter must be `true` to receive Desktop Notification
|
63
|
+
via Mentions in cases of Incoming Webhook and Slack Web API.
|
64
|
+
DESC
|
22
65
|
config_param :link_names, :bool, default: true
|
66
|
+
desc <<-DESC
|
67
|
+
Change how messages are treated. `none` or `full` can be specified.
|
68
|
+
See Parsing mode section of https://api.slack.com/docs/formatting.
|
69
|
+
DESC
|
23
70
|
config_param :parse, :string, default: nil
|
71
|
+
desc <<-DESC
|
72
|
+
Create channels if not exist. Not available for Incoming Webhook mode
|
73
|
+
(since Incoming Webhook is specific to a channel).
|
74
|
+
A web api token for Normal User is required.
|
75
|
+
(Bot User can not create channels. See https://api.slack.com/bot-users)
|
76
|
+
DESC
|
24
77
|
config_param :auto_channels_create, :bool, default: false
|
78
|
+
desc "https proxy url such as https://proxy.foo.bar:443"
|
25
79
|
config_param :https_proxy, :string, default: nil
|
26
80
|
|
81
|
+
desc "channel to send messages (without first '#')."
|
27
82
|
config_param :channel, :string
|
83
|
+
desc <<-DESC
|
84
|
+
Keys used to format channel.
|
85
|
+
%s will be replaced with value specified by channel_keys if this option is used.
|
86
|
+
DESC
|
28
87
|
config_param :channel_keys, default: nil do |val|
|
29
88
|
val.split(',')
|
30
89
|
end
|
90
|
+
desc <<-DESC
|
91
|
+
Title format.
|
92
|
+
%s will be replaced with value specified by title_keys.
|
93
|
+
Title is created from the first appeared record on each tag.
|
94
|
+
NOTE: This parameter must **not** be specified to receive Desktop Notification
|
95
|
+
via Mentions in cases of Incoming Webhook and Slack Web API.
|
96
|
+
DESC
|
31
97
|
config_param :title, :string, default: nil
|
98
|
+
desc "Keys used to format the title."
|
32
99
|
config_param :title_keys, default: nil do |val|
|
33
100
|
val.split(',')
|
34
101
|
end
|
102
|
+
desc <<-DESC
|
103
|
+
Message format.
|
104
|
+
%s will be replaced with value specified by message_keys.
|
105
|
+
DESC
|
35
106
|
config_param :message, :string, default: nil
|
107
|
+
desc "Keys used to format messages."
|
36
108
|
config_param :message_keys, default: nil do |val|
|
37
109
|
val.split(',')
|
38
110
|
end
|
39
111
|
|
112
|
+
desc "Include messages to the fallback attributes"
|
113
|
+
config_param :verbose_fallback, :bool, default: false
|
114
|
+
|
40
115
|
# for test
|
41
116
|
attr_reader :slack, :time_format, :localtime, :timef, :mrkdwn_in, :post_message_opts
|
42
117
|
|
@@ -189,10 +264,16 @@ module Fluent
|
|
189
264
|
ch_fields[channel][per].value << "#{build_message(record)}\n"
|
190
265
|
end
|
191
266
|
ch_fields.map do |channel, fields|
|
267
|
+
fallback_text = if @verbose_fallback
|
268
|
+
fields.values.map { |f| "#{f.title} #{f.value}" }.join(' ')
|
269
|
+
else
|
270
|
+
fields.values.map(&:title).join(' ')
|
271
|
+
end
|
272
|
+
|
192
273
|
{
|
193
274
|
channel: channel,
|
194
275
|
attachments: [{
|
195
|
-
:fallback =>
|
276
|
+
:fallback => fallback_text, # fallback is the message shown on popup
|
196
277
|
:fields => fields.values.map(&:to_h)
|
197
278
|
}.merge(common_attachment)],
|
198
279
|
}.merge(common_payload)
|
@@ -342,6 +342,30 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
342
342
|
end
|
343
343
|
end
|
344
344
|
|
345
|
+
def test_title_payload_with_verbose_fallback_option
|
346
|
+
title = "mytitle"
|
347
|
+
d = create_driver(CONFIG + %[title #{title}\nverbose_fallback true])
|
348
|
+
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
349
|
+
d.tag = 'test'
|
350
|
+
# attachments field should be changed to show the title
|
351
|
+
mock(d.instance.slack).post_message(default_payload.merge({
|
352
|
+
attachments: [default_attachment.merge({
|
353
|
+
fallback: "#{title} sowawa1\nsowawa2\n",
|
354
|
+
fields: [
|
355
|
+
{
|
356
|
+
title: title,
|
357
|
+
value: "sowawa1\nsowawa2\n",
|
358
|
+
}
|
359
|
+
],
|
360
|
+
})]
|
361
|
+
}), {})
|
362
|
+
with_timezone('Asia/Tokyo') do
|
363
|
+
d.emit({message: 'sowawa1'}, time)
|
364
|
+
d.emit({message: 'sowawa2'}, time)
|
365
|
+
d.run
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
345
369
|
def test_color_payload
|
346
370
|
color = 'good'
|
347
371
|
d = create_driver(CONFIG + %[color #{color}])
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-slack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Keisuke SOGAWA
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2016-05-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fluentd
|
@@ -168,7 +168,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
168
168
|
version: '0'
|
169
169
|
requirements: []
|
170
170
|
rubyforge_project:
|
171
|
-
rubygems_version: 2.
|
171
|
+
rubygems_version: 2.5.1
|
172
172
|
signing_key:
|
173
173
|
specification_version: 4
|
174
174
|
summary: fluent Slack plugin
|
@@ -1,265 +0,0 @@
|
|
1
|
-
require_relative 'slack_client'
|
2
|
-
|
3
|
-
module Fluent
|
4
|
-
class SlackOutput < Fluent::BufferedOutput
|
5
|
-
Fluent::Plugin.register_output('buffered_slack', self) # old version compatiblity
|
6
|
-
Fluent::Plugin.register_output('slack', self)
|
7
|
-
|
8
|
-
include SetTimeKeyMixin
|
9
|
-
include SetTagKeyMixin
|
10
|
-
|
11
|
-
config_set_default :include_time_key, true
|
12
|
-
config_set_default :include_tag_key, true
|
13
|
-
|
14
|
-
config_param :webhook_url, :string, default: nil # incoming webhook
|
15
|
-
config_param :slackbot_url, :string, default: nil # slackbot
|
16
|
-
config_param :token, :string, default: nil # api token
|
17
|
-
config_param :username, :string, default: nil
|
18
|
-
config_param :color, :string, default: nil
|
19
|
-
config_param :icon_emoji, :string, default: nil
|
20
|
-
config_param :icon_url, :string, default: nil
|
21
|
-
config_param :mrkdwn, :bool, default: true
|
22
|
-
config_param :link_names, :bool, default: true
|
23
|
-
config_param :parse, :string, default: nil
|
24
|
-
config_param :auto_channels_create, :bool, default: false
|
25
|
-
config_param :https_proxy, :string, default: nil
|
26
|
-
|
27
|
-
config_param :channel, :string
|
28
|
-
config_param :channel_keys, default: nil do |val|
|
29
|
-
val.split(',')
|
30
|
-
end
|
31
|
-
config_param :title, :string, default: nil
|
32
|
-
config_param :title_keys, default: nil do |val|
|
33
|
-
val.split(',')
|
34
|
-
end
|
35
|
-
config_param :message, :string, default: nil
|
36
|
-
config_param :message_keys, default: nil do |val|
|
37
|
-
val.split(',')
|
38
|
-
end
|
39
|
-
|
40
|
-
# for test
|
41
|
-
attr_reader :slack, :time_format, :localtime, :timef, :mrkdwn_in, :post_message_opts
|
42
|
-
|
43
|
-
def initialize
|
44
|
-
super
|
45
|
-
require 'uri'
|
46
|
-
end
|
47
|
-
|
48
|
-
def configure(conf)
|
49
|
-
conf['time_format'] ||= '%H:%M:%S' # old version compatiblity
|
50
|
-
conf['localtime'] ||= true unless conf['utc']
|
51
|
-
|
52
|
-
super
|
53
|
-
|
54
|
-
@channel = URI.unescape(@channel) # old version compatibility
|
55
|
-
@channel = '#' + @channel unless @channel.start_with?('#')
|
56
|
-
|
57
|
-
if @webhook_url
|
58
|
-
if @webhook_url.empty?
|
59
|
-
raise Fluent::ConfigError.new("`webhook_url` is an empty string")
|
60
|
-
end
|
61
|
-
@slack = Fluent::SlackClient::IncomingWebhook.new(@webhook_url)
|
62
|
-
elsif @slackbot_url
|
63
|
-
if @slackbot_url.empty?
|
64
|
-
raise Fluent::ConfigError.new("`slackbot_url` is an empty string")
|
65
|
-
end
|
66
|
-
if @username or @color or @icon_emoji or @icon_url
|
67
|
-
log.warn "out_slack: `username`, `color`, `icon_emoji`, `icon_url` parameters are not available for Slackbot Remote Control"
|
68
|
-
end
|
69
|
-
@slack = Fluent::SlackClient::Slackbot.new(@slackbot_url)
|
70
|
-
elsif @token
|
71
|
-
if @token.empty?
|
72
|
-
raise Fluent::ConfigError.new("`token` is an empty string")
|
73
|
-
end
|
74
|
-
@slack = Fluent::SlackClient::WebApi.new
|
75
|
-
else
|
76
|
-
raise Fluent::ConfigError.new("One of `webhook_url` or `slackbot_url`, or `token` is required")
|
77
|
-
end
|
78
|
-
@slack.log = log
|
79
|
-
@slack.debug_dev = log.out if log.level <= Fluent::Log::LEVEL_TRACE
|
80
|
-
|
81
|
-
if @https_proxy
|
82
|
-
@slack.https_proxy = @https_proxy
|
83
|
-
end
|
84
|
-
|
85
|
-
@message ||= '%s'
|
86
|
-
@message_keys ||= %w[message]
|
87
|
-
begin
|
88
|
-
@message % (['1'] * @message_keys.length)
|
89
|
-
rescue ArgumentError
|
90
|
-
raise Fluent::ConfigError, "string specifier '%s' for `message` and `message_keys` specification mismatch"
|
91
|
-
end
|
92
|
-
if @title and @title_keys
|
93
|
-
begin
|
94
|
-
@title % (['1'] * @title_keys.length)
|
95
|
-
rescue ArgumentError
|
96
|
-
raise Fluent::ConfigError, "string specifier '%s' for `title` and `title_keys` specification mismatch"
|
97
|
-
end
|
98
|
-
end
|
99
|
-
if @channel_keys
|
100
|
-
begin
|
101
|
-
@channel % (['1'] * @channel_keys.length)
|
102
|
-
rescue ArgumentError
|
103
|
-
raise Fluent::ConfigError, "string specifier '%s' for `channel` and `channel_keys` specification mismatch"
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
if @icon_emoji and @icon_url
|
108
|
-
raise Fluent::ConfigError, "either of `icon_emoji` or `icon_url` can be specified"
|
109
|
-
end
|
110
|
-
|
111
|
-
if @mrkdwn
|
112
|
-
# Enable markdown for attachments. See https://api.slack.com/docs/formatting
|
113
|
-
@mrkdwn_in = %w[text fields]
|
114
|
-
end
|
115
|
-
|
116
|
-
if @parse and !%w[none full].include?(@parse)
|
117
|
-
raise Fluent::ConfigError, "`parse` must be either of `none` or `full`"
|
118
|
-
end
|
119
|
-
|
120
|
-
@post_message_opts = {}
|
121
|
-
if @auto_channels_create
|
122
|
-
raise Fluent::ConfigError, "`token` parameter is required to use `auto_channels_create`" unless @token
|
123
|
-
@post_message_opts = {auto_channels_create: true}
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
def format(tag, time, record)
|
128
|
-
[tag, time, record].to_msgpack
|
129
|
-
end
|
130
|
-
|
131
|
-
def write(chunk)
|
132
|
-
begin
|
133
|
-
payloads = build_payloads(chunk)
|
134
|
-
payloads.each {|payload| @slack.post_message(payload, @post_message_opts) }
|
135
|
-
rescue Timeout::Error => e
|
136
|
-
log.warn "out_slack:", :error => e.to_s, :error_class => e.class.to_s
|
137
|
-
raise e # let Fluentd retry
|
138
|
-
rescue => e
|
139
|
-
log.error "out_slack:", :error => e.to_s, :error_class => e.class.to_s
|
140
|
-
log.warn_backtrace e.backtrace
|
141
|
-
# discard. @todo: add more retriable errors
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
private
|
146
|
-
|
147
|
-
def build_payloads(chunk)
|
148
|
-
if @title
|
149
|
-
build_title_payloads(chunk)
|
150
|
-
elsif @color
|
151
|
-
build_color_payloads(chunk)
|
152
|
-
else
|
153
|
-
build_plain_payloads(chunk)
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
def common_payload
|
158
|
-
return @common_payload if @common_payload
|
159
|
-
@common_payload = {}
|
160
|
-
@common_payload[:username] = @username if @username
|
161
|
-
@common_payload[:icon_emoji] = @icon_emoji if @icon_emoji
|
162
|
-
@common_payload[:icon_url] = @icon_url if @icon_url
|
163
|
-
@common_payload[:mrkdwn] = @mrkdwn if @mrkdwn
|
164
|
-
@common_payload[:link_names] = @link_names if @link_names
|
165
|
-
@common_payload[:parse] = @parse if @parse
|
166
|
-
@common_payload[:token] = @token if @token
|
167
|
-
@common_payload
|
168
|
-
end
|
169
|
-
|
170
|
-
def common_attachment
|
171
|
-
return @common_attachment if @common_attachment
|
172
|
-
@common_attachment = {}
|
173
|
-
@common_attachment[:color] = @color if @color
|
174
|
-
@common_attachment[:mrkdwn_in] = @mrkdwn_in if @mrkdwn_in
|
175
|
-
@common_attachment
|
176
|
-
end
|
177
|
-
|
178
|
-
Field = Struct.new("Field", :title, :value)
|
179
|
-
# ruby 1.9.x does not provide #to_h
|
180
|
-
Field.send(:define_method, :to_h) { {title: title, value: value} }
|
181
|
-
|
182
|
-
def build_title_payloads(chunk)
|
183
|
-
ch_fields = {}
|
184
|
-
chunk.msgpack_each do |tag, time, record|
|
185
|
-
channel = build_channel(record)
|
186
|
-
per = tag # title per tag
|
187
|
-
ch_fields[channel] ||= {}
|
188
|
-
ch_fields[channel][per] ||= Field.new(build_title(record), '')
|
189
|
-
ch_fields[channel][per].value << "#{build_message(record)}\n"
|
190
|
-
end
|
191
|
-
ch_fields.map do |channel, fields|
|
192
|
-
{
|
193
|
-
channel: channel,
|
194
|
-
attachments: [{
|
195
|
-
:fallback => fields.values.map(&:title).join(' '), # fallback is the message shown on popup
|
196
|
-
:fields => fields.values.map(&:to_h)
|
197
|
-
}.merge(common_attachment)],
|
198
|
-
}.merge(common_payload)
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
def build_color_payloads(chunk)
|
203
|
-
messages = {}
|
204
|
-
chunk.msgpack_each do |tag, time, record|
|
205
|
-
channel = build_channel(record)
|
206
|
-
messages[channel] ||= ''
|
207
|
-
messages[channel] << "#{build_message(record)}\n"
|
208
|
-
end
|
209
|
-
messages.map do |channel, text|
|
210
|
-
{
|
211
|
-
channel: channel,
|
212
|
-
attachments: [{
|
213
|
-
:fallback => text,
|
214
|
-
:text => text,
|
215
|
-
}.merge(common_attachment)],
|
216
|
-
}.merge(common_payload)
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
def build_plain_payloads(chunk)
|
221
|
-
messages = {}
|
222
|
-
chunk.msgpack_each do |tag, time, record|
|
223
|
-
channel = build_channel(record)
|
224
|
-
messages[channel] ||= ''
|
225
|
-
messages[channel] << "#{build_message(record)}\n"
|
226
|
-
end
|
227
|
-
messages.map do |channel, text|
|
228
|
-
{
|
229
|
-
channel: channel,
|
230
|
-
text: text,
|
231
|
-
}.merge(common_payload)
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
def build_message(record)
|
236
|
-
values = fetch_keys(record, @message_keys)
|
237
|
-
@message % values
|
238
|
-
end
|
239
|
-
|
240
|
-
def build_title(record)
|
241
|
-
return @title unless @title_keys
|
242
|
-
|
243
|
-
values = fetch_keys(record, @title_keys)
|
244
|
-
@title % values
|
245
|
-
end
|
246
|
-
|
247
|
-
def build_channel(record)
|
248
|
-
return @channel unless @channel_keys
|
249
|
-
|
250
|
-
values = fetch_keys(record, @channel_keys)
|
251
|
-
@channel % values
|
252
|
-
end
|
253
|
-
|
254
|
-
def fetch_keys(record, keys)
|
255
|
-
Array(keys).map do |key|
|
256
|
-
begin
|
257
|
-
record.fetch(key).to_s
|
258
|
-
rescue KeyError
|
259
|
-
log.warn "out_slack: the specified key '#{key}' not found in record. [#{record}]"
|
260
|
-
''
|
261
|
-
end
|
262
|
-
end
|
263
|
-
end
|
264
|
-
end
|
265
|
-
end
|