fluent-plugin-slack 0.5.0 → 0.5.1

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 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>