slackr 0.0.2 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - "2.0.0"
4
+ - "1.9.3"
5
+ script: bundle exec rspec spec
data/Gemfile CHANGED
@@ -2,3 +2,7 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in slackr.gemspec
4
4
  gemspec
5
+
6
+ group :test do
7
+ gem 'pry'
8
+ end
data/README.md CHANGED
@@ -1,12 +1,18 @@
1
1
  # Slackr
2
2
 
3
- A simple gem for sending messages to the Slack.com communications platform.
3
+ A simple wrapper for the http://slack.com API.
4
+
5
+ ## Build Status
6
+
7
+ [![Build Status](https://travis-ci.org/risk-io/slackr.svg?branch=master)](https://travis-ci.org/risk-io/slackr)
4
8
 
5
9
  ## Installation
6
10
 
11
+ NOTE: the most recent version of the gem has not been published to rubygems.org, so specify the path as shown.
12
+
7
13
  Add this line to your application's Gemfile:
8
14
 
9
- gem 'slackr'
15
+ gem 'slackr', :git => 'git://github.com/risk-io/slackr.git'
10
16
 
11
17
  And then execute:
12
18
 
@@ -18,23 +24,18 @@ Or install it yourself as:
18
24
 
19
25
  ## Usage
20
26
 
21
-
22
-
23
27
  Send a message to slack:
24
28
 
25
29
  ```
26
30
  require 'slackr'
27
- slack = Slackr::Webhook.new("my_team_name","my_api_key")
28
- slack.say "this is a test"
31
+ slack = Slackr.connect("teamX", "token124", {"channel" => "#myroom", "username" => "systems_bot"})
32
+ slack.say "hello world" # posts 'hello world' to the myroom channel as the systems_bot user
33
+ slack.say "hello", {"channel" => "#room2", "username" => "joke_bot"} # posts 'hello' to the room2 channel as the joke_but user
29
34
  ```
30
35
 
31
- Say a message to slack using some customization:
32
-
36
+ Retrieve the channel list:
33
37
  ```
34
- require 'slackr'
35
- slack = Slackr::Webhook.new("my_team_name","my_api_key",{:icon_emoji => ":ghost:"})
36
- slack.say("this is a test as a ghost")
37
- slack.say("this is a test as a ghost with a custom name",{:username => "casper"}
38
+ slack.channels.list # returns a hash of channel objects
38
39
  ```
39
40
 
40
41
  Available customizations include:
@@ -49,11 +50,17 @@ Available customizations include:
49
50
  # }
50
51
  ```
51
52
 
53
+ ## General Notes
54
+ - Slackr::Connection stores the connection information
55
+ - Slackr::Errors stores the various custom errors thrown
56
+ - Slackr::Version stores the gem version
57
+ - Slackr::IncomingWebhook stores the logic for the various incoming webhook API endpoints
58
+
52
59
  ## TODO
53
60
 
54
- 1. More/better tests
55
- 2. Link parsing and attachments
56
- 3. CLI
61
+ - [ ] Support formats for incoming webhook messages
62
+ - [ ] Link parsing and attachments
63
+ - [ ] CLI
57
64
 
58
65
  ## Contributing
59
66
 
@@ -1,3 +1,39 @@
1
1
  require "slackr/version"
2
2
  require "slackr/errors"
3
- require "slackr/webhook"
3
+ require "slackr/connection"
4
+ require "slackr/webhooks/incoming"
5
+ require "slackr/channel"
6
+
7
+ # slack = Slackr.connect("teamX", "token124", {"channel" => "#myroom", "username" => "systems_bot"})
8
+ # slack.say "hello world" => posts 'hello world' to the myroom channel as the systems_bot user
9
+ # slack.say "hello", {"channel" => "#room2", "username" => "joke_bot"} => posts 'hello' to the room2 channel as the joke_but user
10
+ # slack.channels.list => returns a hash of channel objects
11
+ module Slackr
12
+ extend self
13
+
14
+ attr_accessor :connection
15
+
16
+ def connect(team, token, options = {})
17
+ raise Slackr::ArgumentError, "Team required" if team.nil?
18
+ raise Slackr::ArgumentError, "Token required" if token.nil?
19
+ #TODO: raise error if options doesn't contain channel and username values
20
+ @connection = Slackr::Connection.new(team, token, options).init
21
+ return self
22
+ end
23
+
24
+ def say(text, options = {})
25
+ Slackr::IncomingWebhook.say(connection, text, options)
26
+ end
27
+
28
+ def channels
29
+ Slackr::Channel.init(connection)
30
+ end
31
+
32
+ # support for backwards compatibility
33
+ class Webhook
34
+ def initialize(team, token, options = {})
35
+ warn "[DEPRECATION] `Slackr::Webhook.new` is deprecated. Please use `Slackr.connect` instead."
36
+ end
37
+ end
38
+ end
39
+
@@ -0,0 +1,61 @@
1
+ require "json"
2
+
3
+ module Slackr
4
+ module Channel
5
+ extend self
6
+
7
+ attr_accessor :connection
8
+
9
+ def init(connection)
10
+ @connection = connection
11
+ return self
12
+ end
13
+
14
+ def list
15
+ request = request_for(url_for('list'))
16
+ make_request(request)
17
+ end
18
+
19
+ def history(channel)
20
+ request = request_for(history_url(channel))
21
+ response = make_request(request)
22
+ messages = response["messages"]
23
+ while response["has_more"] do
24
+ oldest_timestamp = oldest_message(response["messages"])["ts"]
25
+ request = request_for(history_url(channel, oldest_timestamp))
26
+ response = make_request(request)
27
+ messages += response["messages"]
28
+ end
29
+ response.merge("messages" => messages)
30
+ end
31
+
32
+ private
33
+
34
+ def url_for(action)
35
+ "#{connection.base_url}/api/channels.#{action}?token=#{connection.token}"
36
+ end
37
+
38
+ def request_for(url)
39
+ Net::HTTP::Get.new(url)
40
+ end
41
+
42
+ def history_url(channel, timestamp=nil)
43
+ base = "#{url_for('history')}&channel=#{channel}&count=1000"
44
+ return base unless timestamp
45
+ "#{base}&latest=#{timestamp}"
46
+ end
47
+
48
+ def make_request(request)
49
+ response = connection.http_request(request)
50
+ if response.code != "200"
51
+ raise Slackr::ServiceError, "Slack.com - #{response.code} - #{response.body}"
52
+ end
53
+ JSON.parse(response.body)
54
+ end
55
+
56
+ def oldest_message(messages)
57
+ messages.min_by { |message| message["ts"]}
58
+ end
59
+ end
60
+ end
61
+
@@ -0,0 +1,51 @@
1
+ require "net/http"
2
+ require "net/https" # Obsolete as of what ruby version?
3
+ require "uri"
4
+
5
+ # slack_options
6
+ # {
7
+ # "channel" => "#myroom",
8
+ # "username" => "my_bot_name",
9
+ # "icon_url" => "https://slack.com/img/icons/app-57.png",
10
+ # "icon_emoji" => ":ghost:"
11
+ # }
12
+ module Slackr
13
+ class Connection
14
+ attr_accessor :http, :uri, :options, :team, :token
15
+
16
+ def initialize(team, token, options={})
17
+ @team, @token, @options = team, token, options
18
+ end
19
+
20
+ def init
21
+ validate_options
22
+ setup_connection
23
+ return self
24
+ end
25
+
26
+ def base_url
27
+ "https://#{@team}.slack.com"
28
+ end
29
+
30
+ def uri_request_uri
31
+ uri.request_uri
32
+ end
33
+
34
+ def http_request(request)
35
+ http.request(request)
36
+ end
37
+
38
+ private
39
+
40
+ def validate_options
41
+ (options.has_key?("channel") && options.has_key?("username")) && !options["channel"].match(/^#/).nil?
42
+ end
43
+
44
+ def setup_connection
45
+ @uri = URI.parse(base_url)
46
+ @http = Net::HTTP.new(@uri.host, @uri.port)
47
+ @http.use_ssl = true
48
+ @http.verify_mode = OpenSSL::SSL::VERIFY_PEER
49
+ end
50
+ end
51
+ end
@@ -1,3 +1,3 @@
1
1
  module Slackr
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -0,0 +1,42 @@
1
+ require "net/http"
2
+ require "net/https" # Obsolete as of what ruby version?
3
+ require "uri"
4
+ require "json"
5
+
6
+ module Slackr
7
+ module IncomingWebhook
8
+ extend self
9
+
10
+ attr_accessor :connection
11
+
12
+ # {
13
+ # :formatter => [BasicFormatter, LinkFormatter, AttachmentFormatter]
14
+ # }
15
+ def say(connection, text="", options={})
16
+ @connection = connection
17
+ #formatter = options[:formatter] || BasicFormatter
18
+ #text = format_text(formatter, text)
19
+ #TODO: fix law of demeter violations
20
+ request = Net::HTTP::Post.new(service_url)
21
+ request.body = encode_message(text, options)
22
+ response = connection.http_request(request)
23
+ if response.code != "200"
24
+ raise Slackr::ServiceError, "Slack.com - #{response.code} - #{response.body}"
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def service_url
31
+ "#{connection.base_url}/services/hooks/incoming-webhook?token=#{connection.token}"
32
+ end
33
+
34
+ def encode_message(text, options)
35
+ #TODO: extract OptionValidator
36
+ #TODO: add guard against invalid options
37
+ #TODO: add guard against nil text
38
+ connection.options.merge(options).merge({"text" => text}).to_json.to_s
39
+ end
40
+ end
41
+ end
42
+
@@ -6,11 +6,11 @@ require 'slackr/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "slackr"
8
8
  spec.version = Slackr::VERSION
9
- spec.authors = ["Jason Rohwedder"]
10
- spec.email = ["jro@risk.io"]
9
+ spec.authors = ["Jason Rohwedder", "Mike Krisher"]
10
+ spec.email = ["jro@risk.io", "mike@mikekrisher.com"]
11
11
  spec.description = %q{Talk to slack.com chat platform from ruby}
12
12
  spec.summary = %q{Send data into Slack in real-time, via the Incoming Webhooks API}
13
- spec.homepage = ""
13
+ spec.homepage = "https://github.com/risk-io/slackr"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
- spec.add_development_dependency "rake"
23
- spec.add_development_dependency "rspec"
24
- spec.add_development_dependency "webmock"
22
+ spec.add_development_dependency "rake", "~> 10.1.1", ">= 10.1.1"
23
+ spec.add_development_dependency "rspec", "~> 2.14.1", ">= 2.14.1"
24
+ spec.add_development_dependency "webmock", "~> 1.17.4", ">= 1.17.4"
25
25
  end
@@ -0,0 +1,127 @@
1
+ require 'spec_helper'
2
+
3
+ describe Slackr::Channel do
4
+ let(:connection) { Slackr::Connection.new('team', 'fakeToken').init }
5
+ subject { Slackr::Channel.init(connection) }
6
+
7
+
8
+ describe "#list" do
9
+ let(:list_body) do
10
+ {
11
+ :ok => true,
12
+ :channels => [
13
+ {
14
+ :id => "C024BE91L",
15
+ :name => "fun",
16
+ :created => "1360782804",
17
+ :creator => "U024BE7LH",
18
+ :is_archived => false,
19
+ :is_member => false,
20
+ :num_members => 6,
21
+ :topic => {
22
+ :value => "Fun times",
23
+ :creator => "U024BE7LV",
24
+ :last_set => "1369677212"
25
+ },
26
+ :purpose => {
27
+ :value => "This channel is for fun",
28
+ :creator => "U024BE7LH",
29
+ :last_set => "1360782804"
30
+ }
31
+ }
32
+ ]
33
+ }
34
+ end
35
+ before do
36
+ stub_request(:get, "https://team.slack.com/api/channels.list?token=fakeToken").
37
+ with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
38
+ to_return(:status => 200, :body => list_body.to_json, :headers => {})
39
+
40
+ stub_request(:get, "https://team.slack.com/api/channels.foo?token=fakeToken").
41
+ with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
42
+ to_return(:status => 404, :body => "", :headers => {})
43
+
44
+ stub_request(:get, "https://team.slack.com/api/channels.list?token=fakeToken").
45
+ with(:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
46
+ to_return(:status => 200, :body => list_body.to_json, :headers => {})
47
+ end
48
+ it "requests the channel list" do
49
+ expect(subject.list).to eq(JSON.parse(list_body.to_json))
50
+ end
51
+
52
+ context "with a bad request" do
53
+ it "raises an error" do
54
+ bad_url = "#{subject.connection.base_url}/api/channel.foo?token=#{subject.connection.token}"
55
+ expect(subject).to receive(:url_for).and_return(bad_url)
56
+ expect {
57
+ subject.list
58
+ }.to raise_error
59
+ end
60
+ end
61
+ end
62
+
63
+ describe "#history" do
64
+ let(:timestamp_1) { "1407368222.000037" }
65
+ def message(timestamp=timestamp_1)
66
+ {
67
+ "user" => "U02FBRY5Z",
68
+ "type" => "message",
69
+ "subtype" => "channel_join",
70
+ "text" => "<@U02FBRY5Z|USER> has joined the channel",
71
+ "ts" => timestamp
72
+ }
73
+ end
74
+ let(:message_1) { message }
75
+ let(:message_2) { message("1307368222.000037")}
76
+
77
+ def history_body(options={})
78
+ options = {messages:[message_1], has_more: false}.merge(options)
79
+ {
80
+ "ok" => true,
81
+ "messages" => options[:messages],
82
+ "has_more" => options[:has_more]
83
+ }
84
+ end
85
+ let(:long_history_body_1) { history_body(has_more: true) }
86
+ let(:long_history_body_2) { history_body(messages: [message_2]) }
87
+ let(:headers) { {:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}} }
88
+
89
+ let(:good_channel) { "goodChannel" }
90
+ let(:bad_channel) { "badChannel" }
91
+ let(:long_channel) { "longChannel" }
92
+ let(:base_history_url) {"https://team.slack.com/api/channels.history?token=fakeToken&count=1000&channel="}
93
+ let(:bad_history_url) { "#{base_history_url}#{bad_channel}" }
94
+ let(:good_history_url) { "#{base_history_url}#{good_channel}" }
95
+ let(:long_history_url_1) { "#{base_history_url}#{long_channel}" }
96
+ let(:long_history_url_2) { "#{long_history_url_1}&latest=#{timestamp_1}" }
97
+
98
+ before do
99
+ stub_request(:get, bad_history_url).with(headers).
100
+ to_return(:status => 404, :body => "", :headers => {})
101
+
102
+ stub_request(:get, good_history_url).with(headers).
103
+ to_return(:status => 200, :body => history_body.to_json, :headers => {})
104
+
105
+ stub_request(:get, long_history_url_1).with(headers).
106
+ to_return(:status => 200, :body => long_history_body_1.to_json, :headers => {})
107
+ stub_request(:get, long_history_url_2).with(headers).
108
+ to_return(:status => 200, :body => long_history_body_2.to_json, :headers => {})
109
+ end
110
+ it "requests the history of a channel" do
111
+ expect(subject.history(good_channel)).to eq(history_body) #TODO: Should this be JSON.parse(history_body.to_json)? why?
112
+ end
113
+ context "with lots of history" do
114
+ it "makes enough requests to get everything" do
115
+ expect(subject.history(long_channel)).to eql(history_body(messages: [message_1, message_2]))
116
+ expect(WebMock).to have_requested(:get, long_history_url_1).once
117
+ expect(WebMock).to have_requested(:get, long_history_url_2)
118
+ end
119
+ end
120
+ context "with a bad request" do
121
+ it "raises an error" do
122
+ expect{subject.history(bad_channel)}.to raise_error
123
+ end
124
+ end
125
+ end
126
+ end
127
+
@@ -0,0 +1,114 @@
1
+ require 'spec_helper'
2
+
3
+ describe Slackr::Connection do
4
+ describe "#init" do
5
+ before do
6
+ @subject = Slackr::Connection.new('team', 'fakeToken')
7
+ end
8
+
9
+ it "should validate the options" do
10
+ expect(@subject).to receive(:validate_options)
11
+ @subject.init
12
+ end
13
+
14
+ it "should setup the connection" do
15
+ expect(@subject).to receive(:setup_connection)
16
+ @subject.init
17
+ end
18
+ end
19
+
20
+ describe "#base_url" do
21
+ it "should return the complete url with subdomain" do
22
+ subject = Slackr::Connection.new("foo", "bar")
23
+ expect(subject.send(:base_url)).to eq("https://foo.slack.com")
24
+ end
25
+ end
26
+
27
+ describe "#uri_request_uri" do
28
+ it "should return the request_url of the uri" do
29
+ subject = Slackr::Connection.new("team", "token", {"channel" => "#foo", "username" => "baz"})
30
+ subject.send(:setup_connection)
31
+ expect(subject.uri_request_uri).to eq("/")
32
+ end
33
+ end
34
+
35
+ describe "#http_request" do
36
+ before do
37
+ stub_request(:post, "https://team.slack.com/").
38
+ with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
39
+ to_return(:status => 200, :body => "", :headers => {})
40
+
41
+ stub_request(:post, "https://team.slack.com/").
42
+ with(:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
43
+ to_return(:status => 200, :body => "", :headers => {})
44
+ end
45
+
46
+ it "should return the request_url of the http" do
47
+ subject = Slackr::Connection.new("team", "token", {"channel" => "#foo", "username" => "baz"})
48
+ subject.send(:setup_connection)
49
+ request = Net::HTTP::Post.new(subject.uri_request_uri)
50
+ response = subject.http_request(request)
51
+ expect(response.code).to eq("200")
52
+ end
53
+ end
54
+
55
+
56
+ describe "#validate_options" do
57
+ before do
58
+ @subject = Slackr::Connection.new('team', 'fakeToken')
59
+ end
60
+
61
+ context 'with valid options' do
62
+ it "should return true" do
63
+ options = {
64
+ "channel" => "#myroom",
65
+ "username" => "my_bot_name"
66
+ }
67
+ @subject.instance_variable_set(:@options, options)
68
+ expect(@subject.send(:validate_options)).to eq(true)
69
+ end
70
+ end
71
+
72
+ context 'with invalid options' do
73
+ context 'with improper channel name' do
74
+ it "should return false" do
75
+ options = {
76
+ "channel" => "foo",
77
+ "username" => "my_bot_name"
78
+ }
79
+ @subject.instance_variable_set(:@options, options)
80
+ expect(@subject.send(:validate_options)).to eq(false)
81
+ end
82
+ end
83
+
84
+ context 'with missing username' do
85
+ it "should return false" do
86
+ options = {
87
+ "channel" => "foo"
88
+ }
89
+ @subject.instance_variable_set(:@options, options)
90
+ expect(@subject.send(:validate_options)).to eq(false)
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ describe "#setup_connection" do
97
+ before do
98
+ @subject = Slackr::Connection.new("team", "token", {"channel" => "#foo", "username" => "bot"})
99
+ end
100
+
101
+ it "should define the uri instance variable" do
102
+ expect(@subject.uri).to be_nil
103
+ @subject.send(:setup_connection)
104
+ expect(@subject.uri).to_not be_nil
105
+ end
106
+
107
+ it "should define the http isntance variable" do
108
+ expect(@subject.http).to be_nil
109
+ @subject.send(:setup_connection)
110
+ expect(@subject.http).to_not be_nil
111
+ end
112
+ end
113
+ end
114
+
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+
3
+ describe Slackr::IncomingWebhook do
4
+ before do
5
+ @connection = Slackr::Connection.new("team", "token", {})
6
+ @connection.send(:setup_connection)
7
+
8
+ stub_request(:post, "https://team.slack.com/services/hooks/incoming-webhook?token=token").
9
+ with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
10
+ to_return(:status => 200, :body => "", :headers => {})
11
+
12
+ stub_request(:post, "https://team.slack.com/services/hooks/incoming-webhook?token=token").
13
+ with(:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
14
+ to_return(:status => 200, :body => "", :headers => {})
15
+ end
16
+
17
+ context "Public API" do
18
+ describe "#say" do
19
+ it "should send the request, posting the message in the channel" do
20
+ text = "This is a test message"
21
+ options = {"channel" => "#somewhere"}
22
+ expect(Slackr::IncomingWebhook).to receive(:encode_message)
23
+ Slackr::IncomingWebhook.say(@connection, text, options)
24
+ end
25
+ end
26
+ end
27
+
28
+ context "Private API" do
29
+ describe "#service_url" do
30
+ it "should generate the right url" do
31
+ subject.instance_variable_set(:@connection, @connection)
32
+ result = subject.send(:service_url)
33
+ expect(result).to eq "https://team.slack.com/services/hooks/incoming-webhook?token=token"
34
+ end
35
+ end
36
+
37
+ describe "#encode_message" do
38
+ it "should encode a basic message" do
39
+ text = "this is my awesome message"
40
+
41
+ result = subject.send(:encode_message, text, {})
42
+ expect(result).to eq "{\"text\":\"#{text}\"}"
43
+ end
44
+
45
+ it "should encode a message with options" do
46
+ text = "this is my awesome message"
47
+ options = {"channel" => "#awesometown"}
48
+
49
+ result = subject.send(:encode_message, text, options)
50
+ expect(result).to eq "{\"channel\":\"#awesometown\",\"text\":\"#{text}\"}"
51
+ end
52
+
53
+ it "should encode a basic message when there are default options" do
54
+ text = "this is my awesome message"
55
+
56
+ subject.connection.stub(:options).and_return({"icon_emoji" => "ghost"})
57
+ result = subject.send(:encode_message, text, {})
58
+ expect(result).to eq("{\"icon_emoji\":\"ghost\",\"text\":\"#{text}\"}")
59
+ end
60
+
61
+ it "should encode a message with option when there are default options present" do
62
+ text = "this is my awesome message"
63
+ options = {"channel" => "#awesometown"}
64
+
65
+ subject.connection.stub(:options).and_return({"icon_emoji" => "ghost"})
66
+ result = subject.send(:encode_message, text, options)
67
+ expect(result).to eq("{\"icon_emoji\":\"ghost\",\"channel\":\"#awesometown\",\"text\":\"#{text}\"}")
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Slackr do
4
+ describe "#say" do
5
+ it "should delegate to the IncomingWebhook" do
6
+ subject = Slackr.connect("foo", "bar", {"channel" => "#general", "username" => "baz"})
7
+ expect(Slackr::IncomingWebhook).to receive(:say)
8
+ subject.say("hello world", {})
9
+ end
10
+ end
11
+
12
+ describe "Webook.new" do
13
+ before do
14
+ @orig_stderr = $stderr
15
+ $stderr = StringIO.new
16
+ end
17
+
18
+ it "should raise a deprecation warning" do
19
+ Slackr::Webhook.new("team", "token")
20
+ $stderr.rewind
21
+ $stderr.string.chomp.should match(/^\[DEPRECATION\]/)
22
+ end
23
+
24
+ after do
25
+ $stderr = @orig_stderr
26
+ end
27
+ end
28
+ end
29
+
@@ -1,8 +1,8 @@
1
- $LOAD_PATH.unshift(File.dirname(__FILE__))
2
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
1
+ Dir.glob('../lib/**/*.rb', &method(:require))
3
2
 
4
3
  require 'slackr'
5
4
  require 'webmock/rspec'
5
+ require 'pry'
6
6
 
7
7
  RSpec.configure do |config|
8
8
  # Use color in STDOUT
metadata CHANGED
@@ -2,99 +2,125 @@
2
2
  name: slackr
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.2
5
+ version: 0.0.5
6
6
  platform: ruby
7
7
  authors:
8
8
  - Jason Rohwedder
9
+ - Mike Krisher
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2014-01-27 00:00:00.000000000 Z
13
+ date: 2014-09-13 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
16
+ type: :development
15
17
  prerelease: false
16
18
  name: bundler
17
- type: :development
18
19
  requirement: !ruby/object:Gem::Requirement
20
+ none: false
19
21
  requirements:
20
22
  - - ~>
21
23
  - !ruby/object:Gem::Version
22
24
  version: '1.3'
23
- none: false
24
25
  version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
25
27
  requirements:
26
28
  - - ~>
27
29
  - !ruby/object:Gem::Version
28
30
  version: '1.3'
29
- none: false
30
31
  - !ruby/object:Gem::Dependency
32
+ type: :development
31
33
  prerelease: false
32
34
  name: rake
33
- type: :development
34
35
  requirement: !ruby/object:Gem::Requirement
36
+ none: false
35
37
  requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 10.1.1
36
41
  - - ! '>='
37
42
  - !ruby/object:Gem::Version
38
- version: '0'
39
- none: false
43
+ version: 10.1.1
40
44
  version_requirements: !ruby/object:Gem::Requirement
45
+ none: false
41
46
  requirements:
47
+ - - ~>
48
+ - !ruby/object:Gem::Version
49
+ version: 10.1.1
42
50
  - - ! '>='
43
51
  - !ruby/object:Gem::Version
44
- version: '0'
45
- none: false
52
+ version: 10.1.1
46
53
  - !ruby/object:Gem::Dependency
54
+ type: :development
47
55
  prerelease: false
48
56
  name: rspec
49
- type: :development
50
57
  requirement: !ruby/object:Gem::Requirement
58
+ none: false
51
59
  requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: 2.14.1
52
63
  - - ! '>='
53
64
  - !ruby/object:Gem::Version
54
- version: '0'
55
- none: false
65
+ version: 2.14.1
56
66
  version_requirements: !ruby/object:Gem::Requirement
67
+ none: false
57
68
  requirements:
69
+ - - ~>
70
+ - !ruby/object:Gem::Version
71
+ version: 2.14.1
58
72
  - - ! '>='
59
73
  - !ruby/object:Gem::Version
60
- version: '0'
61
- none: false
74
+ version: 2.14.1
62
75
  - !ruby/object:Gem::Dependency
76
+ type: :development
63
77
  prerelease: false
64
78
  name: webmock
65
- type: :development
66
79
  requirement: !ruby/object:Gem::Requirement
80
+ none: false
67
81
  requirements:
82
+ - - ~>
83
+ - !ruby/object:Gem::Version
84
+ version: 1.17.4
68
85
  - - ! '>='
69
86
  - !ruby/object:Gem::Version
70
- version: '0'
71
- none: false
87
+ version: 1.17.4
72
88
  version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
73
90
  requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 1.17.4
74
94
  - - ! '>='
75
95
  - !ruby/object:Gem::Version
76
- version: '0'
77
- none: false
96
+ version: 1.17.4
78
97
  description: Talk to slack.com chat platform from ruby
79
98
  email:
80
99
  - jro@risk.io
100
+ - mike@mikekrisher.com
81
101
  executables: []
82
102
  extensions: []
83
103
  extra_rdoc_files: []
84
104
  files:
85
105
  - .gitignore
106
+ - .travis.yml
86
107
  - Gemfile
87
108
  - LICENSE.txt
88
109
  - README.md
89
110
  - Rakefile
90
111
  - lib/slackr.rb
112
+ - lib/slackr/channel.rb
113
+ - lib/slackr/connection.rb
91
114
  - lib/slackr/errors.rb
92
115
  - lib/slackr/version.rb
93
- - lib/slackr/webhook.rb
116
+ - lib/slackr/webhooks/incoming.rb
94
117
  - slackr.gemspec
118
+ - spec/slackr/channel_spec.rb
119
+ - spec/slackr/connection_spec.rb
120
+ - spec/slackr/webhooks/incoming_spec.rb
121
+ - spec/slackr_spec.rb
95
122
  - spec/spec_helper.rb
96
- - spec/webhook_spec.rb
97
- homepage: ''
123
+ homepage: https://github.com/risk-io/slackr
98
124
  licenses:
99
125
  - MIT
100
126
  post_install_message:
@@ -102,29 +128,26 @@ rdoc_options: []
102
128
  require_paths:
103
129
  - lib
104
130
  required_ruby_version: !ruby/object:Gem::Requirement
131
+ none: false
105
132
  requirements:
106
133
  - - ! '>='
107
134
  - !ruby/object:Gem::Version
108
- segments:
109
- - 0
110
- hash: 4548143177958109987
111
135
  version: '0'
112
- none: false
113
136
  required_rubygems_version: !ruby/object:Gem::Requirement
137
+ none: false
114
138
  requirements:
115
139
  - - ! '>='
116
140
  - !ruby/object:Gem::Version
117
- segments:
118
- - 0
119
- hash: 4548143177958109987
120
141
  version: '0'
121
- none: false
122
142
  requirements: []
123
143
  rubyforge_project:
124
- rubygems_version: 1.8.28
144
+ rubygems_version: 1.8.23.2
125
145
  signing_key:
126
146
  specification_version: 3
127
147
  summary: Send data into Slack in real-time, via the Incoming Webhooks API
128
148
  test_files:
149
+ - spec/slackr/channel_spec.rb
150
+ - spec/slackr/connection_spec.rb
151
+ - spec/slackr/webhooks/incoming_spec.rb
152
+ - spec/slackr_spec.rb
129
153
  - spec/spec_helper.rb
130
- - spec/webhook_spec.rb
@@ -1,62 +0,0 @@
1
- require "net/http"
2
- require "net/https" # Obsolete as of what ruby version?
3
- require "uri"
4
- require "json"
5
-
6
- # slack_options
7
- # {
8
- # "channel" => "#myroom",
9
- # "username" => "my_bot_name",
10
- # "icon_url" => "https://slack.com/img/icons/app-57.png",
11
- # "icon_emoji" => ":ghost:"
12
- # }
13
-
14
- module Slackr
15
-
16
- class Webhook
17
- attr_reader :http, :uri, :default_options
18
-
19
- def initialize(team,token,options={})
20
- raise Slackr::ArgumentError, "Team required" if team.nil?
21
- raise Slackr::ArgumentError, "Token required" if token.nil?
22
-
23
- @team = team
24
- @token = token
25
- @default_options = options
26
-
27
- setup_connection
28
- end
29
-
30
- def say(text="",options={})
31
- # reformat links, etc here
32
- send_request(text,options)
33
- end
34
-
35
- private
36
-
37
- def setup_connection
38
- @uri = URI.parse(service_url)
39
- @http = Net::HTTP.new(@uri.host, @uri.port)
40
- @http.use_ssl = true
41
- @http.verify_mode = OpenSSL::SSL::VERIFY_PEER
42
- end
43
-
44
- def service_url
45
- "https://#{@team}.slack.com/services/hooks/incoming-webhook?token=#{@token}"
46
- end
47
-
48
- def encode_message(text,options)
49
- "payload=#{default_options.merge(options).merge({"text" => text}).to_json.to_s}"
50
- end
51
-
52
- def send_request(text,options)
53
- request = Net::HTTP::Post.new(uri.request_uri)
54
- request.body = encode_message(text,options)
55
- response = http.request(request)
56
- unless response.code == "200"
57
- raise Slackr::ServiceError, "Slack.com - #{response.code} - #{response.body}"
58
- end
59
- end
60
-
61
- end
62
- end
@@ -1,57 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Slackr::Webhook do
4
- let(:client) { Slackr::Webhook.new("team","token") }
5
- subject { client }
6
-
7
- describe "#say" do
8
- it "should call Webhook#send_request with proper options" do
9
- msg = "This is a test message"
10
- opts = {"channel" => "#somewhere"}
11
-
12
- subject.should_receive(:send_request).with(msg,opts)
13
- subject.say msg,opts
14
- end
15
- end
16
-
17
- describe "#service_url" do
18
- it "should generate the right url" do
19
- team = "my-team"
20
- token = "my-token"
21
- subject = Slackr::Webhook.new(team,token)
22
-
23
- subject.send(:service_url).should eq "https://#{team}.slack.com/services/hooks/incoming-webhook?token=#{token}"
24
- end
25
- end
26
-
27
- describe "#encode_message" do
28
- it "should encode a basic message" do
29
- msg = "this is my awesome message"
30
-
31
- subject.send(:encode_message,msg,{}).should eq "payload={\"text\":\"#{msg}\"}"
32
- end
33
-
34
- it "should encode a message with options" do
35
- msg = "this is my awesome message"
36
- opts = {"channel" => "#awesometown"}
37
-
38
- subject.send(:encode_message,msg,opts).should eq "payload={\"channel\":\"#awesometown\",\"text\":\"#{msg}\"}"
39
- end
40
-
41
- it "should encode a basic message when there are default options" do
42
- msg = "this is my awesome message"
43
-
44
- subject.stub(:default_options).and_return({"icon_emoji" => "ghost"})
45
- subject.send(:encode_message,msg,{}).should eq "payload={\"icon_emoji\":\"ghost\",\"text\":\"#{msg}\"}"
46
- end
47
-
48
- it "should encode a message with option when there are default options present" do
49
- msg = "this is my awesome message"
50
- opts = {"channel" => "#awesometown"}
51
-
52
- subject.stub(:default_options).and_return({"icon_emoji" => "ghost"})
53
- subject.send(:encode_message,msg,opts).should eq "payload={\"icon_emoji\":\"ghost\",\"channel\":\"#awesometown\",\"text\":\"#{msg}\"}"
54
- end
55
- end
56
-
57
- end