Class: SpomskyApp

Inherits:
SMS::App
  • Object
show all
Defined in:
lib/spomskyd.rb

Instance Method Summary collapse

Constructor Details

#initialize(port) ⇒ SpomskyApp

Returns a new instance of SpomskyApp.


31
32
33
34
35
36
37
38
39
# File 'lib/spomskyd.rb', line 31

def initialize(port)
	@uuid = UUID.new()
	@subscribers = {}
	@port = port.to_i
	
	# to hold messages which were received while
	# no subscribers were available to relay to
	@pending = []
end

Instance Method Details

#incoming(msg) ⇒ Object

Notify each of @subscribers that an incoming SMS has arrived


103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/spomskyd.rb', line 103

def incoming(msg)
	data = { :source => msg.sender.phone_number, :body => msg.text }
	
	# "What?! There is NO USE CASE for discarding incoming
	#  messages. Hold on to them or something!" -- Jonathan
	if @subscribers.empty?
		log("Message held (no subscribers)", :warn)
		@pending.push(msg)
	end
	
	@subscribers.each do |uuid, uri|
		begin
			res = Net::HTTP.post_form(URI.parse(uri), data)
		
		# if something goes wrong... do nothing. a client
		# has probably vanished without unsubscribing. TODO:
		# count these errors per-client, and drop after a few
		rescue StandardError => err
			log_exception(err, "Error while relaying to: #{uri}")
		end
	end
end

#rack_app(env) ⇒ Object


56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/spomskyd.rb', line 56

def rack_app(env)
	req = Rack::Request.new(env)
	path = req.path_info
	post = req.POST
	
	# only POST is supported
	unless req.post?
		return resp "Method not allowed", 405
	end
	
	begin
		if path == "/send"
			router.backends.each do |backend|
				begin
					dest = post["destination"]
					log("Relaying to #{dest} via #{backend.label}")
					SMS::Outgoing.new(backend, dest, post["body"]).send!
				rescue StandardError => err
					return resp "Error while sending SMS: #{err}", 500
				end
			end
			
			resp "Message Sent"
	
		elsif path == "/receive/subscribe"
			uuid = subscribe("http://#{post["host"]}:#{post["port"]}/#{post["path"]}")
			resp "Subscribed", 200, { "x-subscription-uuid" => uuid }
		
		elsif path == "/receive/unsubscribe"
			unsubscribe(post["uuid"])
			resp "Unsubscribed"
		
		# no other urls are supported
		else
			warn "Invalid Request: #{path}"
			resp "Not Found", 404
		end
	
	rescue Exception => err
		log_exception(err)
		resp("Error: #{err.message}", 500)
	end
end

#startObject


41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/spomskyd.rb', line 41

def start
	@rack_thread = Thread.new do
		Rack::Handler::Mongrel.run(
			method(:rack_app), :Port=>@port)
	end
	
	# add the uri of this spomsky server
	# to the screen log, for the curious
	log [
		"Started SPOMSKYd Application",
		"URI: http://localhost:#{@port}/"
	], :init
end