tropo_message 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.5
data/lib/tropo_message.rb CHANGED
@@ -8,94 +8,164 @@ module Tropo
8
8
  @tropo_session = tropo_session
9
9
  end
10
10
 
11
- def parse(tropo_session)
12
- self.tropo_session = tropo_session
11
+ # Interesting methods
12
+
13
+ # Determines whether a message is meant for sending by checking
14
+ # if it has session parameters. This is useful for example if you have the same
15
+ # handler url for incoming and outgoing messages
16
+ #
17
+ # Example:
18
+ # tropo_object = Tropo::Generator.parse(raw_json)
19
+ # tropo_message = Tropo::Message.new(tropo_object)
20
+ # tropo_message.outgoing?
21
+ #
22
+ def outgoing?
23
+ tropo_session["session"] && tropo_session["session"]["parameters"]
13
24
  end
14
25
 
15
- def token
16
- params["token"] || tropo_parameters["token"]
26
+ # An alternative to the constructor
27
+ #
28
+ # Example:
29
+ # tropo_object = Tropo::Generator.parse(raw_json)
30
+ # tropo_message = Tropo::Message.new
31
+ # tropo_message.parse(tropo_object)
32
+ #
33
+ def parse(tropo_session)
34
+ self.tropo_session = tropo_session
17
35
  end
18
36
 
19
- def token=(value)
20
- params["token"] = value
37
+ # Generates xml suitable for an XML POST request to Tropo
38
+ #
39
+ # Example:
40
+ # tropo_message = Tropo::Message.new
41
+ # tropo_message.to = "44122782474"
42
+ # tropo_message.text = "Hi John, how r u today?"
43
+ # tropo_message.token = "1234512345"
44
+ #
45
+ # tropo_message.request_xml # =>
46
+ # # <sessions>
47
+ # # <token>1234512345</token>
48
+ # # <var name="to" value="44122782474"/>
49
+ # # <var name="text" value="Hi+John%2C+how+r+u+today%3F"/>
50
+ # # </sessions>"
51
+ #
52
+ def request_xml
53
+ request_params = @params.dup
54
+ token = request_params.delete("token")
55
+ xml = ""
56
+ request_params.each do |key, value|
57
+ xml << "<var name=\"#{escape(key)}\" value=\"#{escape(value)}\"/>"
58
+ end
59
+ "<sessions><token>#{token}</token>#{xml}</sessions>"
60
+ end
61
+
62
+ # Generates a hash suitable for using to as input to:
63
+ # Tropo::Generator#message (see: http://github.com/voxeo/tropo-webapi-ruby)
64
+ #
65
+ # By default, "channel" => "TEXT" and "network" => "SMS"
66
+ # You can override these values and any other optional parameters by setting
67
+ # their values e.g. tropo_message.channel = "VOICE"
68
+ #
69
+ # Example:
70
+ # tropo_object = Tropo::Generator.parse(raw_json)
71
+ #
72
+ # tropo_object # => {
73
+ # # "session" => {
74
+ # # ...
75
+ # # "parameters" => {
76
+ # # "to" => "44122782474",
77
+ # # "text" => "Hi+John%2C+how+r+u+today%3F",
78
+ # # "my_favourite_food" => "Pizza"
79
+ # # }
80
+ # # }
81
+ # #}
82
+ #
83
+ # tropo_message = Tropo::Message.new(tropo_object)
84
+ # response_params = tropo_message.response_params # => {
85
+ # # "to" => "44122782474",
86
+ # # "channel" => "TEXT",
87
+ # # "network" => "SMS"
88
+ # #}
89
+ #
90
+ # text = tropo_message.text
91
+ #
92
+ # Tropo::Generator.new.message(response_params) do
93
+ # say :value => text
94
+ # end
95
+ #
96
+ def response_params
97
+ params = {
98
+ "to" => to,
99
+ "channel" => channel,
100
+ "network" => network
101
+ }
102
+ params.merge!("from" => from) if from
103
+ params.merge!("timeout" => timeout) if timeout
104
+ params.merge!("answer_on_media" => answer_on_media) if answer_on_media
105
+ params.merge!("headers" => headers) if headers
106
+ params.merge!("recording" => recording) if recording
107
+ params
21
108
  end
22
109
 
23
- def to
24
- params["to"] || tropo_parameters["to"]
110
+ # Getter/Setter methods
111
+ def action
112
+ params["action"] || tropo_parameters["action"]
25
113
  end
26
114
 
27
- def to=(value)
28
- params["to"] = value
115
+ def answer_on_media
116
+ params["answer_on_media"] || tropo_parameters["answer_on_media"]
29
117
  end
30
118
 
31
119
  def channel
32
- params["channel"] || tropo_parameters["channel"] || 'TEXT'
120
+ params["channel"] || tropo_parameters["channel"] || "TEXT"
33
121
  end
34
122
 
35
- def network
36
- params["network"] || tropo_parameters["network"] || 'SMS'
123
+ def from
124
+ params["from"] || tropo_parameters["from"]
37
125
  end
38
126
 
39
- def text
40
- params["text"] || tropo_parameters["msg"]
127
+ def from=(value)
128
+ params["from"] = value
41
129
  end
42
- alias :msg :text
43
130
 
44
- def text=(value)
45
- params["text"] = value
131
+ def headers
132
+ params["headers"] || tropo_parameters["headers"]
46
133
  end
47
- alias :msg= :text=
48
134
 
49
- def from
50
- params["from"] || tropo_parameters["from"]
135
+ def network
136
+ params["network"] || tropo_parameters["network"] || "SMS"
51
137
  end
52
138
 
53
- def from=(value)
54
- params["from"] = value
139
+ def recording
140
+ params["recording"] || tropo_parameters["recording"]
55
141
  end
56
142
 
57
- def timeout
58
- params["timeout"] || tropo_parameters["timeout"]
143
+ def text
144
+ params["text"] || tropo_parameters["text"]
59
145
  end
60
146
 
61
- def answer_on_media
62
- params["answer_on_media"] || tropo_parameters["answer_on_media"]
147
+ def text=(value)
148
+ params["text"] = value
63
149
  end
64
150
 
65
- def headers
66
- params["headers"] || tropo_parameters["headers"]
151
+ def timeout
152
+ params["timeout"] || tropo_parameters["timeout"]
67
153
  end
68
154
 
69
- def recording
70
- params["recording"] || tropo_parameters["recording"]
155
+ def to
156
+ params["to"] || tropo_parameters["to"]
71
157
  end
72
158
 
73
- def outgoing?
74
- tropo_session["session"] && tropo_session["session"]["parameters"]
159
+ def to=(value)
160
+ params["to"] = value
75
161
  end
76
162
 
77
- def response_params
78
- params = {
79
- "to" => to,
80
- "channel" => channel,
81
- "network" => network
82
- }
83
- params.merge!("from" => from) if from
84
- params.merge!("timeout" => timeout) if timeout
85
- params.merge!("answer_on_media" => answer_on_media) if answer_on_media
86
- params.merge!("headers" => headers) if headers
87
- params.merge!("recording" => recording) if recording
88
- params
163
+ def token
164
+ params["token"] || tropo_parameters["token"]
89
165
  end
90
166
 
91
- def request_xml
92
- request_params = @params.dup
93
- token = request_params.delete("token")
94
- xml = ""
95
- request_params.each do |key, value|
96
- xml << "<var name=\"#{key}\" value=\"#{value}\"/>"
97
- end
98
- "<sessions><token>#{token}</token>#{xml.to_s}</sessions>"
167
+ def token=(value)
168
+ params["token"] = value
99
169
  end
100
170
 
101
171
  private
@@ -104,6 +174,27 @@ module Tropo
104
174
  parameters = session["parameters"] if session
105
175
  parameters || {}
106
176
  end
177
+
178
+ # Performs URI escaping so that you can construct proper
179
+ # query strings faster. Use this rather than the cgi.rb
180
+ # version since it's faster. (Stolen from Camping).
181
+ def escape(s)
182
+ s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) {
183
+ '%'+$1.unpack('H2'*bytesize($1)).join('%').upcase
184
+ }.tr(' ', '+')
185
+ end
186
+
187
+ # Return the bytesize of String; uses String#length under Ruby 1.8 and
188
+ # String#bytesize under 1.9.
189
+ if ''.respond_to?(:bytesize)
190
+ def bytesize(string)
191
+ string.bytesize
192
+ end
193
+ else
194
+ def bytesize(string)
195
+ string.size
196
+ end
197
+ end
107
198
  end
108
199
  end
109
200
 
@@ -0,0 +1,6 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'tropo_message'
4
+ require 'rspec'
5
+ require 'rspec/autorun'
6
+
@@ -0,0 +1,361 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tropo::Message do
4
+ let(:tropo_message) { Tropo::Message.new }
5
+ let(:tropo_session) {
6
+ {
7
+ "session" => {
8
+ "id"=>"703c4f12c46dd3a7ae07c95ee68f8b79",
9
+ "account_id"=>"12345",
10
+ "timestamp"=>Time.now,
11
+ "user_type"=>"NONE",
12
+ "initial_text"=>nil,
13
+ "call_id"=>nil,
14
+ "parameters"=>{
15
+ "token" => "123451234512345123451234512345123451234512345",
16
+ "text"=>"Hi%2C+how+r+u+today+%3A+my+friend+%3Cyour+name",
17
+ "to"=>"612382211234",
18
+ "from" => "661213433198",
19
+ "channel" => "SomeChannel",
20
+ "network" => "SomeNetwork",
21
+ "action" => "SomeAction",
22
+ "timeout" => "SomeTimeout",
23
+ "answer_on_media" => "Phone",
24
+ "headers" => "MyCustomHeaders",
25
+ "recording" => "MyRecording"
26
+ }
27
+ }
28
+ }
29
+ }
30
+
31
+ # Interesting methods
32
+ describe "#request_xml" do
33
+ it "should generate xml that includes all the message parameter keys and values" do
34
+ tropo_message.params = {"my_favourite_food" => "pho"}
35
+ tropo_message.request_xml.should include("my_favourite_food")
36
+ tropo_message.request_xml.should include("pho")
37
+ end
38
+ it "should generate xml that includes the session token" do
39
+ tropo_message.token = "23932349191932432"
40
+ tropo_message.request_xml.should include("token")
41
+ tropo_message.request_xml.should include("23932349191932432")
42
+ end
43
+ it "should escape all message parameters" do
44
+ tropo_message.text = "<hello/>+$#%"
45
+ tropo_message.request_xml.should include("%3Chello%2F%3E%2B%24%23%25")
46
+ end
47
+ end
48
+
49
+ describe "#parse" do
50
+ it "should set the @tropo_session instance variable" do
51
+ tropo_message.parse(tropo_session)
52
+ tropo_message.tropo_session.should == tropo_session
53
+ end
54
+ end
55
+
56
+ describe "#outgoing?" do
57
+ context "setting up a message for sending" do
58
+ it "should be false" do
59
+ tropo_message.should_not be_outgoing
60
+ end
61
+ end
62
+ context "responding to tropo" do
63
+ context "the session has a 'parameters' hash" do
64
+ it "should be true" do
65
+ tropo_message.parse(tropo_session)
66
+ tropo_message.should be_outgoing
67
+ end
68
+ end
69
+ context "the session does not have a 'parameters' hash" do
70
+ before do
71
+ tropo_session["session"].delete("parameters")
72
+ end
73
+ it "should be false" do
74
+ tropo_message.parse(tropo_session)
75
+ tropo_message.should_not be_outgoing
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ describe "#response_params" do
82
+ # see also: http://github.com/voxeo/tropo-webapi-ruby
83
+ context "the tropo session parameters include all the required and optional parameters for Tropo::Generator#message" do
84
+ it "should include all the required and optional parameters" do
85
+ tropo_message.parse(tropo_session)
86
+ tropo_message.response_params.should == {
87
+ "to" => "612382211234",
88
+ "channel" => "SomeChannel",
89
+ "network" => "SomeNetwork",
90
+ "from" => "661213433198",
91
+ "timeout" => "SomeTimeout",
92
+ "answer_on_media" => "Phone",
93
+ "headers" => "MyCustomHeaders",
94
+ "recording" => "MyRecording"
95
+ }
96
+ end
97
+ end
98
+ context "the tropo session parameters only includes 'to'" do
99
+ before do
100
+ parameters = tropo_session["session"].delete("parameters")
101
+ tropo_session["session"]["parameters"] = { "to" => parameters["to"] }
102
+ end
103
+ it "should include all the required parameters" do
104
+ tropo_message.parse(tropo_session)
105
+ tropo_message.response_params.should == {
106
+ "to" => "612382211234",
107
+ "channel" => "TEXT",
108
+ "network" => "SMS",
109
+ }
110
+ end
111
+ end
112
+ end
113
+
114
+ # Less interesting methods
115
+ # Methods with setters
116
+ describe "#token" do
117
+ context "setting up a message for sending" do
118
+ it "should set the token" do
119
+ tropo_message.token = "my token"
120
+ tropo_message.token.should == "my token"
121
+ end
122
+ end
123
+ context "responding to tropo" do
124
+ it "should return the token from the session parameters" do
125
+ tropo_message.parse(tropo_session)
126
+ tropo_message.token.should == "123451234512345123451234512345123451234512345"
127
+ end
128
+ end
129
+ end
130
+
131
+ describe "#to" do
132
+ context "setting up a message for sending" do
133
+ it "should set the receiver" do
134
+ tropo_message.to = "841232312342"
135
+ tropo_message.to.should == "841232312342"
136
+ end
137
+ end
138
+ context "responding to tropo" do
139
+ it "should return the receiver from the session parameters" do
140
+ tropo_message.parse(tropo_session)
141
+ tropo_message.to.should == "612382211234"
142
+ end
143
+ end
144
+ end
145
+
146
+ describe "#from" do
147
+ context "setting up a message for sending" do
148
+ it "should set the sender" do
149
+ tropo_message.from = "1331485573"
150
+ tropo_message.from.should == "1331485573"
151
+ end
152
+ end
153
+ context "responding to tropo" do
154
+ it "should return the sender from the session parameters" do
155
+ tropo_message.parse(tropo_session)
156
+ tropo_message.from.should == "661213433198"
157
+ end
158
+ end
159
+ end
160
+
161
+ describe "#text" do
162
+ context "setting up a message for sending" do
163
+ it "should set the text" do
164
+ tropo_message.text = "hello johnny (whats happening?)"
165
+ tropo_message.text.should == "hello johnny (whats happening?)"
166
+ end
167
+ end
168
+ context "responding to tropo" do
169
+ it "should return the text from the session parameters" do
170
+ tropo_message.parse(tropo_session)
171
+ tropo_message.text.should == "Hi%2C+how+r+u+today+%3A+my+friend+%3Cyour+name"
172
+ end
173
+ end
174
+ end
175
+
176
+ # Methods without setters
177
+ # Methods with default return values
178
+ describe "#channel" do
179
+ context "setting up a message for sending" do
180
+ it "should set the channel" do
181
+ tropo_message.params = {"channel" => "Channel 8"}
182
+ tropo_message.channel.should == "Channel 8"
183
+ end
184
+ end
185
+ context "responding to tropo" do
186
+ context "'channel' is in the session parameters" do
187
+ it "should return the channel from the session parameters" do
188
+ tropo_message.parse(tropo_session)
189
+ tropo_message.channel.should == "SomeChannel"
190
+ end
191
+ end
192
+ context "'channel' is not in the session parameters" do
193
+ before do
194
+ tropo_session["session"]["parameters"].delete("channel")
195
+ end
196
+ it "should return 'TEXT'" do
197
+ tropo_message.parse(tropo_session)
198
+ tropo_message.channel.should == "TEXT"
199
+ end
200
+ end
201
+ end
202
+ end
203
+
204
+ describe "#network" do
205
+ context "setting up a message for sending" do
206
+ it "should set the network" do
207
+ tropo_message.params = {"network" => "Network 10"}
208
+ tropo_message.network.should == "Network 10"
209
+ end
210
+ end
211
+ context "responding to tropo" do
212
+ context "'network' is in the session parameters" do
213
+ it "should return the network from the session parameters" do
214
+ tropo_message.parse(tropo_session)
215
+ tropo_message.network.should == "SomeNetwork"
216
+ end
217
+ end
218
+ context "'network' is not in the session parameters" do
219
+ before do
220
+ tropo_session["session"]["parameters"].delete("network")
221
+ end
222
+ it "should return 'SMS'" do
223
+ tropo_message.parse(tropo_session)
224
+ tropo_message.network.should == "SMS"
225
+ end
226
+ end
227
+ end
228
+ end
229
+
230
+ # Methods without default return values
231
+ describe "#action" do
232
+ context "setting up a message for sending" do
233
+ it "should set the action" do
234
+ tropo_message.params = {"action" => "my action"}
235
+ tropo_message.action.should == "my action"
236
+ end
237
+ end
238
+ context "responding to tropo" do
239
+ context "'action' is in the session parameters" do
240
+ it "should return the action from the session parameters" do
241
+ tropo_message.parse(tropo_session)
242
+ tropo_message.action.should == "SomeAction"
243
+ end
244
+ end
245
+ context "'action' is not in the session parameters" do
246
+ before do
247
+ tropo_session["session"]["parameters"].delete("action")
248
+ end
249
+ it "should return nil" do
250
+ tropo_message.parse(tropo_session)
251
+ tropo_message.action.should be_nil
252
+ end
253
+ end
254
+ end
255
+ end
256
+
257
+ describe "#timeout" do
258
+ context "setting up a message for sending" do
259
+ it "should set the timeout" do
260
+ tropo_message.params = {"timeout" => "5 seconds"}
261
+ tropo_message.timeout.should == "5 seconds"
262
+ end
263
+ end
264
+ context "responding to tropo" do
265
+ context "'timeout' is in the session parameters" do
266
+ it "should return the timeout from the session parameters" do
267
+ tropo_message.parse(tropo_session)
268
+ tropo_message.timeout.should == "SomeTimeout"
269
+ end
270
+ end
271
+ context "'timeout' is not in the session parameters" do
272
+ before do
273
+ tropo_session["session"]["parameters"].delete("timeout")
274
+ end
275
+ it "should return nil" do
276
+ tropo_message.parse(tropo_session)
277
+ tropo_message.timeout.should be_nil
278
+ end
279
+ end
280
+ end
281
+ end
282
+
283
+ describe "#answer_on_media" do
284
+ context "setting up a message for sending" do
285
+ it "should set answer_on_media" do
286
+ tropo_message.params = {"answer_on_media" => "yes"}
287
+ tropo_message.answer_on_media.should == "yes"
288
+ end
289
+ end
290
+ context "responding to tropo" do
291
+ context "'answer_on_media' is in the session parameters" do
292
+ it "should return 'answer_on_media' from the session parameters" do
293
+ tropo_message.parse(tropo_session)
294
+ tropo_message.answer_on_media.should == "Phone"
295
+ end
296
+ end
297
+ context "'answer_on_media' is not in the session parameters" do
298
+ before do
299
+ tropo_session["session"]["parameters"].delete("answer_on_media")
300
+ end
301
+ it "should return nil" do
302
+ tropo_message.parse(tropo_session)
303
+ tropo_message.answer_on_media.should be_nil
304
+ end
305
+ end
306
+ end
307
+ end
308
+
309
+ describe "#headers" do
310
+ context "setting up a message for sending" do
311
+ it "should set the headers" do
312
+ tropo_message.params = {"headers" => "some custom headers"}
313
+ tropo_message.headers.should == "some custom headers"
314
+ end
315
+ end
316
+ context "responding to tropo" do
317
+ context "'headers' is in the session parameters" do
318
+ it "should return the headers from the session parameters" do
319
+ tropo_message.parse(tropo_session)
320
+ tropo_message.headers.should == "MyCustomHeaders"
321
+ end
322
+ end
323
+ context "'headers' is not in the session parameters" do
324
+ before do
325
+ tropo_session["session"]["parameters"].delete("headers")
326
+ end
327
+ it "should return nil" do
328
+ tropo_message.parse(tropo_session)
329
+ tropo_message.headers.should be_nil
330
+ end
331
+ end
332
+ end
333
+ end
334
+
335
+ describe "#recording" do
336
+ context "setting up a message for sending" do
337
+ it "should set the recording" do
338
+ tropo_message.params = {"recording" => "my recording"}
339
+ tropo_message.recording.should == "my recording"
340
+ end
341
+ end
342
+ context "responding to tropo" do
343
+ context "'recording' is in the session parameters" do
344
+ it "should return the recording from the session parameters" do
345
+ tropo_message.parse(tropo_session)
346
+ tropo_message.recording.should == "MyRecording"
347
+ end
348
+ end
349
+ context "'recording' is not in the session parameters" do
350
+ before do
351
+ tropo_session["session"]["parameters"].delete("recording")
352
+ end
353
+ it "should return nil" do
354
+ tropo_message.parse(tropo_session)
355
+ tropo_message.recording.should be_nil
356
+ end
357
+ end
358
+ end
359
+ end
360
+ end
361
+
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{tropo_message}
8
- s.version = "0.0.4"
8
+ s.version = "0.0.5"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["David Wilkie"]
12
- s.date = %q{2010-10-14}
12
+ s.date = %q{2010-10-15}
13
13
  s.description = %q{A tiny wrapper for creating a Tropo message}
