bobble 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,112 @@
1
+ require 'bobble/notifier/twilio'
2
+ require 'bobble/notifier/google_voice'
3
+ require 'bobble/notifier/gmail'
4
+
5
+ module Bobble
6
+ class Checker
7
+ class << self
8
+
9
+ def check(url, options={})
10
+ {
11
+ # The status that is considered a success.
12
+ # If nil, any status other than 50x is success.
13
+ :success_status => nil,
14
+ # Specified headers are required for the response
15
+ # to be considered a success.
16
+ # Regex values can be specified.
17
+ :success_header => nil,
18
+ # Response body must match the specified body.
19
+ # Can be a regex.
20
+ :success_body => nil
21
+ }.update(options)
22
+
23
+ begin
24
+ response = http_request(url)
25
+ assert_success(response, options)
26
+ puts "Successful!: #{url}"
27
+ rescue Exception => e
28
+ message = "FAILED: #{url} - #{e.message}"
29
+ puts message
30
+
31
+ self.send_notification(message, url)
32
+ end
33
+ end
34
+
35
+ def http_request(url)
36
+ uri = URI.parse(url)
37
+ http = Net::HTTP.new(uri.host, uri.port)
38
+ request = Net::HTTP::Get.new(uri.request_uri)
39
+ return http.request(request)
40
+ end
41
+
42
+ # raises an exception if not successful
43
+ def assert_success(response, options)
44
+ if response.code.to_i >= 500
45
+ raise Exception.new("Response status code error: #{response.code}")
46
+ end
47
+
48
+ if options[:success_status]
49
+ unless response.code.to_i == options[:success_status].to_i
50
+ raise Exception.new("Response status code error. Is: #{response.code} Expected: #{options[:success_status]}")
51
+ end
52
+ end
53
+
54
+ if options[:success_header]
55
+ options[:success_header].each do |k,v|
56
+ header_value = response.header[k.to_s]
57
+ if v.is_a?(Regexp)
58
+ unless header_value =~ v
59
+ raise Exception.new("Response header '#{k}' should match regexp #{v} ('#{header_value}' does not match)")
60
+ end
61
+ else
62
+ unless header_value == v
63
+ raise Exception.new("Response header '#{k}' should have value '#{v}' (instead is #{header_value})")
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ if options[:success_body]
70
+ match = options[:success_body]
71
+ if match.is_a?(Regexp)
72
+ unless response.body =~ match
73
+ raise Exception.new("Response body should match regexp #{match}, but does not.")
74
+ end
75
+ else
76
+ unless response.body.strip == match.strip
77
+ raise Exception.new("Response body should be '#{match}', instead is '#{response.body}'")
78
+ end
79
+ end
80
+ end
81
+
82
+ end
83
+
84
+ def send_notification(message, url)
85
+ if Bobble.option(:gmail)
86
+ begin
87
+ Notifier::Gmail.send(message, url)
88
+ rescue Exception => e
89
+ puts "Gmail Notifier failed: #{e.message}"
90
+ end
91
+ end
92
+
93
+ if Bobble.option(:twilio)
94
+ begin
95
+ Notifier::Twilio.send(message)
96
+ rescue Exception => e
97
+ puts "Twilio Notifier failed: #{e.message}"
98
+ end
99
+ end
100
+
101
+ if Bobble.option(:google_voice)
102
+ begin
103
+ Notifier::GoogleVoice.send(message)
104
+ rescue Exception => e
105
+ puts "Google Voice Notifier failed: #{e.message}"
106
+ end
107
+ end
108
+ end
109
+
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,29 @@
1
+ require 'pony'
2
+
3
+ module Bobble
4
+ module Notifier
5
+ class Gmail
6
+ class << self
7
+
8
+ def send(message, url)
9
+ Pony.mail({
10
+ :to => ENV["BOBBLE_GMAIL_TO_EMAIL"],
11
+ :via => :smtp,
12
+ :via_options => {
13
+ :address => 'smtp.gmail.com',
14
+ :port => '587',
15
+ :enable_starttls_auto => true,
16
+ :user_name => ENV["BOBBLE_GMAIL_USERNAME"],
17
+ :password => ENV["BOBBLE_GMAIL_PASSWORD"],
18
+ :authentication => :plain, # :plain, :login, :cram_md5, no auth by default
19
+ :domain => "localhost.localdomain" # the HELO domain provided by the client to the server
20
+ },
21
+ :body => message,
22
+ :subject => "Bobble: #{url} is down"
23
+ })
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,85 @@
1
+ require 'bobble/util'
2
+
3
+ #
4
+ # Google Voice Notifier
5
+ # Adapted from: http://brettterpstra.com/sms-from-the-command-line-with-google-voice/
6
+ #
7
+ module Bobble
8
+ module Notifier
9
+ class GoogleVoice
10
+ class << self
11
+
12
+ def postit(uri_str, data, header = nil, limit = 3)
13
+ raise ArgumentError, 'HTTP redirect too deep' if limit == 0
14
+ url = URI.parse(uri_str)
15
+ http = Net::HTTP.new(url.host,443)
16
+ http.use_ssl = true
17
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
18
+ response,content = http.post(url.path,data,header)
19
+ case response
20
+ when Net::HTTPSuccess then content
21
+ when Net::HTTPRedirection then postit(response['location'],data,header, limit - 1)
22
+ else
23
+ puts response.inspect
24
+ response.error!
25
+ end
26
+ end
27
+
28
+ def getit(uri_str, header, limit = 3)
29
+ raise ArgumentError, 'HTTP redirect too deep' if limit == 0
30
+ url = URI.parse(uri_str)
31
+ http = Net::HTTP.new(url.host,url.port)
32
+ http.use_ssl = true
33
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
34
+ response,content = http.get(url.path,header)
35
+ case response
36
+ when Net::HTTPSuccess then content
37
+ when Net::HTTPRedirection then getit(response['location'],header, limit - 1)
38
+ else
39
+ response.error!
40
+ end
41
+ end
42
+
43
+ def send(message)
44
+ message = Bobble::Util.shorten_to_text_message(message)
45
+
46
+ username = ENV["BOBBLE_GVOICE_USERNAME"]
47
+ password = ENV["BOBBLE_GVOICE_PASSWORD"]
48
+ # TODO: support multiple numbers
49
+ number = ENV["BOBBLE_GVOICE_TO_PHONENUMBER"]
50
+ numbers = [number]
51
+
52
+ data = "accountType=GOOGLE&Email=#{username}&Passwd=#{password}&service=grandcentral&source=brettterpstra-CLISMS-2.0"
53
+ res = postit('https://www.google.com/accounts/ClientLogin',data)
54
+
55
+ if res
56
+ authcode = res.match(/Auth=(.+)/)[1]
57
+ header = {'Authorization' => "GoogleLogin auth=#{authcode.strip}",'Content-Length' => '0'}
58
+ newres = getit('https://www.google.com/voice',header)
59
+
60
+ if newres
61
+ rnrse = newres.match(/'_rnr_se': '([^']+)'/)[1]
62
+ numbers.each do |num|
63
+ data = "_rnr_se=#{rnrse}&phoneNumber=#{num.strip}&text=#{message}&id="
64
+ finalres = postit('https://www.google.com/voice/sms/send/',data,header)
65
+
66
+ if finalres["ok"]
67
+ puts "Message sent to #{num}"
68
+ else
69
+ puts "Error sending to #{num}"
70
+ end
71
+ end
72
+
73
+ else
74
+ newres.error!
75
+ end
76
+
77
+ else
78
+ res.error!
79
+ end
80
+ end
81
+
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,35 @@
1
+ require 'twilio-ruby'
2
+ require 'bobble/util'
3
+
4
+ module Bobble
5
+ module Notifier
6
+ class Twilio
7
+ class << self
8
+
9
+ @@client = nil
10
+
11
+ def create_client
12
+ return if @@client
13
+
14
+ account_sid = ENV['BOBBLE_TWILIO_SID']
15
+ auth_token = ENV['BOBBLE_TWILIO_TOKEN']
16
+
17
+ @@client = Twilio::REST::Client.new account_sid, auth_token
18
+ end
19
+
20
+ def send(message)
21
+ create_client
22
+ message = Bobble::Util.shorten_to_text_message(message)
23
+
24
+ params = {
25
+ :from => ENV['BOBBLE_TWILIO_FROM_PHONENUMBER'],
26
+ :to => ENV['BOBBLE_TWILIO_TO_PHONENUMBER'],
27
+ :body => message
28
+ }
29
+ @@client.account.sms.messages.create(params)
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+ end
data/lib/bobble/util.rb CHANGED
@@ -1,13 +1,15 @@
1
- class Bobble::Util
2
- class << self
1
+ module Bobble
2
+ class Util
3
+ class << self
3
4
 
