slack-notify 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 00ae9577d0c514b298a64e4516e24b1b3a888e11
4
- data.tar.gz: 168e894c3fbc4206e0451bb9ff626b2232f6a23b
3
+ metadata.gz: 03e6c9b0e49fde578cd9f35b06f842d31d4f37cd
4
+ data.tar.gz: 6a6cb121c35a1e62ecb7dd0f47e1da4a773d37a0
5
5
  SHA512:
6
- metadata.gz: 3ae2ba9457d0f19474275265e844a8fd2461d6e7ee1154bd990cc4f3238ae7c23bf1d327c9e3e6d598e1b99cdb3d41f5a7720b7072560fbe16f318549dc9e016
7
- data.tar.gz: e56fd9be21863aa0f1ce9656063918ec059383318b526f50cac12184ba9c5cd227869432a5f3596886ec967ed139a9864dc47134ee4ea822c770e03e370a15cd
6
+ metadata.gz: c4d94d98b07f026fbd651e5b3cb87e03af147cb33ea8758109a4ee11680c120997d0337571413d9b2ed307d6d551c1679d07fc345db3e48c02da927684041f9d
7
+ data.tar.gz: f57fd7011d8295e0de59c755b774ddffa9b664e2aa960c565bb7b7913d7e39b447fa638d085bce9d10b1f3eeb8d8253e6f8c7bf22afc751f355b29b810060d65
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ rvm:
2
+ - "2.0.0"
3
+ - "2.1.0"
4
+ - "2.1.1"
data/README.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  Send notifications to [Slack](http://slack.com/)
4
4
 
5
+ [![Build Status](https://travis-ci.org/sosedoff/slack-notify.png?branch=master)](https://travis-ci.org/sosedoff/slack-notify)
6
+ [![Code Climate](https://codeclimate.com/github/sosedoff/slack-notify.png)](https://codeclimate.com/github/sosedoff/slack-notify)
7
+
5
8
  ## Installation
6
9
 
7
10
  Add this line to your application's Gemfile:
@@ -41,7 +44,9 @@ Initialize with options:
41
44
  ```ruby
42
45
  client = SlackNotify::Client.new("team", "token", {
43
46
  channel: "#development",
44
- username: "mybot"
47
+ username: "mybot",
48
+ icon_url: "http://mydomain.com/myimage.png",
49
+ icon_emoji: ":shipit:"
45
50
  })
46
51
  ```
47
52
 
@@ -65,6 +70,12 @@ Send direct message:
65
70
  client.notify("Hello There!", "@username")
66
71
  ```
67
72
 
73
+ You can also test gem via rake console:
74
+
75
+ ```
76
+ rake console
77
+ ```
78
+
68
79
  ## Gotchas
69
80
 
70
81
  Current issues with Slack API:
data/Rakefile CHANGED
@@ -6,4 +6,14 @@ RSpec::Core::RakeTask.new(:test) do |t|
6
6
  t.verbose = false
7
7
  end
8
8
 
9
+ task :console do
10
+ require "irb"
11
+ require "irb/completion"
12
+ require "pp"
13
+ require "slack-notify"
14
+
15
+ ARGV.clear
16
+ IRB.start
17
+ end
18
+
9
19
  task :default => :test
@@ -0,0 +1,55 @@
1
+ require "json"
2
+ require "faraday"
3
+
4
+ module SlackNotify
5
+ class Client
6
+ include SlackNotify::Connection
7
+
8
+ def initialize(team, token, options = {})
9
+ @team = team
10
+ @token = token
11
+ @username = options[:username]
12
+ @channel = options[:channel]
13
+ @icon_url = options[:icon_url]
14
+ @icon_emoji = options[:icon_emoji]
15
+
16
+ validate_arguments
17
+ end
18
+
19
+ def test
20
+ notify("Test Message")
21
+ end
22
+
23
+ def notify(text, channel = nil)
24
+ delivery_channels(channel).each do |chan|
25
+ payload = SlackNotify::Payload.new(
26
+ text: text,
27
+ channel: chan,
28
+ username: @username,
29
+ icon_url: @icon_url,
30
+ icon_emoji: @icon_emoji
31
+ )
32
+
33
+ send_payload(payload)
34
+ end
35
+
36
+ true
37
+ end
38
+
39
+ private
40
+
41
+ def validate_arguments
42
+ raise ArgumentError, "Team name required" if @team.nil?
43
+ raise ArgumentError, "Token required" if @token.nil?
44
+ raise ArgumentError, "Invalid team name" unless valid_team_name?
45
+ end
46
+
47
+ def valid_team_name?
48
+ @team =~ /^[a-z\d\-]+$/ ? true : false
49
+ end
50
+
51
+ def delivery_channels(channel)
52
+ [channel || @channel || "#general"].flatten.compact.uniq
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,34 @@
1
+ module SlackNotify
2
+ module Connection
3
+ def send_payload(payload)
4
+ conn = Faraday.new(hook_url, { timeout: 5, open_timeout: 5 }) do |c|
5
+ c.use(Faraday::Request::UrlEncoded)
6
+ c.adapter(Faraday.default_adapter)
7
+ end
8
+
9
+ response = conn.post do |req|
10
+ req.body = JSON.dump(payload.to_hash)
11
+ end
12
+
13
+ handle_response(response)
14
+ end
15
+
16
+ def handle_response(response)
17
+ unless response.success?
18
+ if response.body.include?("\n")
19
+ raise SlackNotify::Error
20
+ else
21
+ raise SlackNotify::Error.new(response.body)
22
+ end
23
+ end
24
+ end
25
+
26
+ def hook_url
27
+ "#{base_url}/services/hooks/incoming-webhook?token=#{@token}"
28
+ end
29
+
30
+ def base_url
31
+ "https://#{@team}.slack.com"
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,29 @@
1
+ module SlackNotify
2
+ class Payload
3
+ attr_accessor :username, :text, :channel, :icon_url, :icon_emoji
4
+
5
+ def initialize(options = {})
6
+ @username = options[:username] || "webhookbot"
7
+ @channel = options[:channel] || "#general"
8
+ @text = options[:text]
9
+ @icon_url = options[:icon_url]
10
+ @icon_emoji = options[:icon_emoji]
11
+
12
+ unless channel[0] =~ /^(#|@)/
13
+ @channel = "##{@channel}"
14
+ end
15
+ end
16
+
17
+ def to_hash
18
+ hash = {
19
+ text: text,
20
+ username: username,
21
+ channel: channel,
22
+ icon_url: icon_url,
23
+ icon_emoji: icon_emoji
24
+ }
25
+
26
+ hash.delete_if { |_,v| v.nil? }
27
+ end
28
+ end
29
+ end
@@ -1,3 +1,3 @@
1
1
  module SlackNotify
2
- VERSION = "0.1.4"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/slack-notify.rb CHANGED
@@ -1,75 +1,5 @@
1
1
  require "slack-notify/version"
2
2
  require "slack-notify/error"
3
-
4
- require "json"
5
- require "faraday"
6
-
7
- module SlackNotify
8
- class Client
9
- def initialize(team, token, options = {})
10
- @team = team
11
- @token = token
12
- @username = options[:username] || "webhookbot"
13
- @channel = options[:channel] || "#general"
14
-
15
- raise ArgumentError, "Team name required" if @team.nil?
16
- raise ArgumentError, "Token required" if @token.nil?
17
- raise ArgumentError, "Invalid team name" unless valid_team_name?
18
- end
19
-
20
- def test
21
- notify("This is a test message!")
22
- end
23
-
24
- def notify(text, channel = nil)
25
- format_channel(channel).each do |chan|
26
- send_payload(text: text, username: @username, channel: chan)
27
- end
28
-
29
- true
30
- end
31
-
32
- private
33
-
34
- def format_channel(channel)
35
- [channel || @channel].flatten.compact.uniq.map do |name|
36
- name[0].match(/^(#|@)/) && name || "##{name}"
37
- end
38
- end
39
-
40
- def send_payload(payload)
41
- conn = Faraday.new(hook_url, { timeout: 5, open_timeout: 5 }) do |c|
42
- c.use(Faraday::Request::UrlEncoded)
43
- c.adapter(Faraday.default_adapter)
44
- end
45
-
46
- response = conn.post do |req|
47
- req.body = JSON.dump(payload)
48
- end
49
-
50
- handle_response(response)
51
- end
52
-
53
- def handle_response(response)
54
- unless response.success?
55
- if response.body.include?("\n")
56
- raise SlackNotify::Error
57
- else
58
- raise SlackNotify::Error.new(response.body)
59
- end
60
- end
61
- end
62
-
63
- def valid_team_name?
64
- @team =~ /^[a-z\d\-]+$/ ? true : false
65
- end
66
-
67
- def hook_url
68
- "#{base_url}/services/hooks/incoming-webhook?token=#{@token}"
69
- end
70
-
71
- def base_url
72
- "https://#{@team}.slack.com"
73
- end
74
- end
75
- end
3
+ require "slack-notify/connection"
4
+ require "slack-notify/payload"
5
+ require "slack-notify/client"
@@ -23,68 +23,20 @@ describe SlackNotify::Client do
23
23
  end
24
24
 
25
25
  describe "#test" do
26
- let(:client) do
27
- described_class.new("foo", "token")
28
- end
29
-
30
- let(:payload) do
31
- {
32
- text: "This is a test message!",
33
- channel: "#general",
34
- username: "webhookbot"
35
- }
36
- end
26
+ let(:client) { described_class.new("foo", "token") }
37
27
 
38
28
  before do
39
- client.stub(:send_payload) { true }
29
+ client.stub(:notify)
30
+ client.test
40
31
  end
41
32
 
42
- it "sends a test payload" do
43
- expect(client).to receive(:send_payload).with(payload)
44
- client.test
33
+ it "it sends a test message" do
34
+ expect(client).to have_received(:notify).with("Test Message")
45
35
  end
46
36
  end
47
37
 
48
38
  describe "#notify" do
49
- let(:client) do
50
- described_class.new("foo", "token")
51
- end
52
-
53
- it "sends message to default channel" do
54
- client.stub(:send_payload) { true }
55
-
56
- expect(client).to receive(:send_payload).with(
57
- text: "Message",
58
- channel: "#general",
59
- username: "webhookbot"
60
- )
61
-
62
- client.notify("Message")
63
- end
64
-
65
- it "sends message as default user" do
66
- client.stub(:send_payload) { true }
67
-
68
- expect(client).to receive(:send_payload).with(
69
- text: "Message",
70
- channel: "#general",
71
- username: "webhookbot"
72
- )
73
-
74
- client.notify("Message")
75
- end
76
-
77
- it "sends message to a specified channel" do
78
- client.stub(:send_payload) { true }
79
-
80
- expect(client).to receive(:send_payload).with(
81
- text: "Message",
82
- channel: "#mychannel",
83
- username: "webhookbot"
84
- )
85
-
86
- client.notify("Message", "#mychannel")
87
- end
39
+ let(:client) { described_class.new("foo", "token") }
88
40
 
89
41
  it "delivers payload" do
90
42
  stub_request(:post, "https://foo.slack.com/services/hooks/incoming-webhook?token=token").
@@ -119,34 +71,44 @@ describe SlackNotify::Client do
119
71
  end
120
72
  end
121
73
 
122
- context "with multiple channels" do
74
+ context "when icon_url is set" do
75
+ let(:client) { described_class.new("foo", "bar", icon_url: "foobar") }
76
+
123
77
  before do
124
- client.stub(:send_payload) { true }
78
+ stub_request(:post, "https://foo.slack.com/services/hooks/incoming-webhook?token=bar").
79
+ with(:body => {"{\"text\":\"Message\",\"username\":\"webhookbot\",\"channel\":\"#general\",\"icon_url\":\"foobar\"}"=>true},
80
+ :headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Faraday v0.8.9'}).
81
+ to_return(:status => 200, :body => "", :headers => {})
125
82
  end
126
83
 
127
- it "delivers payload to multiple channels" do
128
- expect(client).to receive(:send_payload).exactly(2).times
129
- client.notify("Message", ["#channel1", "#channel2"])
84
+ it "includes url in payload" do
85
+ client.notify("Message")
130
86
  end
131
87
  end
132
88
 
133
- context "when pound symbol is missing" do
134
- before { client.stub(:send_payload).and_return(true) }
89
+ context "when icon_emoji is set" do
90
+ let(:client) { described_class.new("foo", "bar", icon_emoji: "foobar") }
135
91
 
136
- it "adds pound symbol to channel name" do
137
- expect(client).to receive(:send_payload).with(text: "Message", username: "webhookbot", channel: "#foobar")
138
- client.notify("Message", "foobar")
92
+ before do
93
+ stub_request(:post, "https://foo.slack.com/services/hooks/incoming-webhook?token=bar").
94
+ with(:body => {"{\"text\":\"Message\",\"username\":\"webhookbot\",\"channel\":\"#general\",\"icon_emoji\":\"foobar\"}"=>true},
95
+ :headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Faraday v0.8.9'}).
96
+ to_return(:status => 200, :body => "", :headers => {})
97
+ end
98
+
99
+ it "includes icon in payload" do
100
+ client.notify("Message")
139
101
  end
140
102
  end
141
103
 
142
- context "when direct message" do
104
+ context "with multiple channels" do
143
105
  before do
144
- client.stub(:send_payload).and_return(true)
145
- client.notify("Message", "@user")
106
+ client.stub(:send_payload) { true }
107
+ client.notify("Message", ["#channel1", "#channel2"])
146
108
  end
147
109
 
148
- it "sends payload to a user" do
149
- expect(client).to have_received(:send_payload).with(text: "Message", username: "webhookbot", channel: "@user")
110
+ it "delivers payload to multiple channels" do
111
+ expect(client).to have_received(:send_payload).exactly(2).times
150
112
  end
151
113
  end
152
114
 
@@ -0,0 +1,105 @@
1
+ require "spec_helper"
2
+
3
+ describe SlackNotify::Payload do
4
+ let(:options) do
5
+ {
6
+ username: "foo",
7
+ channel: "#bar",
8
+ text: "hola",
9
+ icon_url: "http://domain.com/image.png",
10
+ icon_emoji: ":chart_with_upwards_trend:"
11
+ }
12
+ end
13
+
14
+ describe "#initialize" do
15
+ let(:payload) { described_class.new(options) }
16
+
17
+ context "with options" do
18
+ it "sets username" do
19
+ expect(payload.username).to eq "foo"
20
+ end
21
+
22
+ it "sets channel" do
23
+ expect(payload.channel).to eq "#bar"
24
+ end
25
+
26
+ it "sets text" do
27
+ expect(payload.text).to eq "hola"
28
+ end
29
+
30
+ it "sets icon url" do
31
+ expect(payload.icon_url).to eq "http://domain.com/image.png"
32
+ end
33
+
34
+ it "sets icon emoji" do
35
+ expect(payload.icon_emoji).to eq ":chart_with_upwards_trend:"
36
+ end
37
+
38
+ context "on missing pound in channel" do
39
+ let(:options) do
40
+ { channel: "foo" }
41
+ end
42
+
43
+ it "adds pound symbol" do
44
+ expect(payload.channel).to eq "#foo"
45
+ end
46
+ end
47
+
48
+ context "on direct message" do
49
+ let(:options) do
50
+ { channel: "@dan" }
51
+ end
52
+
53
+ it "keeps the symbol" do
54
+ expect(payload.channel).to eq "@dan"
55
+ end
56
+ end
57
+ end
58
+
59
+ context "without options" do
60
+ let(:options) { Hash.new }
61
+
62
+ it "sets username" do
63
+ expect(payload.username).to eq "webhookbot"
64
+ end
65
+
66
+ it "sets channel" do
67
+ expect(payload.channel).to eq "#general"
68
+ end
69
+ end
70
+ end
71
+
72
+ describe "#to_hash" do
73
+ let(:hash) { described_class.new(options).to_hash }
74
+
75
+ it "includes basic attributes" do
76
+ expect(hash).to eq Hash(
77
+ channel: "#bar",
78
+ icon_url: "http://domain.com/image.png",
79
+ icon_emoji: ":chart_with_upwards_trend:",
80
+ text: "hola",
81
+ username: "foo"
82
+ )
83
+ end
84
+
85
+ context "when icon url is not set" do
86
+ before do
87
+ options[:icon_url] = nil
88
+ end
89
+
90
+ it "excludes icon_url" do
91
+ expect(hash.keys).not_to include "icon_url"
92
+ end
93
+ end
94
+
95
+ context "when icon emoji is not set" do
96
+ before do
97
+ options[:icon_emoji] = nil
98
+ end
99
+
100
+ it "excludes icon_emoji" do
101
+ expect(hash.keys).not_to include "icon_emoji"
102
+ end
103
+ end
104
+ end
105
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slack-notify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Sosedoff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-02 00:00:00.000000000 Z
11
+ date: 2014-04-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -117,15 +117,20 @@ extra_rdoc_files: []
117
117
  files:
118
118
  - .gitignore
119
119
  - .rspec
120
+ - .travis.yml
120
121
  - Gemfile
121
122
  - LICENSE.txt
122
123
  - README.md
123
124
  - Rakefile
124
125
  - lib/slack-notify.rb
126
+ - lib/slack-notify/client.rb
127
+ - lib/slack-notify/connection.rb
125
128
  - lib/slack-notify/error.rb
129
+ - lib/slack-notify/payload.rb
126
130
  - lib/slack-notify/version.rb
127
131
  - slack-notify.gemspec
128
132
  - spec/slack-notify/client_spec.rb
133
+ - spec/slack-notify/payload_spec.rb
129
134
  - spec/spec_helper.rb
130
135
  homepage: https://github.com/sosedoff/slack-notify
131
136
  licenses:
@@ -153,4 +158,5 @@ specification_version: 4
153
158
  summary: Send notifications to a Slack channel
154
159
  test_files:
155
160
  - spec/slack-notify/client_spec.rb
161
+ - spec/slack-notify/payload_spec.rb
156
162
  - spec/spec_helper.rb