fluent-plugin-slack 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c08f44114d6d2335cb8cee39f0053e79000270bc
4
- data.tar.gz: 25186d53c993522e99e92acfb479859d0e6e265d
3
+ metadata.gz: 63fd1c619f76e7bb3df9b2ff11e69af43e23f810
4
+ data.tar.gz: 8fd2eb0e8790c71c8689ae88e42f8a4bae3f1d3b
5
5
  SHA512:
6
- metadata.gz: 9e454cae0012869146257e6c1160b739a4620f27966eeb192991b677d7243de00d24516146de16ca38be2971bd403f7d31197d1fc9f24f54d162ab64c968932c
7
- data.tar.gz: 1a277e5b7ad062af8e25618b7742c680a3c9878ef36f28f4a7ad47a2a782861c909930251dcf0a699890885a95eb331e31fc27158ff5f06ddf003f514bdc91fa
6
+ metadata.gz: bf331ec94a09e572f2aa1c958842634195dad9078cc7fbf86813c121d88ddeb69568617663cf2012151646c52c6ec64203f95b3738348937bc0b8a417c6da976
7
+ data.tar.gz: c16e8a479300bc03539232a4d76d172d7eaa8c0d0e640612424fa483f2b7abd4510de6a3fee5b55d0eb2b70a395cc1a65d2425e3eb62c0e7a1058d9be3418d66
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 2.0.0
4
+ - 2.1.*
5
+ - 2.2.*
6
+ gemfile:
7
+ - Gemfile
data/CHANGELOG.md ADDED
@@ -0,0 +1,13 @@
1
+ ## 0.5.1 (2015/03/27)
2
+
3
+ Enhancements:
4
+
5
+ * Support `auto_channels_create` option to automatically create channels.
6
+
7
+ ## 0.5.0 (2015/03/22)
8
+
9
+ Enhancements:
10
+
11
+ * Support `message` and `message_keys` options
12
+ * Support `title` and `title_keys` options
13
+ * Support `channel_keys` options to dynamically change channels
data/README.md CHANGED
@@ -26,7 +26,7 @@ fluent_logger.post('slack', {
26
26
  })
27
27
  ```
28
28
 
29
- # Usage (Slack API)
29
+ # Usage (Web API)
30
30
 
31
31
  ```apache
32
32
  <match slack>