14
14
  s.email = %q{dwilkie@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -24,6 +24,8 @@ Gem::Specification.new do |s|
24
24
  "Rakefile",
25
25
  "VERSION",
26
26
  "lib/tropo_message.rb",
27
+ "spec/spec_helper.rb",
28
+ "spec/tropo_messsage_spec.rb",
27
29
  "tropo_message.gemspec"
28
30
  ]
29
31
  s.homepage = %q{http://github.com/dwilkie/tropo_message}
@@ -31,6 +33,10 @@ Gem::Specification.new do |s|
31
33
  s.require_paths = ["lib"]
32
34
  s.rubygems_version = %q{1.3.7}
33
35
  s.summary = %q{A tiny wrapper for creating a Tropo message}
36
+ s.test_files = [
37
+ "spec/tropo_messsage_spec.rb",
38
+ "spec/spec_helper.rb"
39
+ ]
34
40
 
35
41
  if s.respond_to? :specification_version then
36
42
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 4
9
- version: 0.0.4
8
+ - 5
9
+ version: 0.0.5
10
10
  platform: ruby
11
11
  authors:
12
12
  - David Wilkie
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-10-14 00:00:00 +07:00
17
+ date: 2010-10-15 00:00:00 +07:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -35,6 +35,8 @@ files:
35
35
  - Rakefile
36
36
  - VERSION
37
37
  - lib/tropo_message.rb
38
+ - spec/spec_helper.rb
39
+ - spec/tropo_messsage_spec.rb
38
40
  - tropo_message.gemspec
39
41
  has_rdoc: true
40
42
  homepage: http://github.com/dwilkie/tropo_message
@@ -68,5 +70,6 @@ rubygems_version: 1.3.7
68
70
  signing_key:
69
71
  specification_version: 3
70
72
  summary: A tiny wrapper for creating a Tropo message
71
- test_files: []
72
-
73
+ test_files:
74
+ - spec/tropo_messsage_spec.rb
75
+ - spec/spec_helper.rb