rocket-chat-notifier 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ddf5914ca33f6d13f39a46dcfee73ec6abc3bd63
4
+ data.tar.gz: 6923aec7d0d30e56861ff493227b43da98c71cf5
5
+ SHA512:
6
+ metadata.gz: e973cd17d57fccb103a39ae552b9c6d50615a368069a7ff0ea13b2f231d67b9acde5d1f2656084c3463cd37bdaf9da572e4e630d5d610f7d49219eae39514247
7
+ data.tar.gz: 213602b05e9da9829cc2ce06874c9ada81ace4b48b5e282ec2a5ed8a2f2d9cfb68c91eba1e2a2ade571364215c66627a9d27f31904296857fd886610b8926257
@@ -0,0 +1,74 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'json'
4
+
5
+ require_relative 'rocket-chat-notifier/default_http_client'
6
+ require_relative 'rocket-chat-notifier/message_formatter'
7
+
8
+ module RocketChat
9
+ class Notifier
10
+ attr_reader :endpoint, :default_payload
11
+
12
+ def initialize webhook_url, options={}
13
+ @endpoint = URI.parse webhook_url
14
+ @default_payload = options
15
+ end
16
+
17
+ def ping message, options={}
18
+ if message.is_a?(Hash)
19
+ message, options = nil, message
20
+ end
21
+
22
+ if attachments = options[:attachments] || options["attachments"]
23
+ wrap_array(attachments).each do |attachment|
24
+ ["text", :text].each do |key|
25
+ attachment[key] = MessageFormatter.format(attachment[key]) if attachment.has_key?(key)
26
+ end
27
+ end
28
+ end
29
+
30
+ payload = default_payload.merge(options)
31
+ client = payload.delete(:http_client) || http_client
32
+ http_options = payload.delete(:http_options)
33
+
34
+ unless message.nil?
35
+ payload.merge!(text: MessageFormatter.format(message))
36
+ end
37
+
38
+ params = { payload: payload.to_json }
39
+ params[:http_options] = http_options if http_options
40
+
41
+ client.post endpoint, params
42
+ end
43
+
44
+ def http_client
45
+ default_payload.fetch :http_client, DefaultHTTPClient
46
+ end
47
+
48
+ def channel
49
+ default_payload[:channel]
50
+ end
51
+
52
+ def channel= channel
53
+ default_payload[:channel] = channel
54
+ end
55
+
56
+ def username
57
+ default_payload[:username]
58
+ end
59
+
60
+ def username= username
61
+ default_payload[:username] = username
62
+ end
63
+
64
+ def wrap_array(object)
65
+ if object.nil?
66
+ []
67
+ elsif object.respond_to?(:to_ary)
68
+ object.to_ary || [object]
69
+ else
70
+ [object]
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,51 @@
1
+ module RocketChat
2
+ class Notifier
3
+
4
+ class DefaultHTTPClient
5
+
6
+ class << self
7
+ def post uri, params
8
+ DefaultHTTPClient.new( uri, params ).call
9
+ end
10
+ end
11
+
12
+ attr_reader :uri, :params, :http_options
13
+
14
+ def initialize uri, params
15
+ @uri = uri
16
+ @http_options = params.delete(:http_options) || {}
17
+ @params = params
18
+ end
19
+
20
+ def call
21
+ http_obj.request request_obj
22
+ end
23
+
24
+ private
25
+
26
+ def request_obj
27
+ req = Net::HTTP::Post.new uri.request_uri
28
+ req.set_form_data params
29
+
30
+ return req
31
+ end
32
+
33
+ def http_obj
34
+ http = Net::HTTP.new uri.host, uri.port
35
+ http.use_ssl = (uri.scheme == "https")
36
+
37
+ http_options.each do |opt, val|
38
+ if http.respond_to? "#{opt}="
39
+ http.send "#{opt}=", val
40
+ else
41
+ warn "Net::HTTP doesn't respond to `#{opt}=`, ignoring that option"
42
+ end
43
+ end
44
+
45
+ return http
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,54 @@
1
+ module RocketChat
2
+ class Notifier
3
+ class MessageFormatter
4
+
5
+ class << self
6
+
7
+ def format string
8
+ MessageFormatter.new(string).formatted
9
+ end
10
+
11
+ end
12
+
13
+ def initialize string
14
+ @orig = if string.respond_to? :scrub
15
+ string.scrub
16
+ else
17
+ string
18
+ end
19
+ end
20
+
21
+ def formatted
22
+ @orig
23
+
24
+ rescue => e
25
+ if RUBY_VERSION < '2.1' && e.message.include?('invalid byte sequence')
26
+ raise e, "#{e.message}. Consider including the 'string-scrub' gem to strip invalid characters"
27
+ else
28
+ raise e
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def slack_link link, text=nil
35
+ out = "<#{link}"
36
+ out << "|#{text}" if text && !text.empty?
37
+ out << ">"
38
+
39
+ return out
40
+ end
41
+
42
+ # http://rubular.com/r/19cNXW5qbH
43
+ def html_pattern
44
+ / <a (?:.*?) href=['"](.+?)['"] (?:.*?)> (.+?) <\/a> /x
45
+ end
46
+
47
+ # http://rubular.com/r/guJbTK6x1f
48
+ def markdown_pattern
49
+ /\[ ([^\[\]]*?) \] \( ((https?:\/\/.*?) | (mailto:.*?)) \) /x
50
+ end
51
+
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,5 @@
1
+ module RocketChat
2
+ class Notifier
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,71 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ RSpec.describe RocketChat::Notifier do
5
+
6
+ before :each do
7
+ @http_client = double("RocketChat::Notifier::DefaultHTTPClient")
8
+ end
9
+
10
+ {
11
+ ['hello', {}] =>
12
+ { payload: { text:"hello" }.to_json },
13
+
14
+ ['[hello](http://example.com/world)', {}] =>
15
+ { payload: { text: '[hello](http://example.com/world)' }.to_json },
16
+
17
+ ['hello/こんにちは from notifier test', {}] =>
18
+ { payload: { text: 'hello/こんにちは from notifier test' }.to_json },
19
+
20
+ ['Hello World, enjoy [this](http://example.com)[this2](http://example2.com)', {}] =>
21
+ { payload: { text: 'Hello World, enjoy [this](http://example.com)[this2](http://example2.com)'}.to_json },
22
+
23
+ ['[John](mailto:john@example.com)', {}] =>
24
+ { payload: { text: "[John](mailto:john@example.com)"}.to_json },
25
+
26
+ ['hello', { channel: 'hodor' }] =>
27
+ { payload: { channel: 'hodor', text: 'hello' }.to_json },
28
+
29
+ ['the message', { channel: 'foo',
30
+ attachments: [{ color: '#000',
31
+ text: 'attachment message',
32
+ fallback: 'fallback message' }] }] =>
33
+ { payload: { channel: 'foo',
34
+ attachments: [ { color: '#000',
35
+ text: 'attachment message',
36
+ fallback: 'fallback message' } ],
37
+ text: 'the message' }.to_json },
38
+
39
+ [{ attachments: [{ color: '#000',
40
+ text: 'attachment message',
41
+ fallback: 'fallback message' }] }] =>
42
+ { payload: { attachments: [{ color: '#000',
43
+ text: 'attachment message',
44
+ fallback: 'fallback message' }] }.to_json },
45
+
46
+ [{ attachments: { color: '#000',
47
+ text: 'attachment message [hodor](http://winterfell.com)',
48
+ fallback: 'fallback message' } }] =>
49
+ { payload: { attachments: { color: '#000',
50
+ text: 'attachment message [hodor](http://winterfell.com)',
51
+ fallback: 'fallback message' } }.to_json },
52
+
53
+ ['hello', { http_options: { timeout: 5 } }] =>
54
+ { http_options: { timeout: 5 }, payload: { text: 'hello' }.to_json }
55
+
56
+
57
+ }.each do |args, payload|
58
+
59
+ it "sends correct payload for #{args}" do
60
+ notifier = RocketChat::Notifier.new 'http://example.com', http_client: @http_client
61
+
62
+ expect( @http_client ).to receive(:post)
63
+ .with( URI.parse('http://example.com'),
64
+ payload )
65
+
66
+ notifier.ping *args
67
+ end
68
+ end
69
+
70
+
71
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+ require_relative '../../lib/rocket-chat-notifier'
3
+
4
+ notifier = RocketChat::Notifier.new ENV['ROCKET_CHAT_WEBHOOK_URL'], username: 'notifier'
5
+ puts "testing with ruby #{RUBY_VERSION}"
6
+ notifier.ping "hello/こんにちは from notifier test script on ruby: #{RUBY_VERSION}\225"
7
+ notifier.ping attachments: [{color:"#1BF5AF",fallback:"fallback",text:"attachment"}]
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe RocketChat::Notifier::DefaultHTTPClient do
4
+
5
+ describe "::post" do
6
+ it "initializes DefaultHTTPClient with the given uri and params then calls" do
7
+ http_post_double = instance_double("RocketChat::Notifier::DefaultHTTPClient")
8
+
9
+ expect( described_class ).to receive(:new)
10
+ .with( 'uri', 'params' )
11
+ .and_return( http_post_double )
12
+ expect( http_post_double ).to receive(:call)
13
+
14
+ described_class.post 'uri', 'params'
15
+ end
16
+ end
17
+
18
+ describe "#initialize" do
19
+ it "allows setting of options for Net::HTTP" do
20
+ net_http_double = instance_double("Net::HTTP")
21
+ http_client = described_class.new( URI.parse('http://example.com'), http_options: { open_timeout: 5 })
22
+
23
+ allow( Net::HTTP ).to receive(:new)
24
+ .and_return(net_http_double)
25
+ allow( net_http_double ).to receive(:use_ssl=)
26
+ allow( net_http_double ).to receive(:request)
27
+
28
+ expect( net_http_double ).to receive(:open_timeout=).with(5)
29
+
30
+ http_client.call
31
+ end
32
+ end
33
+
34
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe RocketChat::Notifier::MessageFormatter do
5
+
6
+ describe "::format" do
7
+
8
+ if "".respond_to? :scrub
9
+ context "when on ruby 2.1+ or have string-scrub installed" do
10
+ it "handles invalid unicode sequences" do
11
+ expect {
12
+ described_class.format("This sequence is invalid: \255")
13
+ }.not_to raise_error
14
+ end
15
+
16
+ it "replaces invalid unicode sequences with the unicode replacement character" do
17
+ formatted = described_class.format("\255")
18
+ expect(formatted).to eq "\uFFFD"
19
+ end
20
+ end
21
+ end
22
+
23
+ it "doesn't replace valid Japanese" do
24
+ formatted = described_class.format("こんにちは")
25
+ expect(formatted).to eq "こんにちは"
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,156 @@
1
+ require 'spec_helper'
2
+
3
+ describe RocketChat::Notifier do
4
+ subject { described_class.new 'http://example.com' }
5
+
6
+ describe "#initialize" do
7
+ it "sets the given hook_url to the endpoint URI" do
8
+ expect( subject.endpoint ).to eq URI.parse 'http://example.com'
9
+ end
10
+
11
+ it "sets the default_payload options" do
12
+ subject = described_class.new 'http://example.com', channel: 'foo'
13
+ expect( subject.channel ).to eq 'foo'
14
+ end
15
+
16
+ it "sets a custom http client" do
17
+ client = double("CustomClient")
18
+ subject = described_class.new 'http://example.com', http_client: client
19
+ expect( subject.http_client ).to eq client
20
+ end
21
+ end
22
+
23
+ describe "#ping" do
24
+ before :each do
25
+ allow( RocketChat::Notifier::DefaultHTTPClient ).to receive(:post)
26
+ end
27
+
28
+ it "passes the message through MessageFormatter" do
29
+ expect( RocketChat::Notifier::MessageFormatter ).to receive(:format)
30
+ .with("the message")
31
+
32
+ described_class.new('http://example.com').ping "the message", channel: 'foo'
33
+ end
34
+
35
+ it "passes attachment messages through MessageFormatter" do
36
+ expect( RocketChat::Notifier::MessageFormatter ).to receive(:format)
37
+ .with("the message")
38
+ expect( RocketChat::Notifier::MessageFormatter ).to receive(:format)
39
+ .with("attachment message")
40
+
41
+ described_class.new('http://example.com').ping "the message", channel: 'foo',
42
+ attachments: [{
43
+ color: "#000",
44
+ text: "attachment message",
45
+ fallback: "fallback message"
46
+ }]
47
+ end
48
+
49
+ it "allows sending only an attachment" do
50
+ expect( RocketChat::Notifier::DefaultHTTPClient ).to receive(:post).with(
51
+ URI.parse('http://example.com'),
52
+ payload: '{"channel":"foo","attachments":[{"text":"attachment","fallback":"fallback"}]}'
53
+ )
54
+
55
+ expect{
56
+ described_class.new('http://example.com')
57
+ .ping channel: 'foo',
58
+ attachments: [{
59
+ text: 'attachment',
60
+ fallback: 'fallback'
61
+ }]
62
+ }.not_to raise_error
63
+ end
64
+
65
+ it "passes attachment messages through MessageFormatter, even if a single value is passed" do
66
+ expect( RocketChat::Notifier::MessageFormatter ).to receive(:format)
67
+ .with("a random message")
68
+ expect( RocketChat::Notifier::MessageFormatter ).to receive(:format)
69
+ .with("attachment message")
70
+ attachment = {
71
+ color: "#000",
72
+ text: "attachment message",
73
+ fallback: "fallback message"
74
+ }
75
+ subject.ping "a random message", attachments: attachment
76
+ end
77
+
78
+ context "with a default channel set" do
79
+
80
+ before :each do
81
+ @endpoint_double = instance_double "URI::HTTP"
82
+ allow( URI ).to receive(:parse)
83
+ .and_return(@endpoint_double)
84
+ subject.channel = '#default'
85
+ end
86
+
87
+ it "does not require a channel to ping" do
88
+ expect{
89
+ subject.ping "the message"
90
+ }.not_to raise_error
91
+ end
92
+
93
+ it "uses default channel" do
94
+ expect( RocketChat::Notifier::DefaultHTTPClient ).to receive(:post)
95
+ .with @endpoint_double,
96
+ payload: '{"channel":"#default","text":"the message"}'
97
+
98
+ subject.ping "the message"
99
+ end
100
+
101
+ it "allows override channel to be set" do
102
+ expect( RocketChat::Notifier::DefaultHTTPClient ).to receive(:post)
103
+ .with @endpoint_double,
104
+ payload: '{"channel":"new","text":"the message"}'
105
+
106
+ subject.ping "the message", channel: "new"
107
+ end
108
+
109
+ end
110
+
111
+ context "with default webhook" do
112
+ it "posts with the correct endpoint & data" do
113
+ @endpoint_double = instance_double "URI::HTTP"
114
+ allow( URI ).to receive(:parse)
115
+ .with("http://example.com")
116
+ .and_return(@endpoint_double)
117
+
118
+ expect( RocketChat::Notifier::DefaultHTTPClient ).to receive(:post)
119
+ .with @endpoint_double,
120
+ payload: '{"channel":"channel","text":"the message"}'
121
+
122
+ described_class.new("http://example.com").ping "the message", channel: "channel"
123
+ end
124
+ end
125
+
126
+ context "with a custom http_client set" do
127
+ it "uses it" do
128
+ endpoint_double = instance_double "URI::HTTP"
129
+ allow( URI ).to receive(:parse)
130
+ .with("http://example.com")
131
+ .and_return(endpoint_double)
132
+ client = double("CustomClient")
133
+ expect( client ).to receive(:post)
134
+ .with endpoint_double,
135
+ payload: '{"text":"the message"}'
136
+
137
+ described_class.new('http://example.com',http_client: client).ping "the message"
138
+ end
139
+ end
140
+ end
141
+
142
+ describe "#channel=" do
143
+ it "sets the given channel" do
144
+ subject.channel = "#foo"
145
+ expect( subject.channel ).to eq "#foo"
146
+ end
147
+ end
148
+
149
+ describe "#username=" do
150
+ it "sets the given username" do
151
+ subject.username = "foo"
152
+ expect( subject.username ).to eq "foo"
153
+ end
154
+ end
155
+
156
+ end
@@ -0,0 +1,13 @@
1
+ require 'rspec'
2
+ require 'rocket-chat-notifier'
3
+
4
+ if ENV['DEBUG']
5
+ require 'pry'
6
+ end
7
+
8
+ RSpec.configure do |config|
9
+ config.mock_with :rspec do |mocks|
10
+ mocks.verify_doubled_constant_names = true
11
+ mocks.verify_partial_doubles = true
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rocket-chat-notifier
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Thiago Felix
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-09-13 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: " A slim ruby wrapper for posting to Rocket.Chat webhooks "
14
+ email:
15
+ - thiago@thiagofelix.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/rocket-chat-notifier.rb
21
+ - lib/rocket-chat-notifier/default_http_client.rb
22
+ - lib/rocket-chat-notifier/message_formatter.rb
23
+ - lib/rocket-chat-notifier/version.rb
24
+ - spec/end_to_end_spec.rb
25
+ - spec/integration/ping_integration_test.rb
26
+ - spec/lib/rocket-chat-notifier/default_http_client_spec.rb
27
+ - spec/lib/rocket-chat-notifier/message_formatter_spec.rb
28
+ - spec/lib/rocket-chat-notifier_spec.rb
29
+ - spec/spec_helper.rb
30
+ homepage: http://github.com/thiagofelix/rocket-chat-notifier
31
+ licenses:
32
+ - MIT
33
+ metadata: {}
34
+ post_install_message:
35
+ rdoc_options: []
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ requirements: []
49
+ rubyforge_project:
50
+ rubygems_version: 2.4.5.1
51
+ signing_key:
52
+ specification_version: 4
53
+ summary: A slim ruby wrapper for posting to Rocket.Chat webhooks
54
+ test_files:
55
+ - spec/end_to_end_spec.rb
56
+ - spec/integration/ping_integration_test.rb
57
+ - spec/lib/rocket-chat-notifier/default_http_client_spec.rb
58
+ - spec/lib/rocket-chat-notifier/message_formatter_spec.rb
59
+ - spec/lib/rocket-chat-notifier_spec.rb
60
+ - spec/spec_helper.rb
61
+ has_rdoc: