absentee_camper 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ Gemfile.lock
2
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in absentee_camper.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ #Absentee Camper
2
+
3
+ This gem will monitor a Campfire room for @mentions, and notify the
4
+ mentioned users via email if they aren't in the room. Multiple users
5
+ can be mentioned in one Campfire message, and each user will receive one
6
+ notification email. The email message will contain the message that was
7
+ triggered by the @mention.
8
+
9
+ ## Usage
10
+
11
+ 1. `gem install absentee_camper`
12
+ 2. `ABSENTEE_CAMPER_CONFIG=/path/to/config absentee_camper`
13
+
14
+ ## Monitoring User
15
+
16
+ It is recommended to create a user for the sole purpose of monitoring
17
+ the Campfire room (e.g. Campfire Bot), and use that user's API token when running
18
+ Absentee Camper. The reason is that if you don't, and instead use the
19
+ API token of a "real" user, that user will never be able to leave the
20
+ Campfire room because Absentee Camper will be running under that user.
21
+ This means that any mentions of that user won't trigger an email since
22
+ they will always be present in the room.
23
+
24
+ ## Configuration
25
+
26
+ Here is a sample config file:
27
+
28
+ ---
29
+ room_id: 12345
30
+ token: 'your-token'
31
+ campfire_subdomain: 'your-subdomain'
32
+ replyto_email_domain: 'your-replyto-domain'
33
+ users:
34
+ john: 12345
35
+ steve: 678910
36
+
37
+ * `room_id` - The ID of the room you wish to monitor. This can be found
38
+ in the URL for the room.
39
+ * `token` - The API token for the monitoring user.
40
+ * `campfire_subdomain` - This can be found in the Campfire URL (e.g. _subdomain_.campfirenow.com)
41
+ * `replyto_email_domain` - The subdomain you would like to appear in the
42
+ email _from_ address.
43
+ * `users` - Each user line consists of the name of the mention name and
44
+ that user's corresponding 37Signals Campfire user ID. One way to get
45
+ this user ID is to log into Campfire as a user that has admin privileges,
46
+ click on the _Users_ tab, and then hover over the _change_ link of the
47
+ user for which you want to find the user ID and take note of the number
48
+ in the path (e.g. https://_your-company_.campfirenow.com/member/12345/permissions).
49
+ For example, if you have a user named John Smith with a
50
+ user ID of 12345, and you want to be able to mention them as _@john_,
51
+ the users line in the config file would be `john: 12345`.
52
+
53
+ ## TODO
54
+
55
+ * Specs!
56
+ * Provide context in the notification. For example, in a Campfire
57
+ session there are two users: John and Steve. Another user, Chad
58
+ is not present in the room:
59
+
60
+ John Smith: Hey Steve. I am having a problem with the build.
61
+ Steve Stallion: Hey John. I don't know anything about that. You
62
+ should ask @chad. That's his department.
63
+ John Smith: Oh, I thought you were the one that handled that. OK,
64
+ I will wait for Chad's response.
65
+
66
+ Currently, the email notification that Absentee Camper sends out will
67
+ only contain the second message, which doesn't have any context about
68
+ what was being discussed. It would be nice to set some configuration
69
+ variables that indicated you wanted to include context in the
70
+ notification message, and how many lines on either side to include.
71
+
72
+ * Provide a means other than email, such as text messaging, to notify
73
+ the users.
74
+
75
+ ## Contributing
76
+
77
+ Do the usual fork -> change -> pull request dance.
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "absentee_camper/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "absentee_camper"
7
+ s.version = AbsenteeCamper::VERSION
8
+ s.authors = ["Chad Boyd", "David Reese"]
9
+ s.email = ["hoverlover@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Monitors a Campfire room for @mentions, and emails the @mentioned user with the message if they aren't in the room.}
12
+ s.description = s.summary
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_dependency('settingslogic', '~> 2.0')
20
+ s.add_dependency('yajl-ruby', '~> 0.8')
21
+ s.add_dependency('httparty', '~> 0.7')
22
+ s.add_dependency('pony', '~> 1.3')
23
+
24
+ s.add_development_dependency('rspec', '~> 2.6.0')
25
+ end
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'absentee_camper'
4
+
5
+ AbsenteeCamper::Monitor.new.start
@@ -0,0 +1,24 @@
1
+ module AbsenteeCamper
2
+ module Campfire
3
+ module API
4
+ extend self
5
+ include HTTParty
6
+
7
+ base_uri "https://#{Config.campfire_subdomain}.campfirenow.com"
8
+ basic_auth Config.token, 'x'
9
+ headers 'Content-Type' => 'application/json'
10
+
11
+ def rooms
12
+ get('/rooms.json')["rooms"]
13
+ end
14
+
15
+ def room(room_id)
16
+ Room.new(room_id)
17
+ end
18
+
19
+ def user(id)
20
+ get("/users/#{id}.json")["user"]
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,65 @@
1
+ module AbsenteeCamper
2
+ module Campfire
3
+ class Room
4
+ attr_reader :room_id
5
+
6
+ def initialize(room_id)
7
+ @room_id = room_id
8
+ end
9
+
10
+ def join
11
+ post 'join'
12
+ end
13
+
14
+ def leave
15
+ post 'leave'
16
+ end
17
+
18
+ def lock
19
+ post 'lock'
20
+ end
21
+
22
+ def unlock
23
+ post 'unlock'
24
+ end
25
+
26
+ def message(message)
27
+ send_message message
28
+ end
29
+
30
+ def paste(paste)
31
+ send_message paste, 'PasteMessage'
32
+ end
33
+
34
+ def play_sound(sound)
35
+ send_message sound, 'SoundMessage'
36
+ end
37
+
38
+ def transcript
39
+ get('transcript')['messages']
40
+ end
41
+
42
+ def info
43
+ API.get "/room/#{room_id}.json"
44
+ end
45
+
46
+ private
47
+
48
+ def send_message(message, type = 'Textmessage')
49
+ post 'speak', :body => {:message => {:body => message, :type => type}}.to_json
50
+ end
51
+
52
+ def get(action, options = {})
53
+ API.get room_url_for(action), options
54
+ end
55
+
56
+ def post(action, options = {})
57
+ API.post room_url_for(action), options
58
+ end
59
+
60
+ def room_url_for(action)
61
+ "/room/#{room_id}/#{action}.json"
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,27 @@
1
+ module AbsenteeCamper
2
+ class Config < ::Settingslogic
3
+ source ENV['ABSENTEE_CAMPER_CONFIG']
4
+
5
+ def inititalize
6
+ Pony.options = {
7
+ # Uncomment for use with Gmail
8
+ #
9
+ #:via => :smtp, :via_options => {
10
+ #:address => 'smtp.gmail.com',
11
+ #:port => '587',
12
+ #:enable_starttls_auto => true,
13
+ #:user_name => 'your username',
14
+ #:password => 'your password',
15
+ #:authentication => :plain, # :plain, :login, :cram_md5, no auth by default
16
+ #:domain => "localhost.localdomain" # the HELO domain provided by the client to the server
17
+ #},
18
+ :from => "campfire-#{room_id}@#{replyto_email_domain}",
19
+ :subject => '[Campfire] People are talking about you!'
20
+ }
21
+ end
22
+
23
+ def room_uri
24
+ "https://#{campfire_subdomain}.campfirenow.com/room/#{room_id}"
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,81 @@
1
+ module AbsenteeCamper
2
+ class Monitor
3
+ include Campfire
4
+
5
+ def initialize
6
+ @room = Room.new(Config.room_id)
7
+ @room.join
8
+ end
9
+
10
+ def users_in_room(room)
11
+ response = room.info
12
+ raise "Error while retrieving room info: #{response.message}" if response.code != 200
13
+
14
+ room = JSON.parse(response.body)
15
+ room['room']['users']
16
+ end
17
+
18
+ def user_info(user_id)
19
+ response = API.get("/users/#{user_id}.json")
20
+
21
+ if response.code != 200
22
+ user_name = Config.users.detect { |kv| kv[1] == user_id }[0]
23
+ raise "Error while retrieving user info for #{user_name}: #{response.message}"
24
+ end
25
+
26
+ user = JSON.parse(response.body)
27
+ user['user']
28
+ end
29
+
30
+ def email_body(message)
31
+ body = <<-BODY
32
+ Come back to the campfire! We're having a good time telling ghost stories! Here's one you missed:
33
+
34
+ #{message}
35
+
36
+ #{Config.room_uri}
37
+ BODY
38
+ end
39
+
40
+ def log(message)
41
+ puts message
42
+ end
43
+
44
+ def start
45
+ log "monitoring room #{Config.room_id} at #{API.base_uri} ..."
46
+
47
+ url = URI.parse("http://#{Config.token}:x@streaming.campfirenow.com/room/#{Config.room_id}/live.json")
48
+
49
+ begin
50
+ Yajl::HttpStream.get(url) do |message|
51
+ if message['type'] == 'TextMessage'
52
+ body = message['body']
53
+ log body
54
+
55
+ body.scan(/@\w+/).each do |mention|
56
+ mentioned = mention[1..-1]
57
+ if Config.users.keys.include? mentioned
58
+ user_id = Config.users[mentioned]
59
+
60
+ begin
61
+ # If the user isn't in the room, fire off an email to them
62
+ unless users_in_room(@room).map { |u| u['id'] }.include? user_id
63
+ email_address = user_info(user_id)['email_address']
64
+ @room.message("[Sent an email to #{mentioned}.]")
65
+ log "sending email to #{mentioned} at #{email_address}"
66
+
67
+ Pony.mail :to => email_address, :body => email_body(body)
68
+ end
69
+ rescue
70
+ log $!
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ rescue Yajl::HttpStream::HttpError => e
77
+ log "Error connecting to campfire: #{e.message}"
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,3 @@
1
+ module AbsenteeCamper
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,19 @@
1
+ require "rubygems"
2
+ require "uri"
3
+ require "yajl/http_stream"
4
+ require 'httparty'
5
+ require 'json'
6
+ require 'pony'
7
+ require 'settingslogic'
8
+
9
+ module AbsenteeCamper
10
+ autoload :Config, 'absentee_camper/config'
11
+ autoload :Monitor, 'absentee_camper/monitor'
12
+ autoload :API, 'absentee_camper/campfire/api'
13
+ autoload :Room, 'absentee_camper/campfire/room'
14
+
15
+ module Campfire
16
+ autoload :API, 'absentee_camper/campfire/api'
17
+ autoload :Room, 'absentee_camper/campfire/room'
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: absentee_camper
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Chad Boyd
13
+ - David Reese
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-08-22 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: settingslogic
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 2
30
+ - 0
31
+ version: "2.0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: yajl-ruby
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ - 8
44
+ version: "0.8"
45
+ type: :runtime
46
+ version_requirements: *id002
47
+ - !ruby/object:Gem::Dependency
48
+ name: httparty
49
+ prerelease: false
50
+ requirement: &id003 !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ - 7
57
+ version: "0.7"
58
+ type: :runtime
59
+ version_requirements: *id003
60
+ - !ruby/object:Gem::Dependency
61
+ name: pony
62
+ prerelease: false
63
+ requirement: &id004 !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ~>
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 1
69
+ - 3
70
+ version: "1.3"
71
+ type: :runtime
72
+ version_requirements: *id004
73
+ - !ruby/object:Gem::Dependency
74
+ name: rspec
75
+ prerelease: false
76
+ requirement: &id005 !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ~>
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 2
82
+ - 6
83
+ - 0
84
+ version: 2.6.0
85
+ type: :development
86
+ version_requirements: *id005
87
+ description: Monitors a Campfire room for @mentions, and emails the @mentioned user with the message if they aren't in the room.
88
+ email:
89
+ - hoverlover@gmail.com
90
+ executables:
91
+ - absentee_camper
92
+ extensions: []
93
+
94
+ extra_rdoc_files: []
95
+
96
+ files:
97
+ - .gitignore
98
+ - Gemfile
99
+ - README.md
100
+ - absentee_camper.gemspec
101
+ - bin/absentee_camper
102
+ - lib/absentee_camper.rb
103
+ - lib/absentee_camper/campfire/api.rb
104
+ - lib/absentee_camper/campfire/room.rb
105
+ - lib/absentee_camper/config.rb
106
+ - lib/absentee_camper/monitor.rb
107
+ - lib/absentee_camper/version.rb
108
+ has_rdoc: true
109
+ homepage: ""
110
+ licenses: []
111
+
112
+ post_install_message:
113
+ rdoc_options: []
114
+
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ segments:
122
+ - 0
123
+ version: "0"
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ segments:
129
+ - 0
130
+ version: "0"
131
+ requirements: []
132
+
133
+ rubyforge_project:
134
+ rubygems_version: 1.3.6
135
+ signing_key:
136
+ specification_version: 3
137
+ summary: Monitors a Campfire room for @mentions, and emails the @mentioned user with the message if they aren't in the room.
138
+ test_files: []
139
+