@@ -50,8 +50,8 @@ fluent_logger.post('slack', {
50
50
 
51
51
  |parameter|description|default|
52
52
  |---|---|---|
53
- |webhook_uri|Incoming Webhook URI (Required for Incoming Webhook mode)||
54
- |token|Token for Slack API (Required for Slack API mode)||
53
+ |webhook_url|Incoming Webhook URI (Required for Incoming Webhook mode)||
54
+ |token|Token for Web API (Required for Web API mode)||
55
55
  |username|name of bot|fluentd|
56
56
  |color|color to use|good|
57
57
  |icon_emoji|emoji to use as the icon|`:question:`|
@@ -61,6 +61,7 @@ fluent_logger.post('slack', {
61
61
  |title_keys|keys used to format the title|nil|
62
62
  |message|message format. %s will be replaced with value specified by message_keys|%s|
63
63
  |message_keys|keys used to format messages|message|
64
+ |auto_channels_create|Create channels if not exist. Available only with Web API mode, and a token for Normal User is required (Bot User can not create channels. See https://api.slack.com/bot-users)|false|
64
65
 
65
66
  `fluent-plugin-slack` uses `SetTimeKeyMixin` and `SetTagKeyMixin`, so you can also use:
66
67
 
@@ -75,6 +76,10 @@ fluent_logger.post('slack', {
75
76
 
76
77
  `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).
77
78
 
79
+ ## ChangeLog
80
+
81
+ See [CHANGELOG.md](CHANGELOG.md) for details.
82
+
78
83
  # Contributors
79
84
 
80
85
  - [@sonots](https://github.com/sonots)
data/Rakefile CHANGED
@@ -7,5 +7,10 @@ Rake::TestTask.new(:test) do |test|
7
7
  test.pattern = 'test/**/test_*.rb'
8
8
  test.verbose = true
9
9
  end
10
-
11
10
  task :default => :test
11
+
12
+ desc 'Open an irb session preloaded with the gem library'
13
+ task :console do
14
+ sh 'irb -rubygems -I lib'
15
+ end
16
+ task :c => :console
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.0
1
+ 0.5.1
data/example.conf ADDED
@@ -0,0 +1,17 @@
1
+ <source>
2
+ type forward
3
+ </source>
4
+
5
+ <match tag>
6
+ type slack
7
+ token "#{ENV['TOKEN']}"
8
+ username fluentd
9
+ color good
10
+ icon_emoji :ghost:
11
+ channel general
12
+ message %s %s
13
+ message_keys tag,message
14
+ title %s %s
15
+ title_keys tag,message
16
+ flush_interval 1s # slack API has limit as a post / sec
17
+ </match>
@@ -7,8 +7,8 @@ Gem::Specification.new do |gem|
7
7
  gem.homepage = "https://github.com/sowawa/fluent-plugin-slack"
8
8
  gem.summary = gem.description
9
9
  gem.version = File.read("VERSION").strip
10
- gem.authors = ["Keisuke SOGAWA"]
11
- gem.email = "keisuke.sogawa@gmail.com"
10
+ gem.authors = ["Keisuke SOGAWA", "Naotoshi Seo"]
11
+ gem.email = ["keisuke.sogawa@gmail.com", "sonots@gmail.com"]
12
12
  gem.has_rdoc = false
13
13
  gem.files = `git ls-files`.split("\n")
14
14
  gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -11,22 +11,23 @@ module Fluent
11
11
  config_set_default :include_time_key, true
12
12
  config_set_default :include_tag_key, true
13
13
 
14
- config_param :webhook_url, :string, default: nil # incoming webhook
15
- config_param :token, :string, default: nil # api token
16
- config_param :username, :string, default: 'fluentd'
17
- config_param :color, :string, default: 'good'
18
- config_param :icon_emoji, :string, default: ':question:'
19
-
20
- config_param :channel, :string
21
- config_param :channel_keys, default: nil do |val|
14
+ config_param :webhook_url, :string, default: nil # incoming webhook
15
+ config_param :token, :string, default: nil # api token
16
+ config_param :username, :string, default: 'fluentd'
17
+ config_param :color, :string, default: 'good'
18
+ config_param :icon_emoji, :string, default: ':question:'
19
+ config_param :auto_channels_create, :bool, default: false
20
+
21
+ config_param :channel, :string
22
+ config_param :channel_keys, default: nil do |val|
22
23
  val.split(',')
23
24
  end
24
- config_param :title, :string, default: nil
25
- config_param :title_keys, default: nil do |val|
25
+ config_param :title, :string, default: nil
26
+ config_param :title_keys, default: nil do |val|
26
27
  val.split(',')
27
28
  end
28
- config_param :message, :string, default: nil
29
- config_param :message_keys, default: nil do |val|
29
+ config_param :message, :string, default: nil
30
+ config_param :message_keys, default: nil do |val|
30
31
  val.split(',')
31
32
  end
32
33
 
@@ -48,19 +49,24 @@ module Fluent
48
49
  @channel = '#' + @channel unless @channel.start_with?('#')
49
50
 
50
51
  if @webhook_url
52
+ if @webhook_url.empty?
53
+ raise Fluent::ConfigError.new("`webhook_url` is an empty string")
54
+ end
51
55
  # following default values are for old version compatibility
52
56
  @title ||= '%s'
53
57
  @title_keys ||= %w[tag]
54
58
  @message ||= '[%s] %s'
55
59
  @message_keys ||= %w[time message]
56
60
  @slack = Fluent::SlackClient::IncomingWebhook.new(@webhook_url)
57
- else
58
- unless @token
59
- raise Fluent::ConfigError.new("`token` is required to call slack api")
61
+ elsif @token
62
+ if @token.empty?
63
+ raise Fluent::ConfigError.new("`token` is an empty string")
60
64
  end
61
65
  @message ||= '%s'
62
66
  @message_keys ||= %w[message]
63
67
  @slack = Fluent::SlackClient::WebApi.new
68
+ else
69
+ raise Fluent::ConfigError.new("Either of `webhook_url` or `token` is required")
64
70
  end
65
71
  @slack.log = log
66
72
  @slack.debug_dev = log.out if log.level <= Fluent::Log::LEVEL_TRACE
@@ -84,6 +90,8 @@ module Fluent
84
90
  raise Fluent::ConfigError, "string specifier '%s' for `channel` and `channel_keys` specification mismatch"
85
91
  end
86
92
  end
93
+
94
+ @post_message_opts = @auto_channels_create ? {auto_channels_create: true} : {}
87
95
  end
88
96
 
89
97
  def format(tag, time, record)
@@ -93,7 +101,7 @@ module Fluent
93
101
  def write(chunk)
94
102
  begin
95
103
  payloads = build_payloads(chunk)
96
- payloads.each {|payload| @slack.post_message(payload) }
104
+ payloads.each {|payload| @slack.post_message(payload, @post_message_opts) }
97
105
  rescue Net::OpenTimeout, Net::ReadTimeout => e
98
106
  log.warn "out_slack:", :error => e.to_s, :error_class => e.class.to_s
99
107
  raise e # let Fluentd retry
@@ -11,22 +11,23 @@ module Fluent
11
11
  config_set_default :include_time_key, true
12
12
  config_set_default :include_tag_key, true
13
13
 
14
- config_param :webhook_url, :string, default: nil # incoming webhook
15
- config_param :token, :string, default: nil # api token
16
- config_param :username, :string, default: 'fluentd'
17
- config_param :color, :string, default: 'good'
18
- config_param :icon_emoji, :string, default: ':question:'
19
-
20
- config_param :channel, :string
21
- config_param :channel_keys, default: nil do |val|
14
+ config_param :webhook_url, :string, default: nil # incoming webhook
15
+ config_param :token, :string, default: nil # api token
16
+ config_param :username, :string, default: 'fluentd'
17
+ config_param :color, :string, default: 'good'
18
+ config_param :icon_emoji, :string, default: ':question:'
19
+ config_param :auto_channels_create, :bool, default: false
20
+
21
+ config_param :channel, :string
22
+ config_param :channel_keys, default: nil do |val|
22
23
  val.split(',')
23
24
  end
24
- config_param :title, :string, default: nil
25
- config_param :title_keys, default: nil do |val|
25
+ config_param :title, :string, default: nil
26
+ config_param :title_keys, default: nil do |val|
26
27
  val.split(',')
27
28
  end
28
- config_param :message, :string, default: nil
29
- config_param :message_keys, default: nil do |val|
29
+ config_param :message, :string, default: nil
30
+ config_param :message_keys, default: nil do |val|
30
31
  val.split(',')
31
32
  end
32
33
 
@@ -48,19 +49,24 @@ module Fluent
48
49
  @channel = '#' + @channel unless @channel.start_with?('#')
49
50
 
50
51
  if @webhook_url
52
+ if @webhook_url.empty?
53
+ raise Fluent::ConfigError.new("`webhook_url` is an empty string")
54
+ end
51
55
  # following default values are for old version compatibility
52
56
  @title ||= '%s'
53
57
  @title_keys ||= %w[tag]
54
58
  @message ||= '[%s] %s'
55
59
  @message_keys ||= %w[time message]
56
60
  @slack = Fluent::SlackClient::IncomingWebhook.new(@webhook_url)
57
- else
58
- unless @token
59
- raise Fluent::ConfigError.new("`token` is required to call slack api")
61
+ elsif @token
62
+ if @token.empty?
63
+ raise Fluent::ConfigError.new("`token` is an empty string")
60
64
  end
61
65
  @message ||= '%s'
62
66
  @message_keys ||= %w[message]
63
67
  @slack = Fluent::SlackClient::WebApi.new
68
+ else
69
+ raise Fluent::ConfigError.new("Either of `webhook_url` or `token` is required")
64
70
  end
65
71
  @slack.log = log
66
72
  @slack.debug_dev = log.out if log.level <= Fluent::Log::LEVEL_TRACE
@@ -84,6 +90,8 @@ module Fluent
84
90
  raise Fluent::ConfigError, "string specifier '%s' for `channel` and `channel_keys` specification mismatch"
85
91
  end
86
92
  end
93
+
94
+ @post_message_opts = @auto_channels_create ? {auto_channels_create: true} : {}
87
95
  end
88
96
 
89
97
  def format(tag, time, record)
@@ -93,7 +101,7 @@ module Fluent
93
101
  def write(chunk)
94
102
  begin
95
103
  payloads = build_payloads(chunk)
96
- payloads.each {|payload| @slack.post_message(payload) }
104
+ payloads.each {|payload| @slack.post_message(payload, @post_message_opts) }
97
105
  rescue Net::OpenTimeout, Net::ReadTimeout => e
98
106
  log.warn "out_slack:", :error => e.to_s, :error_class => e.class.to_s
99
107
  raise e # let Fluentd retry
@@ -1,51 +1,19 @@
1
1
  require 'uri'
2
2
  require 'net/http'
3
+ require 'logger'
4
+ require_relative 'slack_client/error'
3
5
 
4
6
  module Fluent
5
7
  module SlackClient
6
- class Error < StandardError; end
7
-
8
- # This slack client only supports posting message
8
+ # The base framework of slack client
9
9
  class Base
10
10
  attr_accessor :log, :debug_dev
11
11
 
12
- DEFAULT_ENDPOINT = "https://slack.com/api/chat.postMessage"
13
-
14
- def initialize(endpoint = nil)
15
- # Configure Incoming Webhook endpoint instead of chat.postMessage API
16
- @endpoint = URI.parse(endpoint) if endpoint
12
+ def initialize
13
+ @log = Logger.new('/dev/null')
17
14
  end
18
15
 
19
- def endpoint
20
- @endpoint ||= URI.parse(DEFAULT_ENDPOINT)
21
- end
22
-
23
- # Sends a message to a channel.
24
- #
25
- # @option params [channel] :channel
26
- # Channel to send message to. Can be a public channel, private group or IM channel. Can be an encoded ID, or a name.
27
- # @option params [Object] :text
28
- # Text of the message to send. See below for an explanation of formatting.
29
- # @option params [Object] :username
30
- # Name of bot.
31
- # @option params [Object] :parse
32
- # Change how messages are treated. See below.
33
- # @option params [Object] :link_names
34
- # Find and link channel names and usernames.
35
- # @option params [Object] :attachments
36
- # Structured message attachments.
37
- # @option params [Object] :unfurl_links
38
- # Pass true to enable unfurling of primarily text-based content.
39
- # @option params [Object] :unfurl_media
40
- # Pass false to disable unfurling of media content.
41
- # @option params [Object] :icon_url
42
- # URL to an image to use as the icon for this message
43
- # @option params [Object] :icon_emoji
44
- # emoji to use as the icon for this message. Overrides `icon_url`.
45
- # @see https://api.slack.com/methods/chat.postMessage
46
- # @see https://github.com/slackhq/slack-api-docs/blob/master/methods/chat.postMessage.md
47
- # @see https://github.com/slackhq/slack-api-docs/blob/master/methods/chat.postMessage.json
48
- def post_message(params = {})
16
+ def post(endpoint, params)
49
17
  http = Net::HTTP.new(endpoint.host, endpoint.port)
50
18
  http.use_ssl = (endpoint.scheme == 'https')
51
19
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
@@ -57,36 +25,100 @@ module Fluent
57
25
  req['User-Agent'] = 'fluent-plugin-slack'
58
26
  req.body = encode_body(params)
59
27
 
60
- log.info { "out_slack: post #{params.dup.tap {|p| p[:token] = '[FILTERED]' if p[:token] }}" } if log
61
28
  res = http.request(req)
62
- response_check(res)
29
+ response_check(res, params)
63
30
  end
64
31
 
32
+ private
33
+
65
34
  def encode_body(params)
66
35
  raise NotImplementedError
67
36
  end
68
37
 
69
- def response_check(res)
38
+ def response_check(res, params)
70
39
  if res.code != "200"
71
- raise Error, "Slack.com - #{res.code} - #{res.body}"
40
+ raise Error.new(res, params)
72
41
  end
73
42
  end
74
43
  end
75
44
 
45
+ # Slack client for Incoming Webhook
76
46
  class IncomingWebhook < Base
47
+ attr_accessor :endpoint
48
+
49
+ # @param [String] endpoint Configure Incoming Webhook endpoint
50
+ def initialize(endpoint)
51
+ super()
52
+ @endpoint = URI.parse(endpoint)
53
+ end
54
+
55
+ def post_message(params = {}, opts = {})
56
+ log.info { "out_slack: post_message #{params}" }
57
+ post(endpoint, params)
58
+ end
59
+
60
+ private
61
+
77
62
  def encode_body(params = {})
78
63
  params.to_json
79
64
  end
80
65
 
81
- def response_check(res)
66
+ def response_check(res, params)
82
67
  super
83
68
  unless res.body == 'ok'
84
- raise Error, "Slack.com - #{res.code} - #{res.body}"
69
+ raise Error.new(res, params)
85
70
  end
86
71
  end
87
72
  end
88
73
 
74
+ # Slack client for Web API
89
75
  class WebApi < Base
76
+ DEFAULT_ENDPOINT = "https://slack.com/api/".freeze
77
+
78
+ def post_message_endpoint
79
+ @post_message_endpoint ||= URI.join(DEFAULT_ENDPOINT, "chat.postMessage")
80
+ end
81
+
82
+ def channels_create_endpoint
83
+ @channels_create_endpoint ||= URI.join(DEFAULT_ENDPOINT, "channels.create")
84
+ end
85
+
86
+ # Sends a message to a channel.
87
+ #
88
+ # @see https://api.slack.com/methods/chat.postMessage
89
+ # @see https://github.com/slackhq/slack-api-docs/blob/master/methods/chat.postMessage.md
90
+ # @see https://github.com/slackhq/slack-api-docs/blob/master/methods/chat.postMessage.json
91
+ def post_message(params = {}, opts = {})
92
+ retries = 1
93
+ begin
94
+ log.info { "out_slack: post_message #{params.dup.tap {|p| p[:token] = '[FILTERED]' if p[:token] }}" }
95
+ post(post_message_endpoint, params)
96
+ rescue ChannelNotFoundError => e
97
+ if opts[:auto_channels_create]
98
+ log.warn "out_slack: channel \"#{params[:channel]}\" is not found. try to create the channel, and then retry to post the message."
99
+ channels_create({name: params[:channel], token: params[:token]})
100
+ retry if (retries -= 1) >= 0 # one time retry
101
+ else
102
+ raise e
103
+ end
104
+ end
105
+ end
106
+
107
+ # Creates a channel.
108
+ #
109
+ # NOTE: Bot user can not create a channel. Token must be issued by Normal User Account
110
+ # @see https://api.slack.com/bot-users
111
+ #
112
+ # @see https://api.slack.com/methods/channels.create
113
+ # @see https://github.com/slackhq/slack-api-docs/blob/master/methods/channels.create.md
114
+ # @see https://github.com/slackhq/slack-api-docs/blob/master/methods/channels.create.json
115
+ def channels_create(params = {}, opts = {})
116
+ log.info { "out_slack: channels_create #{params.dup.tap {|p| p[:token] = '[FILTERED]' if p[:token] }}" }
117
+ post(channels_create_endpoint, params)
118
+ end
119
+
120
+ private
121
+
90
122
  def encode_body(params = {})
91
123
  body = params.dup
92
124
  if params[:attachments]
@@ -95,11 +127,17 @@ module Fluent
95
127
  URI.encode_www_form(body)
96
128
  end
97
129
 
98
- def response_check(res)
130
+ def response_check(res, params)
99
131
  super
100
- params = JSON.parse(res.body)
101
- unless params['ok']
102
- raise Error, "Slack.com - #{res.code} - #{res.body}"
132
+ res_params = JSON.parse(res.body)
133
+ return if res_params['ok']
134
+ case res_params['error']
135
+ when 'channel_not_found'
136
+ raise ChannelNotFoundError.new(res, params)
137
+ when 'name_taken'
138
+ raise NameTakenError.new(res, params)
139
+ else
140
+ raise Error.new(res, params)
103
141
  end
104
142
  end
105
143
  end
@@ -0,0 +1,24 @@
1
+ require 'net/http'
2
+
3
+ module Fluent
4
+ module SlackClient
5
+ class Error < StandardError
6
+ attr_reader :res, :req_params
7
+
8
+ def initialize(res, req_params = {})
9
+ @res = res
10
+ @req_params = req_params.dup
11
+ end
12
+
13
+ def message
14
+ @req_params[:token] = '[FILTERED]' if @req_params[:token]
15
+ "res.code:#{@res.code}, res.body:#{@res.body}, req_params:#{@req_params}"
16
+ end
17
+
18
+ alias :to_s :message
19
+ end
20
+
21
+ class ChannelNotFoundError < Error; end
22
+ class NameTakenError < Error; end
23
+ end
24
+ end
data/test.sh ADDED
@@ -0,0 +1,2 @@
1
+ #!/bin/bash
2
+ echo '{"message":"message"}' | bundle exec fluent-cat tag
@@ -83,6 +83,21 @@ class SlackOutputTest < Test::Unit::TestCase
83
83
  assert_raise(Fluent::ConfigError) do
84
84
  create_driver(CONFIG + %[channel %s %s\nchannel_keys foo])
85
85
  end
86
+
87
+ # Either of webhook_url or token is required
88
+ assert_raise(Fluent::ConfigError) do
89
+ create_driver(%[channel foo])
90
+ end
91
+
92
+ # webhook_url is an empty string
93
+ assert_raise(Fluent::ConfigError) do
94
+ create_driver(%[channel foo\nwebhook_url])
95
+ end
96
+
97
+ # token is an empty string
98
+ assert_raise(Fluent::ConfigError) do
99
+ create_driver(%[channel foo\ntoken])
100
+ end
86
101
  end
87
102
 
88
103
  def test_timezone_configure
@@ -129,7 +144,7 @@ class SlackOutputTest < Test::Unit::TestCase
129
144
  ])
130
145
  time = Time.parse("2014-01-01 22:00:00 UTC").to_i
131
146
  d.tag = 'test'
132
- mock(d.instance.slack).post_message(
147
+ mock(d.instance.slack).post_message({
133
148
  channel: '#channel',
134
149
  username: 'fluentd',
135
150
  icon_emoji: ':question:',
@@ -141,7 +156,7 @@ class SlackOutputTest < Test::Unit::TestCase
141
156
  value: "[07:00:00] sowawa1\n[07:00:00] sowawa2\n",
142
157
  }],
143
158
  }]
144
- )
159
+ }, {})
145
160
  with_timezone('Asia/Tokyo') do
146
161
  d.emit({message: 'sowawa1'}, time)
147
162
  d.emit({message: 'sowawa2'}, time)
@@ -156,7 +171,7 @@ class SlackOutputTest < Test::Unit::TestCase
156
171
  ])
157
172
  time = Time.parse("2014-01-01 22:00:00 UTC").to_i
158
173
  d.tag = 'test'
159
- mock(d.instance.slack).post_message(
174
+ mock(d.instance.slack).post_message({
160
175
  token: 'XX-XX-XX',
161
176
  channel: '#channel',
162
177
  username: 'fluentd',
@@ -166,7 +181,7 @@ class SlackOutputTest < Test::Unit::TestCase
166
181
  fallback: "sowawa1\nsowawa2\n",
167
182
  text: "sowawa1\nsowawa2\n",
168
183
  }]
169
- )
184
+ }, {})
170
185
  with_timezone('Asia/Tokyo') do
171
186
  d.emit({message: 'sowawa1'}, time)
172
187
  d.emit({message: 'sowawa2'}, time)
@@ -179,7 +194,7 @@ class SlackOutputTest < Test::Unit::TestCase
179
194
  time = Time.parse("2014-01-01 22:00:00 UTC").to_i
180
195
  d.tag = 'test'
181
196
  # attachments field should be changed to show the title
182
- mock(d.instance.slack).post_message(
197
+ mock(d.instance.slack).post_message({
183
198
  token: 'XXX-XXX-XXX',
184
199
  channel: '#channel',
185
200
  username: 'fluentd',
@@ -194,7 +209,7 @@ class SlackOutputTest < Test::Unit::TestCase
194
209
  }
195
210
  ]
196
211
  }]
197
- )
212
+ }, {})
198
213
  with_timezone('Asia/Tokyo') do
199
214
  d.emit({message: 'sowawa1'}, time)
200
215
  d.emit({message: 'sowawa2'}, time)
@@ -206,7 +221,7 @@ class SlackOutputTest < Test::Unit::TestCase
206
221
  d = create_driver(CONFIG + %[message %s %s\nmessage_keys tag,message])
207
222
  time = Time.parse("2014-01-01 22:00:00 UTC").to_i
208
223
  d.tag = 'test'
209
- mock(d.instance.slack).post_message(
224
+ mock(d.instance.slack).post_message({
210
225
  token: 'XXX-XXX-XXX',
211
226
  channel: '#channel',
212
227
  username: 'fluentd',
@@ -216,7 +231,7 @@ class SlackOutputTest < Test::Unit::TestCase
216
231
  fallback: "test sowawa1\ntest sowawa2\n",
217
232
  text: "test sowawa1\ntest sowawa2\n",
218
233
  }]
219
- )
234
+ }, {})
220
235
  with_timezone('Asia/Tokyo') do
221
236
  d.emit({message: 'sowawa1'}, time)
222
237
  d.emit({message: 'sowawa2'}, time)
@@ -228,7 +243,7 @@ class SlackOutputTest < Test::Unit::TestCase
228
243
  d = create_driver(CONFIG + %[channel %s\nchannel_keys channel])
229
244
  time = Time.parse("2014-01-01 22:00:00 UTC").to_i
230
245
  d.tag = 'test'
231
- mock(d.instance.slack).post_message(
246
+ mock(d.instance.slack).post_message({
232
247
  token: 'XXX-XXX-XXX',
233
248
  channel: '#channel1',
234
249
  username: 'fluentd',
@@ -238,8 +253,8 @@ class SlackOutputTest < Test::Unit::TestCase
238
253
  fallback: "sowawa1\n",
239
254
  text: "sowawa1\n",
240
255
  }]
241
- )
242
- mock(d.instance.slack).post_message(
256
+ }, {})
257
+ mock(d.instance.slack).post_message({
243
258
  token: 'XXX-XXX-XXX',
244
259
  channel: '#channel2',
245
260
  username: 'fluentd',
@@ -249,7 +264,7 @@ class SlackOutputTest < Test::Unit::TestCase
249
264
  fallback: "sowawa2\n",
250
265
  text: "sowawa2\n",
251
266
  }]
252
- )
267
+ }, {})
253
268
  with_timezone('Asia/Tokyo') do
254
269
  d.emit({message: 'sowawa1', channel: 'channel1'}, time)
255
270
  d.emit({message: 'sowawa2', channel: 'channel2'}, time)
@@ -23,7 +23,7 @@ if ENV['WEBHOOK_URL'] and ENV['TOKEN']
23
23
  client == @api ? {token: ENV['TOKEN']} : {}
24
24
  end
25
25
 
26
- def test_text
26
+ def test_post_message_text
27
27
  [@incoming_webhook, @api].each do |slack|
28
28
  assert_nothing_raised do
29
29
  slack.post_message(
@@ -42,7 +42,7 @@ if ENV['WEBHOOK_URL'] and ENV['TOKEN']
42
42
  end
43
43
  end
44
44
 
45
- def test_fields
45
+ def test_post_message_fields
46
46
  [@incoming_webhook, @api].each do |slack|
47
47
  assert_nothing_raised do
48
48
  slack.post_message(
@@ -69,5 +69,40 @@ if ENV['WEBHOOK_URL'] and ENV['TOKEN']
69
69
  end
70
70
  end
71
71
  end
72
+
73
+ # Hmm, I need to delete channels to test repeatedly,
74
+ # but slack does not provide channels.delete API
75
+ def test_channels_create
76
+ begin
77
+ @api.channels_create(
78
+ {
79
+ name: '#foo',
80
+ }.merge(token(@api))
81
+ )
82
+ rescue Fluent::SlackClient::NameTakenError
83
+ end
84
+ end
85
+
86
+ # Hmm, I need to delete channels to test repeatedly,
87
+ # but slack does not provide channels.delete API
88
+ def test_auto_channels_create
89
+ assert_nothing_raised do
90
+ @api.post_message(
91
+ {
92
+ channel: '#bar',
93
+ username: 'fluentd',
94
+ icon_emoji: ':question:',
95
+ attachments: [{
96
+ color: 'good',
97
+ fallback: "bar\n",
98
+ text: "bar\n",
99
+ }]
100
+ }.merge(token(@api)),
101
+ {
102
+ auto_channels_create: true,
103
+ }
104
+ )
105
+ end
106
+ end
72
107
  end
73
108
  end
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-slack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keisuke SOGAWA
8
+ - Naotoshi Seo
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2015-03-22 00:00:00.000000000 Z
12
+ date: 2015-03-27 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: fluentd
@@ -123,21 +124,27 @@ dependencies:
123
124
  - !ruby/object:Gem::Version
124
125
  version: '0'
125
126
  description: fluent Slack plugin
126
- email: keisuke.sogawa@gmail.com
127
+ email:
128
+ - keisuke.sogawa@gmail.com
129
+ - sonots@gmail.com
127
130
  executables: []
128
131
  extensions: []
129
132
  extra_rdoc_files: []
130
133
  files:
131
134
  - ".gitignore"
132
- - AUTHORS
135
+ - ".travis.yml"
136
+ - CHANGELOG.md
133
137
  - Gemfile
134
138
  - README.md
135
139
  - Rakefile
136
140
  - VERSION
141
+ - example.conf
137
142
  - fluent-plugin-slack.gemspec
138
143
  - lib/fluent/plugin/out_buffered_slack.rb
139
144
  - lib/fluent/plugin/out_slack.rb
140
145
  - lib/fluent/plugin/slack_client.rb
146
+ - lib/fluent/plugin/slack_client/error.rb
147
+ - test.sh
141
148
  - test/plugin/test_out_slack.rb
142
149
  - test/plugin/test_slack_client.rb
143
150
  - test/test_helper.rb
data/AUTHORS DELETED
@@ -1 +0,0 @@
1
- Keisuke SOGAWA <keisuke.sogawa _at_ gmail.com>