Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

root/plugins/continuous_builder/lib/marshmallow.rb

Revision 5222, 3.5 kB (checked in by david, 2 years ago)

Added Campfire notification support [DHH]

Line 
1 #!/usr/local/bin/ruby
2 #
3 # Marshmallow, the campfire chatbot
4 #
5 # You need to know one the following:
6 #  (a) the secret public URL, or
7 #  (b) an account/password for your room and the room number.
8 #
9 # Usage:
10 #   to login with a password:
11 #
12 #   bot = Marshmallow.new( :domain => 'mydomain', :ssl => true )
13 #   bot.login :method => :login,
14 #     :username  => "yourbot@email.com",
15 #     :password => "passw0rd",
16 #     :room     => "11234"
17 #   bot.say("So many ponies in here! I want one!")
18 #
19 #  to use the public url:
20 #
21 #    Marshmallow.domain = 'mydomain'
22 #    bot = Marshmallow.new
23 #    bot.login( :url => 'aDxf3' )
24 #    bot.say "Ponies!!"
25 #    bot.paste "<script type='text/javascript'>\nalert('Ponies!')\n</script>"
26 #
27
28 class Marshmallow
29   require 'net/https'
30   require 'open-uri'
31   require 'cgi'
32   require 'yaml'
33  
34   def self.version
35     "0.2.5"
36   end
37
38   attr_accessor :domain
39
40   def self.say(to, what)
41     connect(to) { |bot| bot.say(what) }
42   end
43  
44   def self.paste(to, what)
45     connect(to) { |bot| bot.paste(what) }
46   end
47  
48   # https://david:stuff@37s.campfirenow.com/rooms/11234
49   def self.connect(to)
50     if to =~ %r{(http|https)://([^:]+):(.+)@([^.]+).campfirenow.com/rooms/(\d+)}
51       protocol, username, password, domain, room = $1, $2, $3, $4, $5
52     else
53       raise "#{to} didn't match format, try something like https://david:stuff@37s.campfirenow.com/rooms/11234"
54     end
55
56     bot = new(:domain => domain, :ssl => (protocol == "https"))
57     bot.login(:username => username, :password => password, :method => :login, :room => room)
58
59     yield bot
60   end
61
62   def initialize(options={})
63     @debug  = options[:debug]
64     @domain = options[:domain] || @@domain
65     @ssl    = options[:ssl]
66   end
67  
68   def login(options)
69     options = { :method => :url, :username => 'Marshmallow' }.merge(options)
70    
71     @req = Net::HTTP::new("#{@domain}.campfirenow.com", @ssl ? 443 : 80) 
72     @req.use_ssl = @ssl
73     @req.verify_mode = OpenSSL::SSL::VERIFY_NONE if @ssl
74     headers = { 'Content-Type' => 'application/x-www-form-urlencoded' }
75    
76     case options[:method]
77     when :url
78       res = @req.post("/#{options[:url]}", "name=#{options[:username]}", headers)
79       # parse our response headers for the room number.. magic!
80       @room_id = res['location'].scan(/room\/(\d+)/).to_s
81       puts res.body if @debug
82        
83     when :login       
84       params = "email_address=#{CGI.escape(options[:username])}&password=#{CGI.escape(options[:password])}"
85       puts params if @debug
86       res = @req.post("/login/", params, headers)
87       @room_id = options[:room]
88       puts "Logging into room #{@room_id}" if @debug
89       puts res.body if @debug
90     end
91        
92     @headers = { 'Cookie' => res.response['set-cookie'] }
93     res2 = @req.get(res['location'], @headers)
94     puts res2.body if @debug
95
96     # refresh our headers
97     @headers = { 'Cookie' => res.response['set-cookie'] }
98     @req.get("/room/#{@room_id}/") # join the room if necessary
99     return @headers
100   end
101  
102   def paste(message)
103     say(message, true)
104   end
105  
106   def say(message, paste=false)
107     puts "Posting #{message}" if @debug
108     res = @req.post("/room/#{@room_id}/speak", "#{'paste=true&' if paste}message=#{CGI.escape(message.to_s)}", @headers)
109     puts res.body if @debug
110   end
111 end
112
113 if $0 == __FILE__
114   if ARGV.size != 3
115     puts "Usage: marshmallow https://username:password@domain.campfirenow.com/rooms/1234 [say|paste] 'Hello world!'"
116   else
117     print "Sending... "
118     $stdout.flush
119
120     to, how, what = *ARGV
121     Marshmallow.send(how, to, what)
122
123     puts "DONE!"
124   end
125 end
Note: See TracBrowser for help on using the browser.