scamp 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  A framework for writing [Campfire](http://campfirenow.com/) bots. Scamp is in early development so use it at your own risk, pull requests welcome.
4
4
 
5
+ Scamp is designed to be simple, to get out of your way and to let you do what you want. It doesn't have any baggage, so no administration web interfaces, no built in commands. It's a blank slate for you to build on.
6
+
7
+ If you like or use Scamp I'd love to hear from you. Drop me at line at will at 37signals dot com and tell me how you are using it.
8
+
5
9
  ## Requirements
6
10
 
7
11
  Ruby >= 1.9.2 (At least for the named captures)
@@ -28,10 +32,10 @@ Matchers are tested in order and all that satisfy the match and conditions will
28
32
  end
29
33
 
30
34
  #
31
- # A special user and channel method is available in match blocks.
35
+ # A special user and room method is available in match blocks.
32
36
  #
33
37
  match "a user said" do
34
- say "#{user} said something in channel #{channel}"
38
+ say "#{user} said something in room #{room}"
35
39
  end
36
40
 
37
41
  match "Hello!" do
@@ -39,35 +43,42 @@ Matchers are tested in order and all that satisfy the match and conditions will
39
43
  end
40
44
 
41
45
  #
42
- # Limit the match to certain channels, users or both.
46
+ # You can play awesome sounds
43
47
  #
44
- match /^Lets match (.+)$/, :conditions => {:channel => "Some Channel"} do
45
- say "Only said if channel name mathces /someregex/"
48
+ match "ohmy" do
49
+ play "yeah"
50
+ end
51
+
52
+ #
53
+ # Limit the match to certain rooms, users or both.
54
+ #
55
+ match /^Lets match (.+)$/, :conditions => {:room => "Some Room"} do
56
+ say "Only said if room name mathces /someregex/"
46
57
  end
47
58
 
48
59
  match "some text", :conditions => {:user => "Some User"} do
49
60
  say "Only said if user name mathces /someregex/"
50
61
  end
51
62
 
52
- match /some other text/, :conditions => {:user => "Some User", :channel => 123456} do
63
+ match /some other text/, :conditions => {:user => "Some User", :room => 123456} do
53
64
  say "You can mix conditions"
54
65
  end
55
66
 
56
67
  #
57
- # Named caputres become avaiable in your match block
68
+ # Named captures become avaiable in your match block
58
69
  #
59
70
  match /^say (?<yousaid>.+)$/ do
60
71
  say "You said #{yousaid}"
61
72
  end
62
73
 
63
74
  #
64
- # You can say multiple times, and you can specify an alternate channel.
65
- # Default behaviour is to 'say' in the channel that caused the match.
75
+ # You can say multiple times, and you can specify an alternate room.
76
+ # Default behaviour is to 'say' in the room that caused the match.
66
77
  #
67
78
  match "something" do
68
- say "#{user} said something in channel #{channel}"
69
- say "#{user} said something in channel #{channel}", 237872
70
- say "#{user} said something in channel #{channel}", "System Administration"
79
+ say "#{user} said something in room #{room}"
80
+ say "#{user} said something in room #{room}", 237872
81
+ say "#{user} said something in room #{room}", "System Administration"
71
82
  end
72
83
 
73
84
  #
@@ -86,34 +97,36 @@ Matchers are tested in order and all that satisfy the match and conditions will
86
97
  end
87
98
  end
88
99
 
89
- # Connect and join some channels
100
+ # Connect and join some rooms
90
101
  scamp.connect!([293788, "Monitoring"])
91
102
 
92
- In the channel/user conditions you can use the name, regex or ID of a user or channel, in say you can ise a string or ID, eg:
103
+ In the room/user conditions you can use the name, regex or ID of a user or room, in say you can ise a string or ID, eg:
93
104
 
94
- :conditions => {:channel => /someregex/}
95
- :conditions => {:channel => "some string"}
96
- :conditions => {:channel => 123456}
105
+ :conditions => {:room => /someregex/}
106
+ :conditions => {:room => "some string"}
107
+ :conditions => {:room => 123456}
97
108
 
98
109
  :conditions => {:user => /someregex/}
99
110
  :conditions => {:user => "some string"}
100
111
  :conditions => {:user => 123456}
101
112
 
102
- say "#{user} said something in channel #{channel}", 237872
103
- say "#{user} said something in channel #{channel}", "System Administration"
113
+ say "#{user} said something in room #{room}", 237872
114
+ say "#{user} said something in room #{room}", "System Administration"
104
115
 
105
- ## TODO
116
+ By default Scamp listens to itself. This could either be fun, or dangerous, you decide. You can turn this off by passing :first\_match\_only => true in the initialisation options
106
117
 
107
- * Write more tests
108
- * Allow multiple values for conditions, eg: :conditions => {:channel => [/someregex/, "Some channel"]}
109
- * Add paste/play support
110
- * Add option to stop bot responding to itself
118
+ scamp = Scamp.new(:api_key => "YOUR API KEY", :subdomain => "yoursubdomain", :first_match_only => true)
111
119
 
112
- ## Known issues
120
+ Scamp will listen to all messages that are sent on the rooms it is listening on and doesn't need to be addressed by name. If you prefer to only trigger bot commands when you address your bot directly add the :required\_prefix initialisation option:
113
121
 
114
- * Bot doesn't detect that it's been kicked out of a channel and reconnect
115
- * Bot tends to crash when it encounters an error.
116
- * When encountering a problem straming (Couldn't stream channel 401839 at url https://streaming.campfirenow.com/room/<channel_id>/live.json) no attempt is made to re-connect
122
+ scamp = Scamp.new(:api_key => "YOUR API KEY", :subdomain => "yoursubdomain", :required_prefix => 'Bot: ')
123
+
124
+ Scamp will now require commands to begin with 'Bot: ' (or whatever you have specified), and will strip out this prefix before handing the message onto your match block.
125
+
126
+ ## TODO
127
+
128
+ * Allow multiple values for conditions, eg: :conditions => {:room => ["This room", "Some room"]}
129
+ * Add paste support
117
130
 
118
131
  ## How to contribute
119
132
 
@@ -130,6 +143,13 @@ Here's the most direct way to get your work merged into the project:
130
143
 
131
144
  Take a look at the TODO list or known issues for some inspiration if you need it.
132
145
 
146
+ ## Thanks
147
+
148
+ First class support, commits and pull requests, thanks guys!
149
+
150
+ * [Caius Durling](http://caius.name/)
151
+ * Sudara Williams of [Ramen Music](http://ramenmusic.com)
152
+
133
153
  ## License
134
154
 
135
155
  Copyright (C) 2011 by Will Jessop
data/examples/bot.rb CHANGED
@@ -7,15 +7,15 @@ require 'scamp'
7
7
  scamp = Scamp.new(:api_key => "YOUR API KEY", :subdomain => "37s")
8
8
 
9
9
  scamp.behaviour do
10
- # Match some regex limited to a channel condition based on a channel id
11
- match /^channel id (.+)$/, :conditions => {:channel => 401839} do
12
- # Reply in the current channel
13
- say "Match some regex limited to a channel condition based on a channel id"
10
+ # Match some regex limited to a room condition based on a room id
11
+ match /^room id (.+)$/, :conditions => {:room => 401839} do
12
+ # Reply in the current room
13
+ say "Match some regex limited to a room condition based on a room id"
14
14
  end
15
15
 
16
- # Limit a match to a channel condition based on a string
17
- match "channel name check", :conditions => {:channel => "Monitoring"} do
18
- say "Limit a match to a channel condition based on a string"
16
+ # Limit a match to a room condition based on a string
17
+ match "room name check", :conditions => {:room => "Monitoring"} do
18
+ say "Limit a match to a room condition based on a string"
19
19
  end
20
20
 
21
21
  # Limit a match to a user condition based on a string
@@ -28,10 +28,10 @@ scamp.behaviour do
28
28
  say "Limit a match to a user condition based on an ID"
29
29
  end
30
30
 
31
- # Limit a match to a channel & user condition combined
32
- match /^something (.+)$/, :conditions => {:channel => "Monitoring", :user => "Will Jessop"} do
33
- # Reply in the current channel
34
- say "Limit a match to a channel & user condition combined"
31
+ # Limit a match to a room & user condition combined
32
+ match /^something (.+)$/, :conditions => {:room => "Monitoring", :user => "Will Jessop"} do
33
+ # Reply in the current room
34
+ say "Limit a match to a room & user condition combined"
35
35
  end
36
36
 
37
37
  # Match text with a regex, access the captures from the match object
@@ -44,23 +44,29 @@ scamp.behaviour do
44
44
  say "You said #{yousaid}"
45
45
  end
46
46
 
47
- # Simple string match, interpolating the channel and user in response.
47
+ # Simple string match, interpolating the room and user in response.
48
48
  match "something" do |data|
49
- # Send the response to a different channel
50
- say "#{user} said something in channel #{channel}", "Robot Army"
49
+ # Send the response to a different room
50
+ say "#{user} said something in room #{room}", "Robot Army"
51
51
 
52
- # Send the response to a different channel, using the channel ID
53
- say "#{user} said something in channel #{channel}", 293788
52
+ # Send the response to a different room, using the room ID
53
+ say "#{user} said something in room #{room}", 293788
54
54
 
55
- # Send the response to the originating channel
56
- say "#{user} said something in channel #{channel}"
55
+ # Send the response to the originating room
56
+ say "#{user} said something in room #{room}"
57
57
  end
58
58
 
59
- match "multi-condition match", :conditions => {:channel => [401839, "Monitoring"], :nick => ["Will Jessop", "Noah Lorang"]} do
60
- # Reply in the current channel
59
+ # Play some sounds
60
+ match "ohmy" do
61
+ play "yeah"
62
+ play "drama"
63
+ end
64
+
65
+ match "multi-condition match", :conditions => {:room => [401839, "Monitoring"], :user => ["Will Jessop", "Noah Lorang"]} do
66
+ # Reply in the current room
61
67
  say "multi-condition match"
62
68
  end
63
69
  end
64
70
 
65
- # FIXME: this does if the channel doesn't exist. Need a better error.
71
+ # FIXME: this does if the room doesn't exist. Need a better error.
66
72
  scamp.connect!([293788, "Monitoring"])
data/lib/scamp/action.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Actions are run in the context of a Scamp::Action.
3
- # This allows us to make channel, nick etc. methods
3
+ # This allows us to make room, user etc. methods
4
4
  # available on a per-message basis
5
5
  #
6
6
 
@@ -27,8 +27,12 @@ class Scamp
27
27
  end if match.respond_to?(:names) # 1.8 doesn't support named captures
28
28
  end
29
29
 
30
- def channel
31
- bot.channel_name_for @message[:room_id]
30
+ def room_id
31
+ @message[:room_id]
32
+ end
33
+
34
+ def room
35
+ bot.room_name_for @message[:room_id]
32
36
  end
33
37
 
34
38
  def user
@@ -53,8 +57,12 @@ class Scamp
53
57
  bot.command_list
54
58
  end
55
59
 
56
- def say(msg, channel_id_or_name = channel)
57
- bot.say(msg, channel_id_or_name)
60
+ def say(msg, room_id_or_name = room_id)
61
+ bot.say(msg, room_id_or_name)
62
+ end
63
+
64
+ def play(sound, room_id_or_name = room_id)
65
+ bot.play(sound, room_id_or_name)
58
66
  end
59
67
  end
60
68
  end
@@ -2,19 +2,19 @@ class Scamp
2
2
  module Connection
3
3
  private
4
4
 
5
- def connect(api_key, channel_list)
5
+ def connect(api_key, room_list)
6
6
  EventMachine.run do
7
7
 
8
- # Check for channels to join, and join them
8
+ # Check for rooms to join, and join them
9
9
  EventMachine::add_periodic_timer(5) do
10
- while id = @channels_to_join.pop
10
+ while id = @rooms_to_join.pop
11
11
  join_and_stream(id)
12
12
  end
13
13
  end
14
14
 
15
- populate_channel_list do
16
- logger.debug "Adding #{channel_list.join ', '} to list of channels to join"
17
- @channels_to_join = channel_list.map{|c| channel_id(c) }
15
+ populate_room_list do
16
+ logger.debug "Adding #{room_list.join ', '} to list of rooms to join"
17
+ @rooms_to_join = room_list.map{|c| room_id(c) }
18
18
  end
19
19
 
20
20
  end
data/lib/scamp/matcher.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  class Scamp
2
2
  class Matcher
3
- attr_accessor :conditions, :trigger, :action, :bot
3
+ attr_accessor :conditions, :trigger, :action, :bot, :required_prefix
4
4
 
5
5
  def initialize(bot, params = {})
6
6
  params ||= {}
@@ -26,6 +26,10 @@ class Scamp
26
26
  private
27
27
 
28
28
  def triggered_by(message_text)
29
+ if message_text && required_prefix
30
+ message_text = handle_prefix(message_text)
31
+ return false unless message_text
32
+ end
29
33
  if trigger.is_a? String
30
34
  return true if trigger == message_text
31
35
  elsif trigger.is_a? Regexp
@@ -36,6 +40,25 @@ class Scamp
36
40
  false
37
41
  end
38
42
 
43
+ def handle_prefix(message_text)
44
+ return false unless message_text
45
+ if required_prefix.is_a? String
46
+ if required_prefix == message_text[0...required_prefix.length]
47
+ message_text.gsub(required_prefix,'')
48
+ else
49
+ false
50
+ end
51
+ elsif required_prefix.is_a? Regexp
52
+ if required_prefix.match message_text
53
+ message_text.gsub(required_prefix,'')
54
+ else
55
+ false
56
+ end
57
+ else
58
+ false
59
+ end
60
+ end
61
+
39
62
  def run(msg, match = nil)
40
63
  action_run = Action.new(bot, action, msg)
41
64
  action_run.matches = match if match
@@ -45,18 +68,18 @@ class Scamp
45
68
  def conditions_satisfied_by(msg)
46
69
  bot.logger.debug "Checking message against #{conditions.inspect}"
47
70
 
48
- # item will be :nick or :channel
71
+ # item will be :user or :room
49
72
  # cond is the int or string value.
50
73
  conditions.each do |item, cond|
51
74
  bot.logger.debug "Checking #{item} against #{cond}"
52
75
  bot.logger.debug "msg is #{msg.inspect}"
53
76
  if cond.is_a? Integer
54
- # bot.logger.debug "item is #{msg[{:channel => :room_id, :user => :user_id}[item]]}"
55
- return false unless msg[{:channel => :room_id, :user => :user_id}[item]] == cond
77
+ # bot.logger.debug "item is #{msg[{:room => :room_id, :user => :user_id}[item]]}"
78
+ return false unless msg[{:room => :room_id, :user => :user_id}[item]] == cond
56
79
  elsif cond.is_a? String
57
80
  case item
58
- when :channel
59
- return false unless bot.channel_name_for(msg[:room_id]) == cond
81
+ when :room
82
+ return false unless bot.room_name_for(msg[:room_id]) == cond
60
83
  when :user
61
84
  return false unless bot.username_for(msg[:user_id]) == cond
62
85
  end
@@ -0,0 +1,31 @@
1
+ class Scamp
2
+ module Messages
3
+
4
+ def say(message, room_id_or_name)
5
+ send_message(room_id_or_name, message, "Textmessage")
6
+ end
7
+
8
+ def play(sound, room_id_or_name)
9
+ send_message(room_id_or_name, sound, "SoundMessage")
10
+ end
11
+
12
+ private
13
+
14
+ # curl -vvv -H 'Content-Type: application/json' -d '{"message":{"body":"Yeeeeeaaaaaahh", "type":"Textmessage"}}' -u API_KEY:X https://37s.campfirenow.com/room/293788/speak.json
15
+ def send_message(room_id_or_name, payload, type)
16
+ # post 'speak', :body => {:message => {:body => message, :type => type}}.to_json
17
+ room_id = room_id(room_id_or_name)
18
+ url = "https://#{subdomain}.campfirenow.com/room/#{room_id}/speak.json"
19
+ http = EventMachine::HttpRequest.new(url).post :head => {'Content-Type' => 'application/json', 'authorization' => [api_key, 'X']}, :body => Yajl::Encoder.encode({:message => {:body => payload, :type => type}})
20
+ http.errback { logger.error "Couldn't connect to #{url} to post message \"#{payload}\" to room #{room_id}" }
21
+ http.callback {
22
+ if http.response_header.status == 200
23
+ logger.debug "Posted message \"#{payload}\" to room #{room_id}"
24
+ else
25
+ logger.error "Couldn't post message \"#{payload}\" to room #{room_id} using url #{url}, http response from the API was #{http.response_header.status}"
26
+ end
27
+ }
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,113 @@
1
+ class Scamp
2
+ module Rooms
3
+ # TextMessage (regular chat message),
4
+ # PasteMessage (pre-formatted message, rendered in a fixed-width font),
5
+ # SoundMessage (plays a sound as determined by the message, which can be either “rimshot”, “crickets”, or “trombone”),
6
+ # TweetMessage (a Twitter status URL to be fetched and inserted into the chat)
7
+
8
+ def paste(text, room)
9
+ end
10
+
11
+ def upload
12
+ end
13
+
14
+ def join(room_id)
15
+ logger.info "Joining room #{room_id}"
16
+ url = "https://#{subdomain}.campfirenow.com/room/#{room_id}/join.json"
17
+ http = EventMachine::HttpRequest.new(url).post :head => {'Content-Type' => 'application/json', 'authorization' => [api_key, 'X']}
18
+
19
+ http.errback { logger.error "Error joining room: #{room_id}" }
20
+ http.callback {
21
+ yield if block_given?
22
+ }
23
+ end
24
+
25
+ def room_id(room_id_or_name)
26
+ if room_id_or_name.is_a? Integer
27
+ return room_id_or_name
28
+ else
29
+ return room_id_from_room_name(room_id_or_name)
30
+ end
31
+ end
32
+
33
+ def room_name_for(room_id)
34
+ data = room_cache_data(room_id)
35
+ return data["name"] if data
36
+ room_id.to_s
37
+ end
38
+
39
+ private
40
+
41
+ def room_cache_data(room_id)
42
+ return room_cache[room_id] if room_cache.has_key? room_id
43
+ fetch_room_data(room_id)
44
+ return false
45
+ end
46
+
47
+ def populate_room_list
48
+ url = "https://#{subdomain}.campfirenow.com/rooms.json"
49
+ http = EventMachine::HttpRequest.new(url).get :head => {'authorization' => [api_key, 'X']}
50
+ http.errback { logger.error "Couldn't connect to url #{url} to fetch room list" }
51
+ http.callback {
52
+ if http.response_header.status == 200
53
+ logger.debug "Fetched room list"
54
+ new_rooms = {}
55
+ Yajl::Parser.parse(http.response)['rooms'].each do |c|
56
+ new_rooms[c["name"]] = c
57
+ end
58
+ # No idea why using the "rooms" accessor here doesn't
59
+ # work but accessing the ivar directly does. There's
60
+ # Probably a bug.
61
+ @rooms = new_rooms # replace existing room list
62
+ yield if block_given?
63
+ else
64
+ logger.error "Couldn't fetch room list with url #{url}, http response from API was #{http.response_header.status}"
65
+ end
66
+ }
67
+ end
68
+
69
+ def fetch_room_data(room_id)
70
+ url = "https://#{subdomain}.campfirenow.com/room/#{room_id}.json"
71
+ http = EventMachine::HttpRequest.new(url).get :head => {'authorization' => [api_key, 'X']}
72
+ http.errback { logger.error "Couldn't connect to #{url} to fetch room data for room #{room_id}" }
73
+ http.callback {
74
+ if http.response_header.status == 200
75
+ logger.debug "Fetched room data for #{room_id}"
76
+ room = Yajl::Parser.parse(http.response)['room']
77
+ room_cache[room["id"]] = room
78
+
79
+ room['users'].each do |u|
80
+ update_user_cache_with(u["id"], u)
81
+ end
82
+ else
83
+ logger.error "Couldn't fetch room data for room #{room_id} with url #{url}, http response from API was #{http.response_header.status}"
84
+ end
85
+ }
86
+ end
87
+
88
+ def join_and_stream(id)
89
+ join(id) do
90
+ logger.info "Joined room #{id} successfully"
91
+ fetch_room_data(id)
92
+ stream(id)
93
+ end
94
+ end
95
+
96
+ def stream(room_id)
97
+ json_parser = Yajl::Parser.new :symbolize_keys => true
98
+ json_parser.on_parse_complete = method(:process_message)
99
+
100
+ url = "https://streaming.campfirenow.com/room/#{room_id}/live.json"
101
+ # Timeout per https://github.com/igrigorik/em-http-request/wiki/Redirects-and-Timeouts
102
+ http = EventMachine::HttpRequest.new(url, :connect_timeout => 20, :inactivity_timeout => 0).get :head => {'authorization' => [api_key, 'X']}
103
+ http.errback { logger.error "Couldn't stream room #{room_id} at url #{url}" }
104
+ http.callback { logger.info "Disconnected from #{url}"; rooms_to_join << room_id}
105
+ http.stream {|chunk| json_parser << chunk }
106
+ end
107
+
108
+ def room_id_from_room_name(room_name)
109
+ logger.debug "Looking for room id for #{room_name}"
110
+ rooms[room_name]["id"]
111
+ end
112
+ end
113
+ end
data/lib/scamp/users.rb CHANGED
@@ -1,16 +1,5 @@
1
1
  class Scamp
2
2
  module Users
3
-
4
- # <user>
5
- # <id type="integer">1</id>
6
- # <name>Jason Fried</name>
7
- # <email-address>jason@37signals.com</email-address>
8
- # <admin type="boolean">true</admin>
9
- # <created-at type="datetime">2009-11-20T16:41:39Z</created-at>
10
- # <type>Member</type>
11
- # <avatar-url>http://asset0.37img.com/global/.../avatar.png</avatar-url>
12
- # </user>
13
-
14
3
  # Return the user_id if we haven't got the real name and
15
4
  # kick off a user data fetch
16
5
  def username_for(user_id)
@@ -24,13 +13,16 @@ class Scamp
24
13
  def fetch_data_for(user_id)
25
14
  url = "https://#{subdomain}.campfirenow.com/users/#{user_id}.json"
26
15
  http = EventMachine::HttpRequest.new(url).get(:head => {'authorization' => [api_key, 'X'], "Content-Type" => "application/json"})
27
- logger.debug http.inspect
28
16
  http.callback do
29
- logger.debug "Got the data for #{user_id}"
30
- update_user_cache_with(user_id, Yajl::Parser.parse(http.response)['user'])
17
+ if http.response_header.status == 200
18
+ logger.debug "Got the data for #{user_id}"
19
+ update_user_cache_with(user_id, Yajl::Parser.parse(http.response)['user'])
20
+ else
21
+ logger.error "Couldn't fetch user data for user #{user_id} with url #{url}, http response from API was #{http.response_header.status}"
22
+ end
31
23
  end
32
24
  http.errback do
33
- logger.error "Couldn't fetch user data for #{user_id} with url #{url}\n#{http.response_header.status.inspect}\n#{http.response_header.inspect}\n#{http.response.inspect}"
25
+ logger.error "Couldn't connect to #{url} to fetch user data for user #{user_id}"
34
26
  end
35
27
  end
36
28
 
data/lib/scamp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Scamp
2
- VERSION = "0.0.4"
2
+ VERSION = "0.1.0"
3
3
  end
data/lib/scamp.rb CHANGED
@@ -5,17 +5,20 @@ require "logger"
5
5
 
6
6
  require "scamp/version"
7
7
  require 'scamp/connection'
8
- require 'scamp/channels'
8
+ require 'scamp/rooms'
9
9
  require 'scamp/users'
10
10
  require 'scamp/matcher'
11
11
  require 'scamp/action'
12
+ require 'scamp/messages'
12
13
 
13
14
  class Scamp
14
15
  include Connection
15
- include Channels
16
+ include Rooms
16
17
  include Users
18
+ include Messages
17
19
 
18
- attr_accessor :channels, :user_cache, :channel_cache, :matchers, :api_key, :subdomain, :logger, :verbose, :first_match_only, :channels_to_join
20
+ attr_accessor :rooms, :user_cache, :room_cache, :matchers, :api_key, :subdomain,
21
+ :logger, :verbose, :first_match_only, :required_prefix, :rooms_to_join
19
22
 
20
23
  def initialize(options = {})
21
24
  options ||= {}
@@ -31,10 +34,10 @@ class Scamp
31
34
  end
32
35
  end
33
36
 
34
- @channels_to_join = []
35
- @channels = {}
37
+ @rooms_to_join = []
38
+ @rooms = {}
36
39
  @user_cache = {}
37
- @channel_cache = {}
40
+ @room_cache = {}
38
41
  @matchers ||= []
39
42
  end
40
43
 
@@ -42,9 +45,9 @@ class Scamp
42
45
  instance_eval &block
43
46
  end
44
47
 
45
- def connect!(channel_list)
48
+ def connect!(room_list)
46
49
  logger.info "Starting up"
47
- connect(api_key, channel_list)
50
+ connect(api_key, room_list)
48
51
  end
49
52
 
50
53
  def command_list
@@ -73,7 +76,7 @@ class Scamp
73
76
 
74
77
  def match trigger, params={}, &block
75
78
  params ||= {}
76
- matchers << Matcher.new(self, {:trigger => trigger, :action => block, :conditions => params[:conditions]})
79
+ matchers << Matcher.new(self, {:trigger => trigger, :action => block, :conditions => params[:conditions], :required_prefix => required_prefix})
77
80
  end
78
81
 
79
82
  def process_message(msg)
data/scamp.gemspec CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
7
7
  s.version = Scamp::VERSION
8
8
  s.authors = ["Will Jessop"]
9
9
  s.email = ["will@willj.net"]
10
- s.homepage = ""
10
+ s.homepage = "https://github.com/wjessop/Scamp"
11
11
  s.summary = %q{Eventmachine based Campfire bot framework}
12
12
  s.description = %q{Eventmachine based Campfire bot framework}
13
13
 
@@ -22,4 +22,5 @@ Gem::Specification.new do |s|
22
22
 
23
23
  s.add_development_dependency "rspec", "~> 2.6.0"
24
24
  s.add_development_dependency "mocha", "~> 0.10.0"
25
+ s.add_development_dependency "webmock", "~> 1.7.6"
25
26
  end