twilio-ruby 3.2.0 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/.gitignore +5 -0
  2. data/Gemfile +3 -0
  3. data/README.md +70 -6
  4. data/README.rdoc +0 -0
  5. data/lib/twilio-ruby/rest/{accounts/account.rb → accounts.rb} +2 -0
  6. data/lib/twilio-ruby/rest/{applications/application.rb → applications.rb} +1 -0
  7. data/lib/twilio-ruby/rest/{available_phone_numbers/available_phone_numbers.rb → available_phone_numbers.rb} +2 -0
  8. data/lib/twilio-ruby/rest/{calls/call.rb → calls.rb} +6 -0
  9. data/lib/twilio-ruby/rest/client.rb +140 -27
  10. data/lib/twilio-ruby/rest/conferences/participants.rb +18 -1
  11. data/lib/twilio-ruby/rest/{conferences/conference.rb → conferences.rb} +2 -0
  12. data/lib/twilio-ruby/rest/{incoming_phone_numbers/incoming_phone_numbers.rb → incoming_phone_numbers.rb} +2 -0
  13. data/lib/twilio-ruby/rest/instance_resource.rb +39 -0
  14. data/lib/twilio-ruby/rest/list_resource.rb +67 -7
  15. data/lib/twilio-ruby/rest/{notifications/notification.rb → notifications.rb} +1 -0
  16. data/lib/twilio-ruby/rest/{outgoing_caller_ids/outgoing_caller_ids.rb → outgoing_caller_ids.rb} +2 -0
  17. data/lib/twilio-ruby/rest/{recordings/recording.rb → recordings.rb} +2 -2
  18. data/lib/twilio-ruby/rest/{sandbox/sandbox.rb → sandbox.rb} +0 -0
  19. data/lib/twilio-ruby/rest/sms/messages.rb +2 -0
  20. data/lib/twilio-ruby/rest/sms/short_codes.rb +1 -0
  21. data/lib/twilio-ruby/rest/{sms/sms.rb → sms.rb} +0 -0
  22. data/lib/twilio-ruby/rest/{transcriptions/transcription.rb → transcriptions.rb} +1 -0
  23. data/lib/twilio-ruby/version.rb +3 -0
  24. data/lib/twilio-ruby.rb +29 -44
  25. data/test/twilio_spec.rb +141 -4
  26. data/twilio-ruby.gemspec +25 -11
  27. metadata +178 -84
  28. data/lib/twilio-ruby/rest/accounts/accounts.rb +0 -5
  29. data/lib/twilio-ruby/rest/applications/applications.rb +0 -5
  30. data/lib/twilio-ruby/rest/available_phone_numbers/available_phone_number.rb +0 -5
  31. data/lib/twilio-ruby/rest/calls/calls.rb +0 -10
  32. data/lib/twilio-ruby/rest/conferences/conferences.rb +0 -5
  33. data/lib/twilio-ruby/rest/conferences/participant.rb +0 -17
  34. data/lib/twilio-ruby/rest/incoming_phone_numbers/incoming_phone_number.rb +0 -5
  35. data/lib/twilio-ruby/rest/notifications/notifications.rb +0 -5
  36. data/lib/twilio-ruby/rest/outgoing_caller_ids/outgoing_caller_id.rb +0 -5
  37. data/lib/twilio-ruby/rest/recordings/recordings.rb +0 -5
  38. data/lib/twilio-ruby/rest/sms/message.rb +0 -5
  39. data/lib/twilio-ruby/rest/sms/short_code.rb +0 -5
  40. data/lib/twilio-ruby/rest/transcriptions/transcriptions.rb +0 -5
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *~
2
+ .*
3
+ pkg/*
4
+ doc/*
5
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/README.md CHANGED
@@ -16,20 +16,82 @@ $ rake gem
16
16
  $ gem install pkg/twilio-ruby-{version}
17
17
  ```
18
18
 
19
- ## Some Code To Get You Started
19
+ ## Get Started With Client Capability Tokens
20
+
21
+ If you just need to generate a Capability Token for use with Twilio Client, you
22
+ can do this:
23
+
24
+ ``` ruby
25
+ require 'rubygems' # not necessary with ruby 1.9 but included for completeness
26
+ require 'twilio-ruby'
27
+
28
+ # put your own account credentials here:
29
+ account_sid = 'AC043dcf9844e13758bc3a36a84c29761'
30
+ auth_token = '62ea81de3a5b413254eb263595357c69'
31
+
32
+ # set up
33
+ capability = Twilio::Util::Capability.new account_sid, auth_token
34
+
35
+ # allow outgoing calls to an application
36
+ capability.allow_client_outgoing 'AP89a0180a1a4ddf1da954efca349b7a20'
37
+
38
+ # allow incoming calls to 'andrew'
39
+ capability.allow_client_incoming 'andrew'
40
+
41
+ # generate the token string
42
+ @token = capability.generate
43
+ ```
44
+
45
+ There is a slightly more detailed document in the
46
+ [Capability](twilio-ruby/wiki/Capability) section of the wiki.
47
+
48
+ ## Getting Started with TwiML
49
+
50
+ TwiML support is based on the [builder][1] library. You can construct a TwiML
51
+ response like this:
52
+
53
+ ``` ruby
54
+ require 'rubygems' # not necessary with ruby 1.9 but included for completeness
55
+ require 'twilio-ruby'
56
+
57
+ # build up a response
58
+ response = Twilio::TwiML::Response.new do |r|
59
+ r.Say 'hello there', :voice => 'woman'
60
+ r.Dial :callerId => '+14159992222' do |d|
61
+ d.Client 'jenny'
62
+ end
63
+ end
64
+
65
+ # print the result
66
+ puts response.text
67
+ ```
68
+
69
+ This will print the following (except for the whitespace):
70
+
71
+ ```
72
+ <?xml version="1.0" encoding="UTF-8"?>
73
+ <Response>
74
+ <Say voice="woman">hello there</Say>
75
+ <Dial callerId="+14159992222">
76
+ <Client>jenny</Client>
77
+ </Dial>
78
+ </Response>
79
+ ```
80
+
81
+ ## Getting Started with REST
20
82
 
21
83
  ### Setup Work
22
84
 
23
85
  ``` ruby
24
- require 'rubygems' # not necessary with ruby 1.9.2 but included for completeness
86
+ require 'rubygems' # not necessary with ruby 1.9 but included for completeness
25
87
  require 'twilio-ruby'
26
88
 
27
89
  # put your own credentials here
28
- @account_sid = 'AC043dcf9844e04758bc3a36a84c29761'
29
- @auth_token = '62ea81de3a5b414154eb263595357c69'
90
+ account_sid = 'AC043dcf9844e04758bc3a36a84c29761'
91
+ auth_token = '62ea81de3a5b414154eb263595357c69'
30
92
 
31
93
  # set up a client to talk to the Twilio REST API
32
- @client = Twilio::REST::Client.new(@account_sid, @auth_token)
94
+ @client = Twilio::REST::Client.new account_sid, auth_token
33
95
  ```
34
96
 
35
97
  ### Send an SMS
@@ -84,4 +146,6 @@ require 'twilio-ruby'
84
146
 
85
147
  There are more detailed examples in the included [examples.rb](twilio-ruby/blob/master/examples.rb).
86
148
 
87
- Full [API documentation](twilio-ruby/wiki/Documentation), as well as an [upgrade guide](twilio-ruby/wiki/UpgradeGuide) for users of the old twiliolib gem, is available in the [twilio-ruby github wiki](twilio-ruby/wiki).
149
+ Full [API documentation](twilio-ruby/wiki/Documentation), as well as an [upgrade guide](twilio-ruby/wiki/UpgradeGuide) for users of the old twiliolib gem, is available in the [twilio-ruby github wiki](twilio-ruby/wiki).
150
+
151
+ [1]:http://builder.rubyforge.org/
data/README.rdoc ADDED
File without changes
@@ -1,5 +1,7 @@
1
1
  module Twilio
2
2
  module REST
3
+ class Accounts < ListResource; end
4
+
3
5
  class Account < InstanceResource
4
6
  def initialize(uri, client, params={})
5
7
  super uri, client, params
@@ -1,5 +1,6 @@
1
1
  module Twilio
2
2
  module REST
3
+ class Applications < ListResource; end
3
4
  class Application < InstanceResource; end
4
5
  end
5
6
  end
@@ -7,5 +7,7 @@ module Twilio
7
7
  @uri, @client = uri, client
8
8
  end
9
9
  end
10
+
11
+ class AvailablePhoneNumber < InstanceResource; end
10
12
  end
11
13
  end
@@ -1,5 +1,11 @@
1
1
  module Twilio
2
2
  module REST
3
+ class Calls < ListResource
4
+ def make(from, to, url)
5
+ create :from => from, :to => to, :url => url
6
+ end
7
+ end
8
+
3
9
  class Call < InstanceResource
4
10
  def initialize(uri, client, params={})
5
11
  super uri, client, params
@@ -1,26 +1,118 @@
1
1
  module Twilio
2
2
  module REST
3
+ ##
4
+ # The Twilio::REST::Client class caches authentication parameters and
5
+ # exposes methods to make HTTP requests to Twilio's REST API. However, you
6
+ # should never really need to call these methods yourself since you can
7
+ # work with the more pleasant wrapper objects like Twilio::REST::Call.
8
+ #
9
+ # Instantiate a client like so:
10
+ #
11
+ # @client = Twilio::REST::Client.new account_sid, auth_token
12
+ #
13
+ # There are a few options you can use to configure the way your client will
14
+ # communicate with Twilio. See #new for a list and descriptions.
15
+ #
16
+ # Once you have a client object you can use it to do fun things. Every
17
+ # client object exposes two wrapper objects which you can use as entry
18
+ # points into Twilio: +account+ and +accounts+.
19
+ #
20
+ # ==== @client.account
21
+ #
22
+ # Most of the time you'll want to start with the +account+ attribute. This
23
+ # object is an instance of Twilio::REST::Account that wraps the account
24
+ # referenced by the +account_sid+ you used when instantiating the client.
25
+ #
26
+ # An instance of Twilio::REST::Account exposes objects wrapping all of the
27
+ # account-level Twilio resources as properties. So
28
+ #
29
+ # @client.account.calls
30
+ #
31
+ # represents an account's call list.
32
+ #
33
+ # ==== @client.accounts
34
+ #
35
+ # If you are doing anything related to subaccounts you'll want to start
36
+ # here. This object is an instance of Twilio::REST::Accounts that wraps
37
+ # the list of accounts belonging to the master account referenced by
38
+ # the +account_sid+ used to instantiate the client.
39
+ #
40
+ # This class inherits from Twilio::REST::ListResource, so you can use
41
+ # methods like ListResource#list to return a (possibly filtered) list of
42
+ # accounts and ListResource#create to create a new account. Use
43
+ # ListResource#get to grab a particular account once you know its sid.
3
44
  class Client
4
-
5
45
  include Twilio::Util
6
46
  include Twilio::REST::Utils
7
47
 
8
48
  HTTP_HEADERS = {
9
49
  'Accept' => 'application/json',
10
- 'User-Agent' => 'twilio-ruby/3.2.0',
50
+ 'User-Agent' => "twilio-ruby/#{Twilio::VERSION}",
11
51
  }
12
52
 
13
- attr_reader :account_sid, :account, :accounts
53
+ attr_reader :account_sid, :account, :accounts, :last_request,
54
+ :last_response
14
55
 
15
- def initialize(account_sid, auth_token, domain = 'api.twilio.com',
16
- proxy_host = nil, proxy_port = nil)
17
- @account_sid = account_sid
18
- @auth_token = auth_token
19
- set_up_connection_to domain, proxy_host, proxy_port
56
+ ##
57
+ # Instantiate a new HTTP client to talk to Twilio. The parameters
58
+ # +account_sid+ and +auth_token+ are required and used to generate the
59
+ # HTTP basic auth header in each request. The +options+ parameter is a
60
+ # hash of connection configuration options. the following keys are
61
+ # supported:
62
+ #
63
+ # === <tt>:host => 'api.twilio.com'</tt>
64
+ #
65
+ # The domain to which you'd like the client to make HTTP requests. Useful
66
+ # for testing. Defaults to 'api.twilio.com'.
67
+ #
68
+ # === <tt>:port => 443</tt>
69
+ #
70
+ # The port on which to connect to the above domain. Defaults to 443 and
71
+ # should be left that way except in testing environments.
72
+ #
73
+ # === <tt>:use_ssl => true</tt>
74
+ #
75
+ # Declare whether ssl should be used for connections to the above domain.
76
+ # Defaults to true and should be left alone except when testing.
77
+ #
78
+ # === <tt>:ssl_verify_peer => true</tt>
79
+ #
80
+ # Declare whether to verify the host's ssl cert when setting up the
81
+ # connection to the above domain. Defaults to true, but can be turned off
82
+ # to avoid insecure connection warnings in environments without the proper
83
+ # cert validation chain.
84
+ #
85
+ # === <tt>:proxy_addr => 'proxy.host.domain'</tt>
86
+ #
87
+ # The domain of a proxy through which you'd like the client to make HTTP
88
+ # requests. Defaults to nil.
89
+ #
90
+ # === <tt>:proxy_port => 3128</tt>
91
+ #
92
+ # The port on which to connect to the above proxy. Defaults to nil.
93
+ #
94
+ # === <tt>:proxy_user => 'username'</tt>
95
+ #
96
+ # The user name to use for authentication with the proxy. Defaults to nil.
97
+ #
98
+ # === <tt>:proxy_pass => 'password'</tt>
99
+ #
100
+ # The password to use for authentication with the proxy. Defaults to nil.
101
+ def initialize(account_sid, auth_token, options = {})
102
+ @account_sid, @auth_token = account_sid.strip, auth_token.strip
103
+ set_up_connection_from options
20
104
  set_up_subresources
21
105
  end
22
106
 
23
- # Define some helper methods for sending HTTP requests
107
+ def inspect # :nodoc:
108
+ "<Twilio::REST::Client @account_sid=#{@account_sid}>"
109
+ end
110
+
111
+ ##
112
+ # Define #get, #put, #post and #delete helper methods for sending HTTP
113
+ # requests to Twilio. You shouldn't need to use these methods directly,
114
+ # but they can be useful for debugging. Each method returns a hash
115
+ # obtained from parsing the JSON object in the response body.
24
116
  [:get, :put, :post, :delete].each do |method|
25
117
  method_class = Net::HTTP.const_get method.to_s.capitalize
26
118
  define_method method do |uri, *args|
@@ -34,13 +126,21 @@ module Twilio
34
126
  end
35
127
  end
36
128
 
37
- # Mimic the old (deprecated) interface
38
- def request(uri, method = 'POST', params = {})
129
+ ##
130
+ # Mimic the old (deprecated) interface. Make an HTTP request to Twilio
131
+ # using the given +method+ and +uri+. If the +method+ is <tt>'GET'</tt>
132
+ # then +params+ are appended to the +uri+ as urlencoded query parameters.
133
+ # If the +method+ is <tt>'POST'</tt> or <tt>'PUT'</tt> then +params+ are
134
+ # passed as an application/x-www-form-urlencoded string in the request
135
+ # body.
136
+ #
137
+ # Returns the raw Net::HTTP::Response object.
138
+ def request(uri, method = 'POST', params = {}) # :nodoc:
39
139
  raise ArgumentError, 'Invalid path parameter' if uri.empty?
40
140
 
41
141
  uri = "/#{uri}" unless uri.start_with? '/'
42
142
 
43
- case method
143
+ case method.upcase
44
144
  when 'GET'
45
145
  uri << "?#{url_encode(params)}" if params
46
146
  req = Net::HTTP::Get.new uri
@@ -57,33 +157,47 @@ module Twilio
57
157
  end
58
158
 
59
159
  req.basic_auth @account_sid, @auth_token
60
- @connection.request req
160
+ @last_request = req
161
+ @last_response = @connection.request req
61
162
  end
62
163
 
63
164
  private
64
165
 
65
- def set_up_connection_to(domain, proxy_host = nil, proxy_port = nil)
66
- connection_class = Net::HTTP::Proxy proxy_host, proxy_port
67
- @connection = connection_class.new domain, 443
68
- @connection.use_ssl = true
69
- # Don't check the server cert. Ideally this is configurable in case an
70
- # app wants to verify that it's actually talking to the real Twilio.
71
- # But cert validation is usually a nightmare, so we skip it for now.
72
- @connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
166
+ ##
167
+ # Set up and cache a Net::HTTP object to use when making requests. This is
168
+ # a private method documented for completeness.
169
+ def set_up_connection_from(options = {}) # :doc:
170
+ config = {:host => 'api.twilio.com', :port => 443, :use_ssl => true,
171
+ :ssl_verify_peer => true}.merge! options
172
+ connection_class = Net::HTTP::Proxy config[:proxy_addr],
173
+ config[:proxy_port], config[:proxy_user], config[:proxy_pass]
174
+ @connection = connection_class.new config[:host], config[:port]
175
+ @connection.use_ssl = config[:use_ssl]
176
+ unless config[:ssl_verify_peer]
177
+ @connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
178
+ end
73
179
  end
74
180
 
75
- def set_up_subresources
181
+ ##
182
+ # Set up +account+ and +accounts+ attributes.
183
+ def set_up_subresources # :doc:
76
184
  accounts_uri = '/2010-04-01/Accounts'
77
185
  account_uri = "#{accounts_uri}/#{@account_sid}"
78
- # Set up a special handle to grab the account.
79
186
  @account = Twilio::REST::Account.new account_uri, self
80
- # Set up the accounts subresource.
81
187
  @accounts = Twilio::REST::Accounts.new accounts_uri, self
82
188
  end
83
189
 
84
- def connect_and_send(request)
190
+ ##
191
+ # Send an HTTP request using the cached <tt>@connection</tt> object and
192
+ # return the JSON response body parsed into a hash. Also save the raw
193
+ # Net::HTTP::Request and Net::HTTP::Response objects as
194
+ # <tt>@last_request</tt> and <tt>@last_response</tt> to allow for
195
+ # inspection later.
196
+ def connect_and_send(request) # :doc:
197
+ @last_request = request
85
198
  response = @connection.request request
86
- object = JSON.parse response.body if response.body
199
+ @last_response = response
200
+ object = MultiJson.decode response.body if response.body
87
201
  if response.kind_of? Net::HTTPClientError
88
202
  raise Twilio::REST::RequestError, object['message']
89
203
  elsif response.kind_of? Net::HTTPServerError
@@ -91,7 +205,6 @@ module Twilio
91
205
  end
92
206
  object
93
207
  end
94
-
95
208
  end
96
209
  end
97
210
  end
@@ -1,5 +1,22 @@
1
1
  module Twilio
2
2
  module REST
3
- class Participants < ListResource; end
3
+ class Participants < ListResource
4
+ private
5
+ def instance_sid_key
6
+ 'call_sid'
7
+ end
8
+ end
9
+
10
+ class Participant < InstanceResource
11
+ def mute
12
+ update :muted => 'true'
13
+ end
14
+
15
+ def unmute
16
+ update :muted => 'false'
17
+ end
18
+
19
+ alias :kick :delete
20
+ end
4
21
  end
5
22
  end
@@ -1,5 +1,7 @@
1
1
  module Twilio
2
2
  module REST
3
+ class Conferences < ListResource; end
4
+
3
5
  class Conference < InstanceResource
4
6
  def initialize(uri, client, params={})
5
7
  super uri, client, params
@@ -5,5 +5,7 @@ module Twilio
5
5
  create :phone_number => phone_number
6
6
  end
7
7
  end
8
+
9
+ class IncomingPhoneNumber < InstanceResource; end
8
10
  end
9
11
  end
@@ -1,13 +1,41 @@
1
1
  module Twilio
2
2
  module REST
3
+ ##
4
+ # A class to wrap an instance resource (like a call or application) within
5
+ # the Twilio API. All other instance resource classes within this library
6
+ # inherit from this class. You shouldn't need to instantiate this class
7
+ # directly. But reviewing the available methods is informative since they
8
+ # are rarely overridden in the inheriting class.
3
9
  class InstanceResource
4
10
  include Utils
5
11
 
12
+ ##
13
+ # Instantiate a new instance resource object. You must pass the +uri+ of
14
+ # the instance (e.g. /2010-04-01/Accounts/AC123/Calls/CA456) as well as a
15
+ # +client+ object that responds to #get #post and #delete. This client
16
+ # is meant to be an instance of Twilio::REST::Client but could just as
17
+ # well be a mock object if you want to test the interface. The optional
18
+ # +params+ hash will be converted into attributes on the instantiated
19
+ # object.
6
20
  def initialize(uri, client, params = {})
7
21
  @uri, @client = uri, client
8
22
  set_up_properties_from params
9
23
  end
10
24
 
25
+ def inspect # :nodoc:
26
+ "<#{self.class} @uri=#{@uri}>"
27
+ end
28
+
29
+ ##
30
+ # Update the properties of this instance resource using the key/value
31
+ # pairs in +params+. This makes an HTTP POST request to <tt>@uri</tt>
32
+ # to handle the update. For example, to update the +VoiceUrl+ of a Twilio
33
+ # Application you could write:
34
+ #
35
+ # @app.update :voice_url => 'http://my.other.app.com/handle_voice'
36
+ #
37
+ # After returning, the object will contain the most recent state of the
38
+ # instance resource, including the newly updated properties.
11
39
  def update(params = {})
12
40
  raise "Can't update a resource without a REST Client" unless @client
13
41
  response = @client.post @uri, params
@@ -15,18 +43,29 @@ module Twilio
15
43
  self
16
44
  end
17
45
 
46
+ ##
47
+ # Refresh the attributes of this instance resource object by fetching it
48
+ # from Twilio. Calling this makes an HTTP GET request to <tt>@uri</tt>.
18
49
  def refresh
19
50
  raise "Can't refresh a resource without a REST Client" unless @client
20
51
  @updated = false
21
52
  response = @client.get @uri
22
53
  set_up_properties_from response
54
+ self
23
55
  end
24
56
 
57
+ ##
58
+ # Delete an instance resource from Twilio. This operation isn't always
59
+ # supported. For instance, you can't delete an SMS. Calling this method
60
+ # makes an HTTP DELETE request to <tt>@uri</tt>.
25
61
  def delete
26
62
  raise "Can't delete a resource without a REST Client" unless @client
27
63
  @client.delete @uri
28
64
  end
29
65
 
66
+ ##
67
+ # Lazily load attributes of the instance resource by waiting to fetch it
68
+ # until an attempt is made to access an unknown attribute.
30
69
  def method_missing(method, *args)
31
70
  super if @updated
32
71
  response = @client.get @uri