4
- def shorten_to_text_message(message)
5
- text_message = message
6
- if message.length > 140
7
- text_message = message[0..136] + "..."
5
+ def shorten_to_text_message(message)
6
+ text_message = message
7
+ if message.length > 140
8
+ text_message = message[0..136] + "..."
9
+ end
10
+ return message
8
11
  end
9
- return message
10
- end
11
12
 
13
+ end
12
14
  end
13
15
  end
data/lib/bobble.rb CHANGED
@@ -1,4 +1,6 @@
1
- class Bobble
1
+ require 'bobble/checker'
2
+
3
+ module Bobble
2
4
  class << self
3
5
 
4
6
  # default options are guessed based on what environment variables are present
@@ -8,56 +10,15 @@ class Bobble
8
10
  :gmail => !!ENV["BOBBLE_GMAIL_USERNAME"]
9
11
  }
10
12
 
11
- def options(o)
12
- @@options.update(o)
13
+ def option(key)
14
+ @@options[key]
13
15
  end
14
16
 
15
- def check(url)
16
- begin
17
- response = Net::HTTP.get(URI.parse(url))
18
- raise Exception.new("empty response") if response == ""
19
- puts "Successful!: #{url}"
20
- rescue Exception => e
21
- message = "FAILED: #{url} - #{e.message}"
22
- puts message
23
-
24
- send_notification(message, url)
25
- end
26
- end
27
-
28
- def send_notification(message, url)
29
-
30
- if @@options[:gmail]
31
- begin
32
- GmailNotifier.send(message, url)
33
- rescue Exception => e
34
- puts "Gmail Notifier failed: #{e.message}"
35
- end
36
- end
37
-
38
- if @@options[:twilio]
39
- begin
40
- TwilioNotifier.send(message)
41
- rescue Exception => e
42
- puts "Twilio Notifier failed: #{e.message}"
43
- end
44
- end
45
-
46
- if @@options[:google_voice]
47
- begin
48
- GoogleVoiceNotifier.send(message)
49
- rescue Exception => e
50
- puts "Google Voice Notifier failed: #{e.message}"
51
- end
52
- end
53
-
17
+ def check(url, options={})
18
+ Bobble::Checker.check(url, options)
54
19
  end
55
20
 
56
21
  end
57
22
  end
58
23
 
59
- require 'bobble/twilio_notifier'
60
- require 'bobble/google_voice_notifier'
61
- require 'bobble/gmail_notifier'
62
-
63
24
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bobble
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-24 00:00:00.000000000Z
12
+ date: 2012-07-06 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: twilio-ruby
16
- requirement: &70329909850180 !ruby/object:Gem::Requirement
16
+ requirement: &70256347466300 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 3.6.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70329909850180
24
+ version_requirements: *70256347466300
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: pony
27
- requirement: &70329909849480 !ruby/object:Gem::Requirement
27
+ requirement: &70256347465820 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,19 +32,20 @@ dependencies:
32
32
  version: '1.4'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70329909849480
36
- description: For freely pinging your favorite web services & freely or cheaply getting
37
- email/SMS notifications when they're down.
35
+ version_requirements: *70256347465820
36
+ description: For pinging your web services (any URL) & freely or cheaply getting email/SMS
37
+ notifications when they're down.
38
38
  email: ahfarmer@gmail.com
39
39
  executables: []
40
40
  extensions: []
41
41
  extra_rdoc_files: []
42
42
  files:
43
43
  - lib/bobble.rb
44
- - lib/bobble/gmail_notifier.rb
45
- - lib/bobble/google_voice_notifier.rb
46
- - lib/bobble/twilio_notifier.rb
44
+ - lib/bobble/checker.rb
47
45
  - lib/bobble/util.rb
46
+ - lib/bobble/notifier/gmail.rb
47
+ - lib/bobble/notifier/google_voice.rb
48
+ - lib/bobble/notifier/twilio.rb
48
49
  homepage: https://github.com/ahfarmer/bobble
49
50
  licenses: []
50
51
  post_install_message:
