fluent-plugin-slack 0.5.5 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/README.md +20 -9
- data/VERSION +1 -1
- data/lib/fluent/plugin/out_buffered_slack.rb +38 -18
- data/lib/fluent/plugin/out_slack.rb +38 -18
- data/lib/fluent/plugin/slack_client.rb +7 -3
- data/test/plugin/test_out_slack.rb +215 -126
- data/test/plugin/test_slack_client.rb +112 -129
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63a07a1d2026c16d55cd088092f69953404b202e
|
4
|
+
data.tar.gz: 33f8b2de136067d8e0e7adfa69457bb676d97eaa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 429287c6ea93b6a2af9371e7c50624142295be16a2e81e2ba27f3d293dc310eed431a0481f33b349c52384839db415401285f38ee7a4dbbcc778dc2f5017ad06
|
7
|
+
data.tar.gz: 50b5c8f83db6ef873cc448c85106b63e6dd7c6ff547f960701ec0634077d9539d09cbb5adfea347448c17982c538f87c5cfd37a44876eb5f90c2e91d43c3dfc6
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
## 0.6.0 (2015/04/02)
|
2
|
+
|
3
|
+
This version has impcompatibility with previous versions in default option values
|
4
|
+
|
5
|
+
Enhancements:
|
6
|
+
|
7
|
+
* Support `link_names` and `parse` option. `link_names` option is `true` as default
|
8
|
+
|
9
|
+
Changes:
|
10
|
+
|
11
|
+
* the default payload of Incoming Webhook was changed
|
12
|
+
* `color` is `nil` as default
|
13
|
+
* `icon_emoji` is `nil` as default
|
14
|
+
* `username` is `nil` as default
|
15
|
+
* `mrkdwn` is `true` as default
|
16
|
+
|
1
17
|
## 0.5.5 (2015/04/01)
|
2
18
|
|
3
19
|
Enhancements:
|
data/README.md
CHANGED
@@ -14,7 +14,6 @@ $ fluent-gem install fluent-plugin-slack
|
|
14
14
|
webhook_url https://hooks.slack.com/services/XXX/XXX/XXX
|
15
15
|
channel general
|
16
16
|
username sowasowa
|
17
|
-
color good
|
18
17
|
icon_emoji :ghost:
|
19
18
|
flush_interval 60s
|
20
19
|
</match>
|
@@ -51,7 +50,6 @@ fluent_logger.post('slack', {
|
|
51
50
|
token xoxb-XXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXX
|
52
51
|
channel general
|
53
52
|
username sowasowa
|
54
|
-
color good
|
55
53
|
icon_emoji :ghost:
|
56
54
|
flush_interval 60s
|
57
55
|
</match>
|
@@ -68,16 +66,18 @@ fluent_logger.post('slack', {
|
|
68
66
|
|parameter|description|default|
|
69
67
|
|---|---|---|
|
70
68
|
|webhook_url|Incoming Webhook URI (Required for Incoming Webhook mode). See https://api.slack.com/incoming-webhooks||
|
71
|
-
|slackbot_url|Slackbot URI (Required for Slackbot mode). See https://api.slack.com/slackbot. `username`, `color`, `icon_emoji`, `icon_url` are not available for this mode, but Desktop Notification via Highlight Words works with only this mode
|
69
|
+
|slackbot_url|Slackbot URI (Required for Slackbot mode). See https://api.slack.com/slackbot. NOTE: most of optional parameters such as `username`, `color`, `icon_emoji`, `icon_url`, and `title` are not available for this mode, but Desktop Notification via Highlight Words works with only this mode||
|
72
70
|
|token|Token for Web API (Required for Web API mode). See https://api.slack.com/web||
|
73
|
-
|username|name of bot|
|
74
|
-
|color|color to use
|
75
|
-
|icon_emoji|emoji to use as the icon. either of icon_emoji or icon_url can be specified
|
76
|
-
|icon_url|url to an image to use as the icon. either of icon_emoji or icon_url can be specified|nil|
|
77
|
-
|mrkdwn|enable formatting. see https://api.slack.com/docs/formatting|
|
71
|
+
|username|name of bot|nil|
|
72
|
+
|color|color to use such as `good` or `bad`. See `Color` section of https://api.slack.com/docs/attachments. NOTE: This parameter must **not** be specified to receive Desktop Notification via Mentions in cases of Incoming Webhook and Slack Web API|nil|
|
73
|
+
|icon_emoji|emoji to use as the icon. either of `icon_emoji` or `icon_url` can be specified|nil|
|
74
|
+
|icon_url|url to an image to use as the icon. either of `icon_emoji` or `icon_url` can be specified|nil|
|
75
|
+
|mrkdwn|enable formatting. see https://api.slack.com/docs/formatting|true|
|
76
|
+
|link_names|find and link channel names and usernames. NOTE: This parameter must be `true` to receive Desktop Notification via Mentions in cases of Incoming Webhook and Slack Web API|true|
|
77
|
+
|parse|change how messages are treated. `none` or `full` can be specified. See `Parsing mode` section of https://api.slack.com/docs/formatting|nil|
|
78
78
|
|channel|channel to send messages (without first '#')||
|
79
79
|
|channel_keys|keys used to format channel. %s will be replaced with value specified by channel_keys if this option is used|nil|
|
80
|
-
|title|title format. %s will be replaced with value specified by title_keys. title is created from the first appeared record on each tag|nil|
|
80
|
+
|title|title format. %s will be replaced with value specified by title_keys. title is created from the first appeared record on each tag. NOTE: This parameter must **not** be specified to receive Desktop Notification via Mentions in cases of Incoming Webhook and Slack Web API|nil|
|
81
81
|
|title_keys|keys used to format the title|nil|
|
82
82
|
|message|message format. %s will be replaced with value specified by message_keys|%s|
|
83
83
|
|message_keys|keys used to format messages|message|
|
@@ -97,6 +97,17 @@ fluent_logger.post('slack', {
|
|
97
97
|
|
98
98
|
`fluent-plugin-slack` is a kind of BufferedOutput plugin, so you can also use [Buffer Parameters](http://docs.fluentd.org/articles/out_exec#buffer-parameters).
|
99
99
|
|
100
|
+
## FAQ
|
101
|
+
|
102
|
+
### Desktop Notification seems not working?
|
103
|
+
|
104
|
+
Currently, slack.com has following limitations:
|
105
|
+
|
106
|
+
1. Desktop Notification via both Highlight Words and Mentions works only with Slackbot Remote Control
|
107
|
+
2. Desktop Notification via Mentions works for the `text` field if `link_names` parameter is specified in cases of Incoming Webhook and Slack Web API, that is,
|
108
|
+
* Desktop Notification does not work for the `attachments` filed (used in `color` and `title`)
|
109
|
+
* Desktop Notification via Highlight Words does not work for Incoming Webhook and Slack Web API anyway
|
110
|
+
|
100
111
|
## ChangeLog
|
101
112
|
|
102
113
|
See [CHANGELOG.md](CHANGELOG.md) for details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.6.0
|
@@ -14,11 +14,13 @@ module Fluent
|
|
14
14
|
config_param :webhook_url, :string, default: nil # incoming webhook
|
15
15
|
config_param :slackbot_url, :string, default: nil # slackbot
|
16
16
|
config_param :token, :string, default: nil # api token
|
17
|
-
config_param :username, :string, default:
|
18
|
-
config_param :color, :string, default:
|
17
|
+
config_param :username, :string, default: nil
|
18
|
+
config_param :color, :string, default: nil
|
19
19
|
config_param :icon_emoji, :string, default: nil
|
20
20
|
config_param :icon_url, :string, default: nil
|
21
|
-
config_param :mrkdwn, :bool, default:
|
21
|
+
config_param :mrkdwn, :bool, default: true
|
22
|
+
config_param :link_names, :bool, default: true
|
23
|
+
config_param :parse, :string, default: nil
|
22
24
|
config_param :auto_channels_create, :bool, default: false
|
23
25
|
config_param :https_proxy, :string, default: nil
|
24
26
|
|
@@ -56,25 +58,19 @@ module Fluent
|
|
56
58
|
if @webhook_url.empty?
|
57
59
|
raise Fluent::ConfigError.new("`webhook_url` is an empty string")
|
58
60
|
end
|
59
|
-
# following default values are for old version compatibility
|
60
|
-
@title ||= '%s'
|
61
|
-
@title_keys ||= %w[tag]
|
62
|
-
@message ||= '[%s] %s'
|
63
|
-
@message_keys ||= %w[time message]
|
64
61
|
@slack = Fluent::SlackClient::IncomingWebhook.new(@webhook_url)
|
65
62
|
elsif @slackbot_url
|
66
63
|
if @slackbot_url.empty?
|
67
64
|
raise Fluent::ConfigError.new("`slackbot_url` is an empty string")
|
68
65
|
end
|
69
|
-
@
|
70
|
-
|
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
|
71
69
|
@slack = Fluent::SlackClient::Slackbot.new(@slackbot_url)
|
72
70
|
elsif @token
|
73
71
|
if @token.empty?
|
74
72
|
raise Fluent::ConfigError.new("`token` is an empty string")
|
75
73
|
end
|
76
|
-
@message ||= '%s'
|
77
|
-
@message_keys ||= %w[message]
|
78
74
|
@slack = Fluent::SlackClient::WebApi.new
|
79
75
|
else
|
80
76
|
raise Fluent::ConfigError.new("One of `webhook_url` or `slackbot_url`, or `token` is required")
|
@@ -86,6 +82,8 @@ module Fluent
|
|
86
82
|
@slack.https_proxy = @https_proxy
|
87
83
|
end
|
88
84
|
|
85
|
+
@message ||= '%s'
|
86
|
+
@message_keys ||= %w[message]
|
89
87
|
begin
|
90
88
|
@message % (['1'] * @message_keys.length)
|
91
89
|
rescue ArgumentError
|
@@ -109,13 +107,16 @@ module Fluent
|
|
109
107
|
if @icon_emoji and @icon_url
|
110
108
|
raise Fluent::ConfigError, "either of `icon_emoji` or `icon_url` can be specified"
|
111
109
|
end
|
112
|
-
@icon_emoji ||= ':question:' unless @icon_url
|
113
110
|
|
114
111
|
if @mrkdwn
|
115
112
|
# Enable markdown for attachments. See https://api.slack.com/docs/formatting
|
116
113
|
@mrkdwn_in = %w[text fields]
|
117
114
|
end
|
118
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
|
+
|
119
120
|
@post_message_opts = @auto_channels_create ? {auto_channels_create: true} : {}
|
120
121
|
end
|
121
122
|
|
@@ -142,6 +143,8 @@ module Fluent
|
|
142
143
|
def build_payloads(chunk)
|
143
144
|
if @title
|
144
145
|
build_title_payloads(chunk)
|
146
|
+
elsif @color
|
147
|
+
build_color_payloads(chunk)
|
145
148
|
else
|
146
149
|
build_plain_payloads(chunk)
|
147
150
|
end
|
@@ -150,9 +153,12 @@ module Fluent
|
|
150
153
|
def common_payload
|
151
154
|
return @common_payload if @common_payload
|
152
155
|
@common_payload = {}
|
153
|
-
@common_payload[:username] = @username
|
156
|
+
@common_payload[:username] = @username if @username
|
154
157
|
@common_payload[:icon_emoji] = @icon_emoji if @icon_emoji
|
155
158
|
@common_payload[:icon_url] = @icon_url if @icon_url
|
159
|
+
@common_payload[:mrkdwn] = @mrkdwn if @mrkdwn
|
160
|
+
@common_payload[:link_names] = @link_names if @link_names
|
161
|
+
@common_payload[:parse] = @parse if @parse
|
156
162
|
@common_payload[:token] = @token if @token
|
157
163
|
@common_payload
|
158
164
|
end
|
@@ -160,7 +166,8 @@ module Fluent
|
|
160
166
|
def common_attachment
|
161
167
|
return @common_attachment if @common_attachment
|
162
168
|
@common_attachment = {}
|
163
|
-
@common_attachment[:
|
169
|
+
@common_attachment[:color] = @color if @color
|
170
|
+
@common_attachment[:mrkdwn_in] = @mrkdwn_in if @mrkdwn_in
|
164
171
|
@common_attachment
|
165
172
|
end
|
166
173
|
|
@@ -179,7 +186,6 @@ module Fluent
|
|
179
186
|
{
|
180
187
|
channel: channel,
|
181
188
|
attachments: [{
|
182
|
-
:color => @color,
|
183
189
|
:fallback => fields.values.map(&:title).join(' '), # fallback is the message shown on popup
|
184
190
|
:fields => fields.values.map(&:to_h)
|
185
191
|
}.merge(common_attachment)],
|
@@ -187,7 +193,7 @@ module Fluent
|
|
187
193
|
end
|
188
194
|
end
|
189
195
|
|
190
|
-
def
|
196
|
+
def build_color_payloads(chunk)
|
191
197
|
messages = {}
|
192
198
|
chunk.msgpack_each do |tag, time, record|
|
193
199
|
channel = build_channel(record)
|
@@ -198,7 +204,6 @@ module Fluent
|
|
198
204
|
{
|
199
205
|
channel: channel,
|
200
206
|
attachments: [{
|
201
|
-
:color => @color,
|
202
207
|
:fallback => text,
|
203
208
|
:text => text,
|
204
209
|
}.merge(common_attachment)],
|
@@ -206,6 +211,21 @@ module Fluent
|
|
206
211
|
end
|
207
212
|
end
|
208
213
|
|
214
|
+
def build_plain_payloads(chunk)
|
215
|
+
messages = {}
|
216
|
+
chunk.msgpack_each do |tag, time, record|
|
217
|
+
channel = build_channel(record)
|
218
|
+
messages[channel] ||= ''
|
219
|
+
messages[channel] << "#{build_message(record)}\n"
|
220
|
+
end
|
221
|
+
messages.map do |channel, text|
|
222
|
+
{
|
223
|
+
channel: channel,
|
224
|
+
text: text,
|
225
|
+
}.merge(common_payload)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
209
229
|
def build_message(record)
|
210
230
|
values = fetch_keys(record, @message_keys)
|
211
231
|
@message % values
|
@@ -14,11 +14,13 @@ module Fluent
|
|
14
14
|
config_param :webhook_url, :string, default: nil # incoming webhook
|
15
15
|
config_param :slackbot_url, :string, default: nil # slackbot
|
16
16
|
config_param :token, :string, default: nil # api token
|
17
|
-
config_param :username, :string, default:
|
18
|
-
config_param :color, :string, default:
|
17
|
+
config_param :username, :string, default: nil
|
18
|
+
config_param :color, :string, default: nil
|
19
19
|
config_param :icon_emoji, :string, default: nil
|
20
20
|
config_param :icon_url, :string, default: nil
|
21
|
-
config_param :mrkdwn, :bool, default:
|
21
|
+
config_param :mrkdwn, :bool, default: true
|
22
|
+
config_param :link_names, :bool, default: true
|
23
|
+
config_param :parse, :string, default: nil
|
22
24
|
config_param :auto_channels_create, :bool, default: false
|
23
25
|
config_param :https_proxy, :string, default: nil
|
24
26
|
|
@@ -56,25 +58,19 @@ module Fluent
|
|
56
58
|
if @webhook_url.empty?
|
57
59
|
raise Fluent::ConfigError.new("`webhook_url` is an empty string")
|
58
60
|
end
|
59
|
-
# following default values are for old version compatibility
|
60
|
-
@title ||= '%s'
|
61
|
-
@title_keys ||= %w[tag]
|
62
|
-
@message ||= '[%s] %s'
|
63
|
-
@message_keys ||= %w[time message]
|
64
61
|
@slack = Fluent::SlackClient::IncomingWebhook.new(@webhook_url)
|
65
62
|
elsif @slackbot_url
|
66
63
|
if @slackbot_url.empty?
|
67
64
|
raise Fluent::ConfigError.new("`slackbot_url` is an empty string")
|
68
65
|
end
|
69
|
-
@
|
70
|
-
|
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
|
71
69
|
@slack = Fluent::SlackClient::Slackbot.new(@slackbot_url)
|
72
70
|
elsif @token
|
73
71
|
if @token.empty?
|
74
72
|
raise Fluent::ConfigError.new("`token` is an empty string")
|
75
73
|
end
|
76
|
-
@message ||= '%s'
|
77
|
-
@message_keys ||= %w[message]
|
78
74
|
@slack = Fluent::SlackClient::WebApi.new
|
79
75
|
else
|
80
76
|
raise Fluent::ConfigError.new("One of `webhook_url` or `slackbot_url`, or `token` is required")
|
@@ -86,6 +82,8 @@ module Fluent
|
|
86
82
|
@slack.https_proxy = @https_proxy
|
87
83
|
end
|
88
84
|
|
85
|
+
@message ||= '%s'
|
86
|
+
@message_keys ||= %w[message]
|
89
87
|
begin
|
90
88
|
@message % (['1'] * @message_keys.length)
|
91
89
|
rescue ArgumentError
|
@@ -109,13 +107,16 @@ module Fluent
|
|
109
107
|
if @icon_emoji and @icon_url
|
110
108
|
raise Fluent::ConfigError, "either of `icon_emoji` or `icon_url` can be specified"
|
111
109
|
end
|
112
|
-
@icon_emoji ||= ':question:' unless @icon_url
|
113
110
|
|
114
111
|
if @mrkdwn
|
115
112
|
# Enable markdown for attachments. See https://api.slack.com/docs/formatting
|
116
113
|
@mrkdwn_in = %w[text fields]
|
117
114
|
end
|
118
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
|
+
|
119
120
|
@post_message_opts = @auto_channels_create ? {auto_channels_create: true} : {}
|
120
121
|
end
|
121
122
|
|
@@ -142,6 +143,8 @@ module Fluent
|
|
142
143
|
def build_payloads(chunk)
|
143
144
|
if @title
|
144
145
|
build_title_payloads(chunk)
|
146
|
+
elsif @color
|
147
|
+
build_color_payloads(chunk)
|
145
148
|
else
|
146
149
|
build_plain_payloads(chunk)
|
147
150
|
end
|
@@ -150,9 +153,12 @@ module Fluent
|
|
150
153
|
def common_payload
|
151
154
|
return @common_payload if @common_payload
|
152
155
|
@common_payload = {}
|
153
|
-
@common_payload[:username] = @username
|
156
|
+
@common_payload[:username] = @username if @username
|
154
157
|
@common_payload[:icon_emoji] = @icon_emoji if @icon_emoji
|
155
158
|
@common_payload[:icon_url] = @icon_url if @icon_url
|
159
|
+
@common_payload[:mrkdwn] = @mrkdwn if @mrkdwn
|
160
|
+
@common_payload[:link_names] = @link_names if @link_names
|
161
|
+
@common_payload[:parse] = @parse if @parse
|
156
162
|
@common_payload[:token] = @token if @token
|
157
163
|
@common_payload
|
158
164
|
end
|
@@ -160,7 +166,8 @@ module Fluent
|
|
160
166
|
def common_attachment
|
161
167
|
return @common_attachment if @common_attachment
|
162
168
|
@common_attachment = {}
|
163
|
-
@common_attachment[:
|
169
|
+
@common_attachment[:color] = @color if @color
|
170
|
+
@common_attachment[:mrkdwn_in] = @mrkdwn_in if @mrkdwn_in
|
164
171
|
@common_attachment
|
165
172
|
end
|
166
173
|
|
@@ -179,7 +186,6 @@ module Fluent
|
|
179
186
|
{
|
180
187
|
channel: channel,
|
181
188
|
attachments: [{
|
182
|
-
:color => @color,
|
183
189
|
:fallback => fields.values.map(&:title).join(' '), # fallback is the message shown on popup
|
184
190
|
:fields => fields.values.map(&:to_h)
|
185
191
|
}.merge(common_attachment)],
|
@@ -187,7 +193,7 @@ module Fluent
|
|
187
193
|
end
|
188
194
|
end
|
189
195
|
|
190
|
-
def
|
196
|
+
def build_color_payloads(chunk)
|
191
197
|
messages = {}
|
192
198
|
chunk.msgpack_each do |tag, time, record|
|
193
199
|
channel = build_channel(record)
|
@@ -198,7 +204,6 @@ module Fluent
|
|
198
204
|
{
|
199
205
|
channel: channel,
|
200
206
|
attachments: [{
|
201
|
-
:color => @color,
|
202
207
|
:fallback => text,
|
203
208
|
:text => text,
|
204
209
|
}.merge(common_attachment)],
|
@@ -206,6 +211,21 @@ module Fluent
|
|
206
211
|
end
|
207
212
|
end
|
208
213
|
|
214
|
+
def build_plain_payloads(chunk)
|
215
|
+
messages = {}
|
216
|
+
chunk.msgpack_each do |tag, time, record|
|
217
|
+
channel = build_channel(record)
|
218
|
+
messages[channel] ||= ''
|
219
|
+
messages[channel] << "#{build_message(record)}\n"
|
220
|
+
end
|
221
|
+
messages.map do |channel, text|
|
222
|
+
{
|
223
|
+
channel: channel,
|
224
|
+
text: text,
|
225
|
+
}.merge(common_payload)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
209
229
|
def build_message(record)
|
210
230
|
values = fetch_keys(record, @message_keys)
|
211
231
|
@message % values
|
@@ -151,8 +151,12 @@ module Fluent
|
|
151
151
|
end
|
152
152
|
|
153
153
|
def encode_body(params = {})
|
154
|
-
|
155
|
-
|
154
|
+
return params[:text]if params[:text]
|
155
|
+
unless params[:attachments]
|
156
|
+
raise ArgumentError, 'params[:text] or params[:attachments] is required'
|
157
|
+
end
|
158
|
+
# handle params[:attachments]
|
159
|
+
attachment = Array(params[:attachments]).first # see only the first for now
|
156
160
|
# {
|
157
161
|
# attachments: [{
|
158
162
|
# text: "HERE",
|
@@ -168,7 +172,7 @@ module Fluent
|
|
168
172
|
# }]
|
169
173
|
# }
|
170
174
|
if text.nil? and attachment[:fields]
|
171
|
-
text = Array(attachment[:fields]).first[:value] #
|
175
|
+
text = Array(attachment[:fields]).first[:value] # see only the first for now
|
172
176
|
end
|
173
177
|
text
|
174
178
|
end
|
@@ -12,9 +12,23 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
12
12
|
|
13
13
|
CONFIG = %[
|
14
14
|
channel channel
|
15
|
-
|
15
|
+
webhook_url https://hooks.slack.com/services/XXXX/XXXX/XXX
|
16
16
|
]
|
17
17
|
|
18
|
+
def default_payload
|
19
|
+
{
|
20
|
+
channel: '#channel',
|
21
|
+
mrkdwn: true,
|
22
|
+
link_names: true,
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def default_attachment
|
27
|
+
{
|
28
|
+
mrkdwn_in: %w[text fields],
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
18
32
|
def create_driver(conf = CONFIG)
|
19
33
|
Fluent::Test::BufferedOutputTestDriver.new(Fluent::SlackOutput).configure(conf)
|
20
34
|
end
|
@@ -23,12 +37,15 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
23
37
|
def test_old_config
|
24
38
|
# default check
|
25
39
|
d = create_driver
|
26
|
-
assert_equal true,
|
27
|
-
assert_equal
|
28
|
-
assert_equal
|
29
|
-
assert_equal ':question:'
|
40
|
+
assert_equal true, d.instance.localtime
|
41
|
+
assert_equal nil, d.instance.username # 'fluentd' break lower version compatibility
|
42
|
+
assert_equal nil, d.instance.color # 'good' break lower version compatibility
|
43
|
+
assert_equal nil, d.instance.icon_emoji # ':question:' break lower version compatibility
|
44
|
+
assert_equal nil, d.instance.icon_url
|
45
|
+
assert_equal true, d.instance.mrkdwn
|
46
|
+
assert_equal true, d.instance.link_names
|
47
|
+
assert_equal nil, d.instance.parse
|
30
48
|
|
31
|
-
# incoming webhook endpoint was changed. api_key option should be ignored
|
32
49
|
assert_nothing_raised do
|
33
50
|
create_driver(CONFIG + %[api_key testtoken])
|
34
51
|
end
|
@@ -84,7 +101,9 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
84
101
|
assert_raise(Fluent::ConfigError) do
|
85
102
|
create_driver(CONFIG + %[channel %s %s\nchannel_keys foo])
|
86
103
|
end
|
104
|
+
end
|
87
105
|
|
106
|
+
def test_slack_configure
|
88
107
|
# One of webhook_url or slackbot_url, or token is required
|
89
108
|
assert_raise(Fluent::ConfigError) do
|
90
109
|
create_driver(%[channel foo])
|
@@ -146,7 +165,7 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
146
165
|
def test_icon_configure
|
147
166
|
# default
|
148
167
|
d = create_driver(CONFIG)
|
149
|
-
assert_equal
|
168
|
+
assert_equal nil, d.instance.icon_emoji
|
150
169
|
assert_equal nil, d.instance.icon_url
|
151
170
|
|
152
171
|
# either of icon_emoji or icon_url can be specified
|
@@ -165,28 +184,66 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
165
184
|
assert_equal @icon_url, d.instance.icon_url
|
166
185
|
end
|
167
186
|
|
168
|
-
def
|
187
|
+
def test_link_names_configure
|
169
188
|
# default
|
170
189
|
d = create_driver(CONFIG)
|
171
|
-
assert_equal
|
172
|
-
assert_equal Net::HTTP, d.instance.slack.proxy_class
|
190
|
+
assert_equal true, d.instance.link_names
|
173
191
|
|
174
|
-
#
|
175
|
-
d = create_driver(CONFIG + %[
|
176
|
-
assert_equal
|
177
|
-
|
192
|
+
# true
|
193
|
+
d = create_driver(CONFIG + %[link_names true])
|
194
|
+
assert_equal true, d.instance.link_names
|
195
|
+
|
196
|
+
# false
|
197
|
+
d = create_driver(CONFIG + %[link_names false])
|
198
|
+
assert_equal false, d.instance.link_names
|
199
|
+
end
|
200
|
+
|
201
|
+
def test_parse_configure
|
202
|
+
# default
|
203
|
+
d = create_driver(CONFIG)
|
204
|
+
assert_equal nil, d.instance.parse
|
205
|
+
|
206
|
+
# none
|
207
|
+
d = create_driver(CONFIG + %[parse none])
|
208
|
+
assert_equal 'none', d.instance.parse
|
209
|
+
|
210
|
+
# full
|
211
|
+
d = create_driver(CONFIG + %[parse full])
|
212
|
+
assert_equal 'full', d.instance.parse
|
213
|
+
|
214
|
+
# invalid
|
215
|
+
assert_raise(Fluent::ConfigError) do
|
216
|
+
d = create_driver(CONFIG + %[parse invalid])
|
217
|
+
end
|
178
218
|
end
|
179
219
|
|
180
220
|
def test_mrkwn_configure
|
181
221
|
# default
|
182
222
|
d = create_driver(CONFIG)
|
183
|
-
assert_equal
|
184
|
-
assert_equal
|
223
|
+
assert_equal true, d.instance.mrkdwn
|
224
|
+
assert_equal %w[text fields], d.instance.mrkdwn_in
|
185
225
|
|
186
|
-
#
|
226
|
+
# true
|
187
227
|
d = create_driver(CONFIG + %[mrkdwn true])
|
188
228
|
assert_equal true, d.instance.mrkdwn
|
189
229
|
assert_equal %w[text fields], d.instance.mrkdwn_in
|
230
|
+
|
231
|
+
# false
|
232
|
+
d = create_driver(CONFIG + %[mrkdwn false])
|
233
|
+
assert_equal false, d.instance.mrkdwn
|
234
|
+
assert_equal nil, d.instance.mrkdwn_in
|
235
|
+
end
|
236
|
+
|
237
|
+
def test_https_proxy_configure
|
238
|
+
# default
|
239
|
+
d = create_driver(CONFIG)
|
240
|
+
assert_equal nil, d.instance.slack.https_proxy
|
241
|
+
assert_equal Net::HTTP, d.instance.slack.proxy_class
|
242
|
+
|
243
|
+
# https_proxy
|
244
|
+
d = create_driver(CONFIG + %[https_proxy https://proxy.foo.bar:443])
|
245
|
+
assert_equal URI.parse('https://proxy.foo.bar:443'), d.instance.slack.https_proxy
|
246
|
+
assert_not_equal Net::HTTP, d.instance.slack.proxy_class # Net::HTTP.Proxy
|
190
247
|
end
|
191
248
|
|
192
249
|
def test_default_incoming_webhook
|
@@ -197,19 +254,9 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
197
254
|
assert_equal Fluent::SlackClient::IncomingWebhook, d.instance.slack.class
|
198
255
|
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
199
256
|
d.tag = 'test'
|
200
|
-
mock(d.instance.slack).post_message({
|
201
|
-
|
202
|
-
|
203
|
-
icon_emoji: ':question:',
|
204
|
-
attachments: [{
|
205
|
-
color: 'good',
|
206
|
-
fallback: 'test',
|
207
|
-
fields: [{
|
208
|
-
title: 'test',
|
209
|
-
value: "[07:00:00] sowawa1\n[07:00:00] sowawa2\n",
|
210
|
-
}],
|
211
|
-
}]
|
212
|
-
}, {})
|
257
|
+
mock(d.instance.slack).post_message(default_payload.merge({
|
258
|
+
text: "sowawa1\nsowawa2\n",
|
259
|
+
}), {})
|
213
260
|
with_timezone('Asia/Tokyo') do
|
214
261
|
d.emit({message: 'sowawa1'}, time)
|
215
262
|
d.emit({message: 'sowawa2'}, time)
|
@@ -225,16 +272,9 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
225
272
|
assert_equal Fluent::SlackClient::Slackbot, d.instance.slack.class
|
226
273
|
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
227
274
|
d.tag = 'test'
|
228
|
-
mock(d.instance.slack).post_message({
|
229
|
-
|
230
|
-
|
231
|
-
icon_emoji: ':question:',
|
232
|
-
attachments: [{
|
233
|
-
color: 'good',
|
234
|
-
fallback: "sowawa1\nsowawa2\n",
|
235
|
-
text: "sowawa1\nsowawa2\n",
|
236
|
-
}]
|
237
|
-
}, {})
|
275
|
+
mock(d.instance.slack).post_message(default_payload.merge({
|
276
|
+
text: "sowawa1\nsowawa2\n",
|
277
|
+
}), {})
|
238
278
|
with_timezone('Asia/Tokyo') do
|
239
279
|
d.emit({message: 'sowawa1'}, time)
|
240
280
|
d.emit({message: 'sowawa2'}, time)
|
@@ -250,17 +290,69 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
250
290
|
assert_equal Fluent::SlackClient::WebApi, d.instance.slack.class
|
251
291
|
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
252
292
|
d.tag = 'test'
|
253
|
-
mock(d.instance.slack).post_message({
|
254
|
-
token:
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
293
|
+
mock(d.instance.slack).post_message(default_payload.merge({
|
294
|
+
token: 'XX-XX-XX',
|
295
|
+
text: "sowawa1\nsowawa2\n",
|
296
|
+
}), {})
|
297
|
+
with_timezone('Asia/Tokyo') do
|
298
|
+
d.emit({message: 'sowawa1'}, time)
|
299
|
+
d.emit({message: 'sowawa2'}, time)
|
300
|
+
d.run
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
def test_title_payload
|
305
|
+
title = "mytitle"
|
306
|
+
d = create_driver(CONFIG + %[title #{title}])
|
307
|
+
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
308
|
+
d.tag = 'test'
|
309
|
+
# attachments field should be changed to show the title
|
310
|
+
mock(d.instance.slack).post_message(default_payload.merge({
|
311
|
+
attachments: [default_attachment.merge({
|
312
|
+
fallback: title,
|
313
|
+
fields: [
|
314
|
+
{
|
315
|
+
title: title,
|
316
|
+
value: "sowawa1\nsowawa2\n",
|
317
|
+
}
|
318
|
+
],
|
319
|
+
})]
|
320
|
+
}), {})
|
321
|
+
with_timezone('Asia/Tokyo') do
|
322
|
+
d.emit({message: 'sowawa1'}, time)
|
323
|
+
d.emit({message: 'sowawa2'}, time)
|
324
|
+
d.run
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
def test_color_payload
|
329
|
+
color = 'good'
|
330
|
+
d = create_driver(CONFIG + %[color #{color}])
|
331
|
+
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
332
|
+
d.tag = 'test'
|
333
|
+
# attachments field should be changed to show the title
|
334
|
+
mock(d.instance.slack).post_message(default_payload.merge({
|
335
|
+
attachments: [default_attachment.merge({
|
336
|
+
color: color,
|
260
337
|
fallback: "sowawa1\nsowawa2\n",
|
261
338
|
text: "sowawa1\nsowawa2\n",
|
262
|
-
}]
|
263
|
-
}, {})
|
339
|
+
})]
|
340
|
+
}), {})
|
341
|
+
with_timezone('Asia/Tokyo') do
|
342
|
+
d.emit({message: 'sowawa1'}, time)
|
343
|
+
d.emit({message: 'sowawa2'}, time)
|
344
|
+
d.run
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
def test_plain_payload
|
349
|
+
d = create_driver(CONFIG)
|
350
|
+
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
351
|
+
d.tag = 'test'
|
352
|
+
# attachments field should be changed to show the title
|
353
|
+
mock(d.instance.slack).post_message(default_payload.merge({
|
354
|
+
text: "sowawa1\nsowawa2\n",
|
355
|
+
}), {})
|
264
356
|
with_timezone('Asia/Tokyo') do
|
265
357
|
d.emit({message: 'sowawa1'}, time)
|
266
358
|
d.emit({message: 'sowawa2'}, time)
|
@@ -269,26 +361,21 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
269
361
|
end
|
270
362
|
|
271
363
|
def test_title_keys
|
272
|
-
d = create_driver(CONFIG + %[title %s\ntitle_keys tag])
|
364
|
+
d = create_driver(CONFIG + %[title [%s] %s\ntitle_keys time,tag])
|
273
365
|
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
274
366
|
d.tag = 'test'
|
275
367
|
# attachments field should be changed to show the title
|
276
|
-
mock(d.instance.slack).post_message({
|
277
|
-
|
278
|
-
|
279
|
-
username: 'fluentd',
|
280
|
-
icon_emoji: ':question:',
|
281
|
-
attachments: [{
|
282
|
-
color: 'good',
|
283
|
-
fallback: d.tag,
|
368
|
+
mock(d.instance.slack).post_message(default_payload.merge({
|
369
|
+
attachments: [default_attachment.merge({
|
370
|
+
fallback: "[07:00:00] #{d.tag}",
|
284
371
|
fields: [
|
285
372
|
{
|
286
|
-
title: d.tag,
|
373
|
+
title: "[07:00:00] #{d.tag}",
|
287
374
|
value: "sowawa1\nsowawa2\n",
|
288
375
|
}
|
289
376
|
],
|
290
|
-
}]
|
291
|
-
}, {})
|
377
|
+
})]
|
378
|
+
}), {})
|
292
379
|
with_timezone('Asia/Tokyo') do
|
293
380
|
d.emit({message: 'sowawa1'}, time)
|
294
381
|
d.emit({message: 'sowawa2'}, time)
|
@@ -297,20 +384,12 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
297
384
|
end
|
298
385
|
|
299
386
|
def test_message_keys
|
300
|
-
d = create_driver(CONFIG + %[message %s %s\nmessage_keys tag,message])
|
387
|
+
d = create_driver(CONFIG + %[message [%s] %s %s\nmessage_keys time,tag,message])
|
301
388
|
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
302
389
|
d.tag = 'test'
|
303
|
-
mock(d.instance.slack).post_message({
|
304
|
-
|
305
|
-
|
306
|
-
username: 'fluentd',
|
307
|
-
icon_emoji: ':question:',
|
308
|
-
attachments: [{
|
309
|
-
color: 'good',
|
310
|
-
fallback: "test sowawa1\ntest sowawa2\n",
|
311
|
-
text: "test sowawa1\ntest sowawa2\n",
|
312
|
-
}]
|
313
|
-
}, {})
|
390
|
+
mock(d.instance.slack).post_message(default_payload.merge({
|
391
|
+
text: "[07:00:00] test sowawa1\n[07:00:00] test sowawa2\n",
|
392
|
+
}), {})
|
314
393
|
with_timezone('Asia/Tokyo') do
|
315
394
|
d.emit({message: 'sowawa1'}, time)
|
316
395
|
d.emit({message: 'sowawa2'}, time)
|
@@ -322,28 +401,14 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
322
401
|
d = create_driver(CONFIG + %[channel %s\nchannel_keys channel])
|
323
402
|
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
324
403
|
d.tag = 'test'
|
325
|
-
mock(d.instance.slack).post_message({
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
text: "sowawa1\n",
|
334
|
-
}]
|
335
|
-
}, {})
|
336
|
-
mock(d.instance.slack).post_message({
|
337
|
-
token: 'XXX-XXX-XXX',
|
338
|
-
channel: '#channel2',
|
339
|
-
username: 'fluentd',
|
340
|
-
icon_emoji: ':question:',
|
341
|
-
attachments: [{
|
342
|
-
color: 'good',
|
343
|
-
fallback: "sowawa2\n",
|
344
|
-
text: "sowawa2\n",
|
345
|
-
}]
|
346
|
-
}, {})
|
404
|
+
mock(d.instance.slack).post_message(default_payload.merge({
|
405
|
+
channel: '#channel1',
|
406
|
+
text: "sowawa1\n",
|
407
|
+
}), {})
|
408
|
+
mock(d.instance.slack).post_message(default_payload.merge({
|
409
|
+
channel: '#channel2',
|
410
|
+
text: "sowawa2\n",
|
411
|
+
}), {})
|
347
412
|
with_timezone('Asia/Tokyo') do
|
348
413
|
d.emit({message: 'sowawa1', channel: 'channel1'}, time)
|
349
414
|
d.emit({message: 'sowawa2', channel: 'channel2'}, time)
|
@@ -355,17 +420,10 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
355
420
|
d = create_driver(CONFIG + %[icon_emoji :ghost:])
|
356
421
|
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
357
422
|
d.tag = 'test'
|
358
|
-
mock(d.instance.slack).post_message({
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
icon_emoji: ':ghost:',
|
363
|
-
attachments: [{
|
364
|
-
color: 'good',
|
365
|
-
fallback: "foo\n",
|
366
|
-
text: "foo\n",
|
367
|
-
}]
|
368
|
-
}, {})
|
423
|
+
mock(d.instance.slack).post_message(default_payload.merge({
|
424
|
+
icon_emoji: ':ghost:',
|
425
|
+
text: "foo\n",
|
426
|
+
}), {})
|
369
427
|
with_timezone('Asia/Tokyo') do
|
370
428
|
d.emit({message: 'foo'}, time)
|
371
429
|
d.run
|
@@ -376,17 +434,10 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
376
434
|
d = create_driver(CONFIG + %[icon_url #{@icon_url}])
|
377
435
|
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
378
436
|
d.tag = 'test'
|
379
|
-
mock(d.instance.slack).post_message({
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
icon_url: @icon_url,
|
384
|
-
attachments: [{
|
385
|
-
color: 'good',
|
386
|
-
fallback: "foo\n",
|
387
|
-
text: "foo\n",
|
388
|
-
}]
|
389
|
-
}, {})
|
437
|
+
mock(d.instance.slack).post_message(default_payload.merge({
|
438
|
+
icon_url: @icon_url,
|
439
|
+
text: "foo\n",
|
440
|
+
}), {})
|
390
441
|
with_timezone('Asia/Tokyo') do
|
391
442
|
d.emit({message: 'foo'}, time)
|
392
443
|
d.run
|
@@ -397,18 +448,56 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
397
448
|
d = create_driver(CONFIG + %[mrkdwn true])
|
398
449
|
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
399
450
|
d.tag = 'test'
|
400
|
-
mock(d.instance.slack).post_message({
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
451
|
+
mock(d.instance.slack).post_message(default_payload.merge({
|
452
|
+
mrkdwn: true,
|
453
|
+
text: "foo\n",
|
454
|
+
}), {})
|
455
|
+
with_timezone('Asia/Tokyo') do
|
456
|
+
d.emit({message: 'foo'}, time)
|
457
|
+
d.run
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
461
|
+
def test_mrkdwn_in
|
462
|
+
d = create_driver(CONFIG + %[mrkdwn true\ncolor good])
|
463
|
+
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
464
|
+
d.tag = 'test'
|
465
|
+
mock(d.instance.slack).post_message(default_payload.merge({
|
466
|
+
attachments: [default_attachment.merge({
|
467
|
+
color: "good",
|
407
468
|
fallback: "foo\n",
|
408
469
|
text: "foo\n",
|
409
470
|
mrkdwn_in: ["text", "fields"],
|
410
|
-
}]
|
411
|
-
}, {})
|
471
|
+
})]
|
472
|
+
}), {})
|
473
|
+
with_timezone('Asia/Tokyo') do
|
474
|
+
d.emit({message: 'foo'}, time)
|
475
|
+
d.run
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
def test_link_names
|
480
|
+
d = create_driver(CONFIG + %[link_names true])
|
481
|
+
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
482
|
+
d.tag = 'test'
|
483
|
+
mock(d.instance.slack).post_message(default_payload.merge({
|
484
|
+
link_names: true,
|
485
|
+
text: "foo\n",
|
486
|
+
}), {})
|
487
|
+
with_timezone('Asia/Tokyo') do
|
488
|
+
d.emit({message: 'foo'}, time)
|
489
|
+
d.run
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
493
|
+
def test_parse
|
494
|
+
d = create_driver(CONFIG + %[parse full])
|
495
|
+
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
496
|
+
d.tag = 'test'
|
497
|
+
mock(d.instance.slack).post_message(default_payload.merge({
|
498
|
+
parse: "full",
|
499
|
+
text: "foo\n",
|
500
|
+
}), {})
|
412
501
|
with_timezone('Asia/Tokyo') do
|
413
502
|
d.emit({message: 'foo'}, time)
|
414
503
|
d.run
|
@@ -10,10 +10,11 @@ require 'webrick/httpproxy'
|
|
10
10
|
# Create .env file with contents as:
|
11
11
|
#
|
12
12
|
# WEBHOOK_URL=https://hooks.slack.com/services/XXXX/YYYY/ZZZZ
|
13
|
-
#
|
13
|
+
# SLACKBOt_URL=https://xxxx.slack.com/services/hooks/slackbot?token=XXXX
|
14
|
+
# SLACK_API_TOKEN=XXXXX
|
14
15
|
#
|
15
16
|
Dotenv.load
|
16
|
-
if ENV['WEBHOOK_URL'] and ENV['SLACKBOT_URL'] and ENV['
|
17
|
+
if ENV['WEBHOOK_URL'] and ENV['SLACKBOT_URL'] and ENV['SLACK_API_TOKEN']
|
17
18
|
|
18
19
|
class TestProxyServer
|
19
20
|
def initialize
|
@@ -47,152 +48,148 @@ if ENV['WEBHOOK_URL'] and ENV['SLACKBOT_URL'] and ENV['TOKEN']
|
|
47
48
|
end
|
48
49
|
|
49
50
|
class SlackClientTest < Test::Unit::TestCase
|
51
|
+
class << self
|
52
|
+
attr_reader :proxy
|
53
|
+
|
54
|
+
def startup
|
55
|
+
@proxy = TestProxyServer.new.tap {|proxy| proxy.start }
|
56
|
+
end
|
57
|
+
|
58
|
+
def shutdown
|
59
|
+
@proxy.shutdown
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
50
63
|
def setup
|
51
64
|
super
|
52
65
|
@incoming = Fluent::SlackClient::IncomingWebhook.new(ENV['WEBHOOK_URL'])
|
53
66
|
@slackbot = Fluent::SlackClient::Slackbot.new(ENV['SLACKBOT_URL'])
|
54
67
|
@api = Fluent::SlackClient::WebApi.new
|
55
68
|
|
56
|
-
|
57
|
-
@incoming_proxy = Fluent::SlackClient::IncomingWebhook.new(ENV['WEBHOOK_URL'],
|
58
|
-
@slackbot_proxy = Fluent::SlackClient::Slackbot.new(ENV['SLACKBOT_URL'],
|
59
|
-
@api_proxy = Fluent::SlackClient::WebApi.new(nil,
|
69
|
+
proxy_url = self.class.proxy.proxy_url
|
70
|
+
@incoming_proxy = Fluent::SlackClient::IncomingWebhook.new(ENV['WEBHOOK_URL'], proxy_url)
|
71
|
+
@slackbot_proxy = Fluent::SlackClient::Slackbot.new(ENV['SLACKBOT_URL'], proxy_url)
|
72
|
+
@api_proxy = Fluent::SlackClient::WebApi.new(nil, proxy_url)
|
60
73
|
|
61
74
|
@icon_url = 'http://www.google.com/s2/favicons?domain=www.google.de'
|
62
75
|
end
|
63
76
|
|
64
|
-
def
|
65
|
-
|
77
|
+
def token(client)
|
78
|
+
client.is_a?(Fluent::SlackClient::IncomingWebhook) ? {} : {token: ENV['SLACK_API_TOKEN']}
|
66
79
|
end
|
67
80
|
|
68
|
-
def
|
69
|
-
|
81
|
+
def default_payload(client)
|
82
|
+
{
|
83
|
+
channel: '#general',
|
84
|
+
mrkdwn: true,
|
85
|
+
link_names: true,
|
86
|
+
}.merge!(token(client))
|
70
87
|
end
|
71
88
|
|
72
|
-
def
|
89
|
+
def default_attachment
|
90
|
+
{
|
91
|
+
mrkdwn_in: %w[text fields]
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
# Notification via Mention works for all three with plain text payload
|
96
|
+
def test_post_message_plain_payload_mention
|
73
97
|
[@incoming, @slackbot, @api].each do |slack|
|
74
98
|
assert_nothing_raised do
|
75
|
-
slack.post_message(
|
76
|
-
|
77
|
-
|
78
|
-
username: 'fluentd',
|
79
|
-
icon_emoji: ':question:',
|
80
|
-
attachments: [{
|
81
|
-
color: 'good',
|
82
|
-
fallback: "sowawa1\nsowawa2\n",
|
83
|
-
text: "sowawa1\nsowawa2\n",
|
84
|
-
}]
|
85
|
-
}.merge(token(slack))
|
86
|
-
)
|
99
|
+
slack.post_message(default_payload(slack).merge({
|
100
|
+
text: "#general @everyone\n",
|
101
|
+
}))
|
87
102
|
end
|
88
103
|
end
|
89
104
|
end
|
90
105
|
|
91
|
-
|
106
|
+
# Notification via Highlight Words works with only Slackbot with plain text payload
|
107
|
+
# NOTE: Please add `sowawa1` to Highlight Words
|
108
|
+
def test_post_message_plain_payload_highlight_words
|
92
109
|
[@incoming, @slackbot, @api].each do |slack|
|
93
110
|
assert_nothing_raised do
|
94
|
-
slack.post_message(
|
95
|
-
|
96
|
-
|
97
|
-
username: 'fluentd',
|
98
|
-
icon_emoji: ':question:',
|
99
|
-
attachments: [{
|
100
|
-
color: 'good',
|
101
|
-
fallback: 'test1 test2',
|
102
|
-
fields: [
|
103
|
-
{
|
104
|
-
title: 'test1',
|
105
|
-
value: "[07:00:00] sowawa1\n[07:00:00] sowawa2\n",
|
106
|
-
},
|
107
|
-
{
|
108
|
-
title: 'test2',
|
109
|
-
value: "[07:00:00] sowawa1\n[07:00:00] sowawa2\n",
|
110
|
-
},
|
111
|
-
],
|
112
|
-
}]
|
113
|
-
}.merge(token(slack))
|
114
|
-
)
|
111
|
+
slack.post_message(default_payload(slack).merge({
|
112
|
+
text: "sowawa1\n",
|
113
|
+
}))
|
115
114
|
end
|
116
115
|
end
|
117
116
|
end
|
118
117
|
|
119
|
-
|
120
|
-
|
118
|
+
# Notification via Mention does not work for attachments
|
119
|
+
def test_post_message_color_payload
|
120
|
+
[@incoming, @slackbot, @api].each do |slack|
|
121
121
|
assert_nothing_raised do
|
122
|
-
slack.post_message(
|
123
|
-
{
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
fallback: "sowawa1\nsowawa2\n",
|
130
|
-
text: "sowawa1\nsowawa2\n",
|
131
|
-
}]
|
132
|
-
}.merge(token(slack))
|
133
|
-
)
|
122
|
+
slack.post_message(default_payload(slack).merge({
|
123
|
+
attachments: [default_attachment.merge({
|
124
|
+
color: 'good',
|
125
|
+
fallback: "sowawa1\n@everyone\n",
|
126
|
+
text: "sowawa1\n@everyone\n",
|
127
|
+
})]
|
128
|
+
}))
|
134
129
|
end
|
135
130
|
end
|
136
131
|
end
|
137
132
|
|
138
|
-
|
139
|
-
|
133
|
+
# Notification via Mention does not work for attachments
|
134
|
+
def test_post_message_fields_payload
|
135
|
+
[@incoming, @slackbot, @api].each do |slack|
|
136
|
+
assert_nothing_raised do
|
137
|
+
slack.post_message(default_payload(slack).merge({
|
138
|
+
attachments: [default_attachment.merge({
|
139
|
+
color: 'good',
|
140
|
+
fallback: 'test1 test2',
|
141
|
+
fields: [
|
142
|
+
{
|
143
|
+
title: 'test1',
|
144
|
+
value: "[07:00:00] sowawa1\n[07:00:00] @everyone\n",
|
145
|
+
},
|
146
|
+
{
|
147
|
+
title: 'test2',
|
148
|
+
value: "[07:00:00] sowawa1\n[07:00:00] @everyone\n",
|
149
|
+
},
|
150
|
+
],
|
151
|
+
})]
|
152
|
+
}))
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_post_via_proxy
|
158
|
+
[@incoming_proxy, @slackbot_proxy, @api_proxy].each do |slack|
|
140
159
|
assert_nothing_raised do
|
141
|
-
slack.post_message(
|
142
|
-
{
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
fallback: "sowawa1\nsowawa2\n",
|
149
|
-
text: "sowawa1\nsowawa2\n",
|
150
|
-
}]
|
151
|
-
}.merge(token(slack))
|
152
|
-
)
|
160
|
+
slack.post_message(default_payload(slack).merge({
|
161
|
+
attachments: [default_attachment.merge({
|
162
|
+
color: 'good',
|
163
|
+
fallback: "sowawa1\n@everyone\n",
|
164
|
+
text: "sowawa1\n@everyone\n",
|
165
|
+
})]
|
166
|
+
}))
|
153
167
|
end
|
154
168
|
end
|
155
169
|
end
|
156
170
|
|
157
|
-
def
|
171
|
+
def test_post_message_username
|
158
172
|
[@incoming, @api].each do |slack|
|
159
173
|
assert_nothing_raised do
|
160
|
-
slack.post_message(
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
attachments: [{
|
165
|
-
color: 'good',
|
166
|
-
fallback: "plain *bold* _italic_ `preformat`\n", # mrkdwn not work
|
167
|
-
text: "plain *bold* _italic_ `preformat`\n",
|
168
|
-
mrkdwn_in: ['text', 'fields'],
|
169
|
-
}]
|
170
|
-
}.merge(token(slack))
|
171
|
-
)
|
174
|
+
slack.post_message(default_payload(slack).merge({
|
175
|
+
username: 'fluentd',
|
176
|
+
text: "#general @everyone\n",
|
177
|
+
}))
|
172
178
|
end
|
173
179
|
end
|
174
180
|
end
|
175
181
|
|
176
|
-
def
|
182
|
+
def test_post_message_icon_url
|
177
183
|
[@incoming, @api].each do |slack|
|
178
184
|
assert_nothing_raised do
|
179
|
-
slack.post_message(
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
{
|
188
|
-
title: 'plain *bold* _italic* `preformat`', # mrkdwn not work
|
189
|
-
value: "plain *bold* _italic* `preformat`\n",
|
190
|
-
},
|
191
|
-
],
|
192
|
-
mrkdwn_in: ['text', 'fields'],
|
193
|
-
}]
|
194
|
-
}.merge(token(slack))
|
195
|
-
)
|
185
|
+
slack.post_message(default_payload(slack).merge({
|
186
|
+
icon_url: @icon_url,
|
187
|
+
attachments: [default_attachment.merge({
|
188
|
+
color: 'good',
|
189
|
+
fallback: "sowawa1\n@everyone\n",
|
190
|
+
text: "sowawa1\n@everyone\n",
|
191
|
+
})]
|
192
|
+
}))
|
196
193
|
end
|
197
194
|
end
|
198
195
|
end
|
@@ -201,11 +198,9 @@ if ENV['WEBHOOK_URL'] and ENV['SLACKBOT_URL'] and ENV['TOKEN']
|
|
201
198
|
# but slack does not provide channels.delete API
|
202
199
|
def test_channels_create
|
203
200
|
begin
|
204
|
-
@api.channels_create(
|
205
|
-
|
206
|
-
|
207
|
-
}.merge(token(@api))
|
208
|
-
)
|
201
|
+
@api.channels_create(token(@api).merge({
|
202
|
+
name: '#test_channels_create',
|
203
|
+
}))
|
209
204
|
rescue Fluent::SlackClient::NameTakenError
|
210
205
|
end
|
211
206
|
end
|
@@ -214,17 +209,11 @@ if ENV['WEBHOOK_URL'] and ENV['SLACKBOT_URL'] and ENV['TOKEN']
|
|
214
209
|
# but slack does not provide channels.delete API
|
215
210
|
def test_auto_channels_create
|
216
211
|
assert_nothing_raised do
|
217
|
-
@api.post_message(
|
212
|
+
@api.post_message(default_payload(@api).merge(
|
218
213
|
{
|
219
|
-
channel:
|
220
|
-
|
221
|
-
|
222
|
-
attachments: [{
|
223
|
-
color: 'good',
|
224
|
-
fallback: "bar\n",
|
225
|
-
text: "bar\n",
|
226
|
-
}]
|
227
|
-
}.merge(token(@api)),
|
214
|
+
channel: '#test_auto_api',
|
215
|
+
text: "bar\n",
|
216
|
+
}),
|
228
217
|
{
|
229
218
|
auto_channels_create: true,
|
230
219
|
}
|
@@ -232,17 +221,11 @@ if ENV['WEBHOOK_URL'] and ENV['SLACKBOT_URL'] and ENV['TOKEN']
|
|
232
221
|
end
|
233
222
|
|
234
223
|
assert_nothing_raised do
|
235
|
-
@slackbot.post_message(
|
224
|
+
@slackbot.post_message(default_payload(@slackbot).merge(
|
236
225
|
{
|
237
|
-
channel:
|
238
|
-
|
239
|
-
|
240
|
-
attachments: [{
|
241
|
-
color: 'good',
|
242
|
-
fallback: "bar\n",
|
243
|
-
text: "bar\n",
|
244
|
-
}]
|
245
|
-
}.merge(token(@api)),
|
226
|
+
channel: '#test_auto_slackbot',
|
227
|
+
text: "bar\n",
|
228
|
+
}),
|
246
229
|
{
|
247
230
|
auto_channels_create: true,
|
248
231
|
}
|
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.
|
4
|
+
version: 0.6.0
|
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: 2015-04-
|
12
|
+
date: 2015-04-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fluentd
|