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 +4 -4
- data/.travis.yml +4 -0
- data/README.md +12 -1
- data/Rakefile +10 -0
- data/lib/slack-notify/client.rb +55 -0
- data/lib/slack-notify/connection.rb +34 -0
- data/lib/slack-notify/payload.rb +29 -0
- data/lib/slack-notify/version.rb +1 -1
- data/lib/slack-notify.rb +3 -73
- data/spec/slack-notify/client_spec.rb +31 -69
- data/spec/slack-notify/payload_spec.rb +105 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 03e6c9b0e49fde578cd9f35b06f842d31d4f37cd
|
4
|
+
data.tar.gz: 6a6cb121c35a1e62ecb7dd0f47e1da4a773d37a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4d94d98b07f026fbd651e5b3cb87e03af147cb33ea8758109a4ee11680c120997d0337571413d9b2ed307d6d551c1679d07fc345db3e48c02da927684041f9d
|
7
|
+
data.tar.gz: f57fd7011d8295e0de59c755b774ddffa9b664e2aa960c565bb7b7913d7e39b447fa638d085bce9d10b1f3eeb8d8253e6f8c7bf22afc751f355b29b810060d65
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
Send notifications to [Slack](http://slack.com/)
|
4
4
|
|
5
|
+
[](https://travis-ci.org/sosedoff/slack-notify)
|
6
|
+
[](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
@@ -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
|
data/lib/slack-notify/version.rb
CHANGED
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 "
|
5
|
-
require "
|
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)
|
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(:
|
29
|
+
client.stub(:notify)
|
30
|
+
client.test
|
40
31
|
end
|
41
32
|
|
42
|
-
it "sends a test
|
43
|
-
expect(client).to
|
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)
|
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 "
|
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
|
-
|
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 "
|
128
|
-
|
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
|
134
|
-
|
89
|
+
context "when icon_emoji is set" do
|
90
|
+
let(:client) { described_class.new("foo", "bar", icon_emoji: "foobar") }
|
135
91
|
|
136
|
-
|
137
|
-
|
138
|
-
|
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 "
|
104
|
+
context "with multiple channels" do
|
143
105
|
before do
|
144
|
-
client.stub(:send_payload)
|
145
|
-
client.notify("Message", "
|
106
|
+
client.stub(:send_payload) { true }
|
107
|
+
client.notify("Message", ["#channel1", "#channel2"])
|
146
108
|
end
|
147
109
|
|
148
|
-
it "
|
149
|
-
expect(client).to have_received(:send_payload).
|
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.
|
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-
|
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
|