@@ -1,25 +0,0 @@
1
- require 'pony'
2
-
3
- class Bobble::GmailNotifier
4
- class << self
5
-
6
- def send(message, url)
7
- Pony.mail({
8
- :to => ENV["BOBBLE_GMAIL_TO_EMAIL"],
9
- :via => :smtp,
10
- :via_options => {
11
- :address => 'smtp.gmail.com',
12
- :port => '587',
13
- :enable_starttls_auto => true,
14
- :user_name => ENV["BOBBLE_GMAIL_USERNAME"],
15
- :password => ENV["BOBBLE_GMAIL_PASSWORD"],
16
- :authentication => :plain, # :plain, :login, :cram_md5, no auth by default
17
- :domain => "localhost.localdomain" # the HELO domain provided by the client to the server
18
- },
19
- :body => message,
20
- :subject => "Bobble: #{url} is down"
21
- })
22
- end
23
-
24
- end
25
- end
@@ -1,81 +0,0 @@
1
- require 'bobble/util'
2
-
3
- #
4
- # Google Voice Notifier
5
- # Adapted from: http://brettterpstra.com/sms-from-the-command-line-with-google-voice/
6
- #
7
- class Bobble::GoogleVoiceNotifier
8
- class << self
9
-
10
- def postit(uri_str, data, header = nil, limit = 3)
11
- raise ArgumentError, 'HTTP redirect too deep' if limit == 0
12
- url = URI.parse(uri_str)
13
- http = Net::HTTP.new(url.host,443)
14
- http.use_ssl = true
15
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
16
- response,content = http.post(url.path,data,header)
17
- case response
18
- when Net::HTTPSuccess then content
19
- when Net::HTTPRedirection then postit(response['location'],data,header, limit - 1)
20
- else
21
- puts response.inspect
22
- response.error!
23
- end
24
- end
25
-
26
- def getit(uri_str, header, limit = 3)
27
- raise ArgumentError, 'HTTP redirect too deep' if limit == 0
28
- url = URI.parse(uri_str)
29
- http = Net::HTTP.new(url.host,url.port)
30
- http.use_ssl = true
31
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
32
- response,content = http.get(url.path,header)
33
- case response
34
- when Net::HTTPSuccess then content
35
- when Net::HTTPRedirection then getit(response['location'],header, limit - 1)
36
- else
37
- response.error!
38
- end
39
- end
40
-
41
- def send(message)
42
- message = Bobble::Util.shorten_to_text_message(message)
43
-
44
- username = ENV["BOBBLE_GVOICE_USERNAME"]
45
- password = ENV["BOBBLE_GVOICE_PASSWORD"]
46
- # TODO: support multiple numbers
47
- number = ENV["BOBBLE_GVOICE_TO_PHONENUMBER"]
48
- numbers = [number]
49
-
50
- data = "accountType=GOOGLE&Email=#{username}&Passwd=#{password}&service=grandcentral&source=brettterpstra-CLISMS-2.0"
51
- res = postit('https://www.google.com/accounts/ClientLogin',data)
52
-
53
- if res
54
- authcode = res.match(/Auth=(.+)/)[1]
55
- header = {'Authorization' => "GoogleLogin auth=#{authcode.strip}",'Content-Length' => '0'}
56
- newres = getit('https://www.google.com/voice',header)
57
-
58
- if newres
59
- rnrse = newres.match(/'_rnr_se': '([^']+)'/)[1]
60
- numbers.each do |num|
61
- data = "_rnr_se=#{rnrse}&phoneNumber=#{num.strip}&text=#{message}&id="
62
- finalres = postit('https://www.google.com/voice/sms/send/',data,header)
63
-
64
- if finalres["ok"]
65
- puts "Message sent to #{num}"
66
- else
67
- puts "Error sending to #{num}"
68
- end
69
- end
70
-
71
- else
72
- newres.error!
73
- end
74
-
75
- else
76
- res.error!
77
- end
78
- end
79
-
80
- end
81
- end
@@ -1,31 +0,0 @@
1
- require 'twilio-ruby'
2
- require 'bobble/util'
3
-
4
- class Bobble::TwilioNotifier
5
- class << self
6
-
7
- @@client = nil
8
-
9
- def create_client
10
- return if @@client
11
-
12
- account_sid = ENV['BOBBLE_TWILIO_SID']
13
- auth_token = ENV['BOBBLE_TWILIO_TOKEN']
14
-
15
- @@client = Twilio::REST::Client.new account_sid, auth_token
16
- end
17
-
18
- def send(message)
19
- create_client
20
- message = Bobble::Util.shorten_to_text_message(message)
21
-
22
- params = {
23
- :from => ENV['BOBBLE_TWILIO_FROM_PHONENUMBER'],
24
- :to => ENV['BOBBLE_TWILIO_TO_PHONENUMBER'],
25
- :body => message
26
- }
27
- @@client.account.sms.messages.create(params)
28
- end
29
-
30
- end
31
- end