twilio-ruby 3.12.3 → 3.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +8 -8
  2. data/CHANGES.md +12 -0
  3. data/README.md +14 -14
  4. data/Rakefile +2 -2
  5. data/docs/faq.rst +3 -3
  6. data/docs/getting-started.rst +17 -12
  7. data/docs/usage/accounts.rst +6 -6
  8. data/docs/usage/applications.rst +5 -5
  9. data/docs/usage/basics.rst +1 -1
  10. data/docs/usage/caller-ids.rst +4 -2
  11. data/docs/usage/conferences.rst +1 -1
  12. data/docs/usage/errors.rst +3 -3
  13. data/docs/usage/messages.rst +24 -16
  14. data/docs/usage/phone-calls.rst +10 -8
  15. data/docs/usage/phone-numbers.rst +15 -11
  16. data/docs/usage/sip.rst +9 -8
  17. data/docs/usage/twiml.rst +2 -2
  18. data/examples/examples.rb +44 -20
  19. data/lib/rack/twilio_webhook_authentication.rb +5 -1
  20. data/lib/twilio-ruby/rest/calls.rb +4 -4
  21. data/lib/twilio-ruby/rest/client.rb +25 -23
  22. data/lib/twilio-ruby/rest/conferences/participants.rb +2 -2
  23. data/lib/twilio-ruby/rest/incoming_phone_numbers.rb +1 -1
  24. data/lib/twilio-ruby/rest/instance_resource.rb +9 -5
  25. data/lib/twilio-ruby/rest/list_resource.rb +18 -10
  26. data/lib/twilio-ruby/rest/outgoing_caller_ids.rb +1 -1
  27. data/lib/twilio-ruby/rest/queues/members.rb +1 -1
  28. data/lib/twilio-ruby/rest/sip.rb +1 -3
  29. data/lib/twilio-ruby/rest/utils.rb +11 -3
  30. data/lib/twilio-ruby/util/capability.rb +4 -4
  31. data/lib/twilio-ruby/version.rb +1 -1
  32. data/spec/rack/twilio_webhook_authentication_spec.rb +18 -6
  33. data/spec/rest/account_spec.rb +24 -8
  34. data/spec/rest/call_spec.rb +6 -2
  35. data/spec/rest/client_spec.rb +37 -14
  36. data/spec/rest/conference_spec.rb +3 -1
  37. data/spec/rest/instance_resource_spec.rb +1 -1
  38. data/spec/rest/numbers_spec.rb +18 -6
  39. data/spec/rest/queue_spec.rb +3 -1
  40. data/spec/rest/recording_spec.rb +3 -1
  41. data/spec/util/url_encode_spec.rb +1 -1
  42. metadata +1 -1
@@ -27,9 +27,9 @@ under sip.twilio.com.
27
27
  @client = Twilio::REST::Client.new account_sid, auth_token
28
28
 
29
29
  @domain = @client.sip.domains.create(
30
- {:friendly_name => "The Office Domain",
31
- :voice_url => "http://example.com/voice",
32
- :domain_name => "dunder-mifflin-scranton.sip.twilio.com",}
30
+ friendly_name: "The Office Domain",
31
+ voice_url: "http://example.com/voice"
32
+ domain_name: "dunder-mifflin-scranton.sip.twilio.com"
33
33
  )
34
34
  puts @domain.sid
35
35
 
@@ -51,7 +51,7 @@ to individual ip addresses. To do this, you'll first need to create an
51
51
  @client = Twilio::REST::Client.new account_sid, auth_token
52
52
 
53
53
  @ip_acl = @client.sip.ip_access_control_lists.create(
54
- {:friendly_name => "The Office IpAccessControlList",}
54
+ friendly_name: "The Office IpAccessControlList"
55
55
  )
56
56
  puts @ip_acl.sid
57
57
 
@@ -71,10 +71,10 @@ Now it's time to add an :class:`IpAddress` to your new :class:`IpAccessControlLi
71
71
  @client = Twilio::REST::Client.new account_sid, auth_token
72
72
 
73
73
  @ip_address = @client.sip.ip_access_control_lists.get(
74
- "AL456", # IpAccessControlList sid
74
+ "AL456", # IpAccessControlList sid
75
75
  ).ip_addresses.create(
76
- {:friendly_name => "Dwights's Computer",
77
- :ip_address => "192.168.1.42",}
76
+ friendly_name: "Dwights's Computer",
77
+ ip_address: "192.168.1.42"
78
78
  )
79
79
  puts @ip_address.sid
80
80
 
@@ -97,7 +97,8 @@ associate them. To do this, create an :class:`IpAccessControlListMapping`.
97
97
  @ip_acl_mapping = @client.sip.domains.get(
98
98
  "SD456", # SIP Domain sid
99
99
  ).ip_access_control_list_mappings.create(
100
- {:ip_access_control_list_sid => "AL789"})
100
+ ip_access_control_list_sid: "AL789"
101
+ )
101
102
 
102
103
  puts @ip_acl_mapping.sid
103
104
 
@@ -35,7 +35,7 @@ All attributes are keyword arguments.
35
35
  require 'twilio-ruby'
36
36
 
37
37
  Twilio::TwiML::Response.new do |r|
38
- r.Play "https://api.twilio.com/cowbell.mp3", :loop => 5
38
+ r.Play "https://api.twilio.com/cowbell.mp3", loop: 5
39
39
  end.text
40
40
 
41
41
  .. code-block:: xml
@@ -53,7 +53,7 @@ Any example of nesting nouns in verbs
53
53
 
54
54
  Twilio::TwiML::Response.new do |r|
55
55
  r.Say "hello"
56
- r.Gather :finishOnKey => 4 do |g|
56
+ r.Gather finishOnKey: => 4 do |g|
57
57
  g.Say "world"
58
58
  end
59
59
  end.text
@@ -8,7 +8,7 @@
8
8
  ################ ACCOUNTS ################
9
9
 
10
10
  # shortcut to grab your account object (account_sid is inferred from the client's auth credentials)
11
- @account = @client.account
11
+ @account = @client.account
12
12
 
13
13
  # list your (sub)accounts
14
14
  @client.accounts.list
@@ -19,12 +19,16 @@
19
19
  puts @account.friendly_name
20
20
 
21
21
  # update an account's friendly name
22
- @client.accounts.get(@account_sid).update(:friendly_name => 'A Fabulous Friendly Name')
22
+ @client.accounts.get(@account_sid).update(friendly_name: 'A Fabulous Friendly Name')
23
23
 
24
24
  ################ CALLS ################
25
25
 
26
26
  # print a list of calls (all parameters optional)
27
- @account.calls.list({:page => 0, :page_size => 1000, :start_time => '2010-09-01'}).each do |call|
27
+ @account.calls.list(
28
+ page: 0,
29
+ page_size: 1000,
30
+ start_time: '2010-09-01'
31
+ ).each do |call|
28
32
  puts call.sid
29
33
  end
30
34
 
@@ -34,18 +38,23 @@ end
34
38
  end
35
39
 
36
40
  # make a new outgoing call. returns a call object just like calls.get
37
- @call = @account.calls.create({:from => '+14159341234', :to => '+18004567890', :url => 'http://example.com/call-handler'})
41
+ @call = @account.calls.create(
42
+ from: '+14159341234',
43
+ to: '+18004567890',
44
+ url: 'http://example.com/call-handler'
45
+ )
38
46
 
39
47
  # cancel the call if not already in progress
40
- @account.calls.get(@call.sid).update({:status => 'canceled'})
48
+ @account.calls.get(@call.sid).update(status: 'canceled')
41
49
  # or equivalently
42
- @call.update({:status => 'canceled'})
50
+ @call.update(status: 'canceled')
43
51
  # or simply
44
52
  @call.cancel
45
53
 
46
54
  # redirect and then terminate a call
47
- @account.calls.get('CA386025c9bf5d6052a1d1ea42b4d16662').update({:url => 'http://example.com/call-redirect'})
48
- @account.calls.get('CA386025c9bf5d6052a1d1ea42b4d16662').update({:status => 'completed'})
55
+ @call = @account.calls.get('CA386025c9bf5d6052a1d1ea42b4d16662')
56
+ @call.update(url: 'http://example.com/call-redirect')
57
+ @call.update(status: 'completed')
49
58
  # or, use the aliases...
50
59
  @call.redirect_to('http://example.com/call-redirect')
51
60
  @call.hangup
@@ -53,7 +62,7 @@ end
53
62
  ################ SMS MESSAGES ################
54
63
 
55
64
  # print a list of messages
56
- @account.messages.list({:date_sent => '2010-09-01'}).each do |message|
65
+ @account.messages.list(date_sent: '2010-09-01').each do |message|
57
66
  puts message.body
58
67
  end
59
68
 
@@ -61,10 +70,18 @@ end
61
70
  puts @account.messages.get('SMXXXXXXXX').body
62
71
 
63
72
  # send an sms
64
- @account.messages.create(:from => '+14159341234', :to => '+16105557069', :body => 'Hey there!')
73
+ @account.messages.create(
74
+ from: '+14159341234',
75
+ to: '+16105557069',
76
+ body: 'Hey there!'
77
+ )
65
78
 
66
79
  # send an mms
67
- @account.messages.create(:from => '+14159341234', :to => '+16105557069', :media_urls => 'http://example.com/media.png')
80
+ @account.messages.create(
81
+ from: '+14159341234',
82
+ to: '+16105557069',
83
+ media_urls: 'http://example.com/media.png'
84
+ )
68
85
 
69
86
  ################ PHONE NUMBERS ################
70
87
 
@@ -72,22 +89,28 @@ puts @account.messages.get('SMXXXXXXXX').body
72
89
  @account.available_phone_numbers.list
73
90
 
74
91
  # print some available numbers
75
- @numbers = @account.available_phone_numbers.get('US').local.list({:contains => 'AWESOME'})
76
- @numbers.each {|num| puts num.phone_number}
92
+ @numbers = @account.available_phone_numbers.get('US').local.list(
93
+ contains: 'AWESOME'
94
+ )
95
+ @numbers.each { |num| puts num.phone_number }
77
96
 
78
97
  # buy the first one
79
- @account.incoming_phone_numbers.create(:phone_number => @numbers[0].phone_number)
98
+ @account.incoming_phone_numbers.create(phone_number: @numbers[0].phone_number)
80
99
 
81
100
  # update an existing phone number's voice url
82
- @account.incoming_phone_numbers.get('PNdba508c5616a7f5e141789f44f022cc3').update({:voice_url => 'http://example.com/voice'})
101
+ number = @account.incoming_phone_numbers.get('PNdba508c5616a7f5e141789f44f022cc3')
102
+ number.update(voice_url: 'http://example.com/voice')
83
103
 
84
104
  # decommission an existing phone number
85
- numbers = @account.incoming_phone_numbers.list(:friendly_name => 'A Fabulous Friendly Name')
105
+ numbers = @account.incoming_phone_numbers.list(
106
+ friendly_name: 'A Fabulous Friendly Name'
107
+ )
86
108
  numbers[0].delete
87
109
  ################ CONFERENCES ################
88
110
 
89
111
  # get a particular conference's participants object and stash it
90
- @participants = @account.conferences.get('CFbbe46ff1274e283f7e3ac1df0072ab39').participants
112
+ conference = @account.conferences.get('CFbbe46ff1274e283f7e3ac1df0072ab39')
113
+ @participants = conference.participants
91
114
 
92
115
  # list participants
93
116
  @participants.list.each do |p|
@@ -95,17 +118,18 @@ numbers[0].delete
95
118
  end
96
119
 
97
120
  # update a conference participant
98
- @participants.get('CA386025c9bf5d6052a1d1ea42b4d16662').update({:muted => 'true'})
121
+ @participants.get('CA386025c9bf5d6052a1d1ea42b4d16662').update(muted: 'true')
99
122
  # or an easier way
100
123
  @participants.get('CA386025c9bf5d6052a1d1ea42b4d16662').mute
101
124
 
102
125
  # and, since we're lazy loading, this would only incur one http request
103
- @account.conferences.get('CFbbe46ff1274e283f7e3ac1df0072ab39').participants.get('CA386025c9bf5d6052a1d1ea42b4d16662').update({:muted => 'true'})
126
+ @account.conferences.get('CFbbe46ff1274e283f7e3ac1df0072ab39').participants
127
+ .get('CA386025c9bf5d6052a1d1ea42b4d16662').update(muted: 'true')
104
128
 
105
129
  ################ QUEUES ###################
106
130
 
107
131
  # create a new queue
108
- @queue = @account.queues.create(:friendly_name => 'MyQueue', :max_size => 50)
132
+ @queue = @account.queues.create(friendly_name: 'MyQueue', max_size: 50)
109
133
 
110
134
  # get a list of queues for this account
111
135
  @queues = @account.queues.list
@@ -33,7 +33,11 @@ module Rack
33
33
  if validator.validate(original_url, params, signature)
34
34
  @app.call(env)
35
35
  else
36
- [403, {'Content-Type' => 'text/plain'}, ["Twilio Request Validation Failed."]]
36
+ [
37
+ 403,
38
+ {'Content-Type' => 'text/plain'},
39
+ ["Twilio Request Validation Failed."]
40
+ ]
37
41
  end
38
42
  end
39
43
  end
@@ -7,7 +7,7 @@ module Twilio
7
7
  end
8
8
 
9
9
  def make(from, to, url)
10
- create :from => from, :to => to, :url => url
10
+ create from: from, to: to, url: url
11
11
  end
12
12
  end
13
13
 
@@ -18,15 +18,15 @@ module Twilio
18
18
  end
19
19
 
20
20
  def redirect_to(url)
21
- update :url => url
21
+ update url: url
22
22
  end
23
23
 
24
24
  def cancel
25
- update :status => 'canceled'
25
+ update status: 'canceled'
26
26
  end
27
27
 
28
28
  def hangup
29
- update :status => 'completed'
29
+ update status: 'completed'
30
30
  end
31
31
  end
32
32
  end
@@ -63,21 +63,23 @@ module Twilio
63
63
  HTTP_HEADERS = {
64
64
  'Accept' => 'application/json',
65
65
  'Accept-Charset' => 'utf-8',
66
- 'User-Agent' => "twilio-ruby/#{Twilio::VERSION} (#{engine}/#{RUBY_PLATFORM} #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL})",
66
+ 'User-Agent' => "twilio-ruby/#{Twilio::VERSION}" \
67
+ " (#{engine}/#{RUBY_PLATFORM}" \
68
+ " #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL})"
67
69
  }
68
70
 
69
71
  DEFAULTS = {
70
- :host => 'api.twilio.com',
71
- :port => 443,
72
- :use_ssl => true,
73
- :ssl_verify_peer => true,
74
- :ssl_ca_file => File.dirname(__FILE__) + '/../../../conf/cacert.pem',
75
- :timeout => 30,
76
- :proxy_addr => nil,
77
- :proxy_port => nil,
78
- :proxy_user => nil,
79
- :proxy_pass => nil,
80
- :retry_limit => 1,
72
+ host: 'api.twilio.com',
73
+ port: 443,
74
+ use_ssl: true,
75
+ ssl_verify_peer: true,
76
+ ssl_ca_file: File.dirname(__FILE__) + '/../../../conf/cacert.pem',
77
+ timeout: 30,
78
+ proxy_addr: nil,
79
+ proxy_port: nil,
80
+ proxy_user: nil,
81
+ proxy_pass: nil,
82
+ retry_limit: 1
81
83
  }
82
84
 
83
85
  attr_reader :account_sid, :account, :accounts, :last_request,
@@ -91,36 +93,36 @@ module Twilio
91
93
  # hash of connection configuration options. the following keys are
92
94
  # supported:
93
95
  #
94
- # === <tt>:host => 'api.twilio.com'</tt>
96
+ # === <tt>host: 'api.twilio.com'</tt>
95
97
  #
96
98
  # The domain to which you'd like the client to make HTTP requests. Useful
97
99
  # for testing. Defaults to 'api.twilio.com'.
98
100
  #
99
- # === <tt>:port => 443</tt>
101
+ # === <tt>port: 443</tt>
100
102
  #
101
103
  # The port on which to connect to the above domain. Defaults to 443 and
102
104
  # should be left that way except in testing environments.
103
105
  #
104
- # === <tt>:use_ssl => true</tt>
106
+ # === <tt>use_ssl: true</tt>
105
107
  #
106
108
  # Declare whether ssl should be used for connections to the above domain.
107
109
  # Defaults to true and should be left alone except when testing.
108
110
  #
109
- # === <tt>:ssl_verify_peer => true</tt>
111
+ # === <tt>ssl_verify_peer: true</tt>
110
112
  #
111
113
  # Declare whether to verify the host's ssl cert when setting up the
112
114
  # connection to the above domain. Defaults to true, but can be turned off
113
115
  # to avoid ssl certificate verification failures in environments without
114
116
  # the necessary ca certificates.
115
117
  #
116
- # === <tt>:ssl_ca_file => '/path/to/ca/file'</tt>
118
+ # === <tt>ssl_ca_file: '/path/to/ca/file'</tt>
117
119
  #
118
120
  # Specify the path to the certificate authority bundle you'd like to use
119
121
  # to verify Twilio's SSL certificate on each request. If not specified, a
120
122
  # certificate bundle extraced from Firefox is packaged with the gem and
121
123
  # used by default.
122
124
  #
123
- # === <tt>:timeout => 30</tt>
125
+ # === <tt>timeout: 30</tt>
124
126
  #
125
127
  # Set the time in seconds to wait before timing out the HTTP request.
126
128
  # Defaults to 30 seconds. If you aren't fetching giant pages of call or
@@ -128,24 +130,24 @@ module Twilio
128
130
  # lower. In paricular if you are sending SMS you can set this to 1 second
129
131
  # or less and swallow the exception if you don't care about the response.
130
132
  #
131
- # === <tt>:proxy_addr => 'proxy.host.domain'</tt>
133
+ # === <tt>proxy_addr: 'proxy.host.domain'</tt>
132
134
  #
133
135
  # The domain of a proxy through which you'd like the client to make HTTP
134
136
  # requests. Defaults to nil.
135
137
  #
136
- # === <tt>:proxy_port => 3128</tt>
138
+ # === <tt>proxy_port: 3128</tt>
137
139
  #
138
140
  # The port on which to connect to the above proxy. Defaults to nil.
139
141
  #
140
- # === <tt>:proxy_user => 'username'</tt>
142
+ # === <tt>proxy_user: 'username'</tt>
141
143
  #
142
144
  # The user name to use for authentication with the proxy. Defaults to nil.
143
145
  #
144
- # === <tt>:proxy_pass => 'password'</tt>
146
+ # === <tt>proxy_pass: 'password'</tt>
145
147
  #
146
148
  # The password to use for authentication with the proxy. Defaults to nil.
147
149
  #
148
- # === <tt>:retry_limit => 1</tt>
150
+ # === <tt>retry_limit: 1</tt>
149
151
  #
150
152
  # The number of times to retry a request that has failed before throwing
151
153
  # an exception. Defaults to one.
@@ -10,11 +10,11 @@ module Twilio
10
10
 
11
11
  class Participant < InstanceResource
12
12
  def mute
13
- update :muted => 'true'
13
+ update muted: 'true'
14
14
  end
15
15
 
16
16
  def unmute
17
- update :muted => 'false'
17
+ update muted: 'false'
18
18
  end
19
19
 
20
20
  alias :kick :delete
@@ -8,7 +8,7 @@ module Twilio
8
8
  end
9
9
 
10
10
  def buy(phone_number)
11
- create :phone_number => phone_number
11
+ create phone_number: phone_number
12
12
  end
13
13
  end
14
14
 
@@ -32,7 +32,7 @@ module Twilio
32
32
  # to handle the update. For example, to update the +VoiceUrl+ of a Twilio
33
33
  # Application you could write:
34
34
  #
35
- # @app.update :voice_url => 'http://my.other.app.com/handle_voice'
35
+ # @app.update voice_url: 'http://my.other.app.com/handle_voice'
36
36
  #
37
37
  # After returning, the object will contain the most recent state of the
38
38
  # instance resource, including the newly updated properties.
@@ -77,23 +77,27 @@ module Twilio
77
77
  hash.each do |p,v|
78
78
  property = detwilify p
79
79
  unless ['client', 'updated'].include? property
80
- eigenclass.send :define_method, property.to_sym, &lambda {v}
80
+ eigenclass.send :define_method, property.to_sym, &lambda { v }
81
81
  end
82
82
  end
83
83
  @updated = !hash.keys.empty?
84
84
  end
85
85
 
86
86
  def resource(*resources)
87
- custom_resource_names = {:sms => 'SMS', :sip => 'SIP'}
87
+ custom_resource_names = { sms: 'SMS', sip: 'SIP' }
88
88
  resources.each do |r|
89
89
  resource = twilify r
90
90
  relative_path = custom_resource_names.fetch(r, resource)
91
91
  path = "#{@path}/#{relative_path}"
92
- enclosing_module = @submodule == nil ? (Twilio::REST) : (Twilio::REST.const_get(@submodule))
92
+ enclosing_module = if @submodule == nil
93
+ Twilio::REST
94
+ else
95
+ Twilio::REST.const_get(@submodule)
96
+ end
93
97
  resource_class = enclosing_module.const_get resource
94
98
  instance_variable_set("@#{r}", resource_class.new(path, @client))
95
99
  end
96
- self.class.instance_eval {attr_reader *resources}
100
+ self.class.instance_eval { attr_reader *resources }
97
101
  end
98
102
 
99
103
  end
@@ -5,9 +5,9 @@ module Twilio
5
5
 
6
6
  def initialize(path, client)
7
7
  custom_names = {
8
- 'Media' => 'MediaInstance',
9
- 'IpAddresses' => 'IpAddress',
10
- 'Feedback' => 'FeedbackInstance',
8
+ 'Media' => 'MediaInstance',
9
+ 'IpAddresses' => 'IpAddress',
10
+ 'Feedback' => 'FeedbackInstance'
11
11
  }
12
12
  @path, @client = path, client
13
13
  resource_name = self.class.name.split('::')[-1]
@@ -16,7 +16,11 @@ module Twilio
16
16
  # The next line grabs the enclosing module. Necessary for resources
17
17
  # contained in their own submodule like /SMS/Messages
18
18
  parent_module = self.class.to_s.split('::')[-2]
19
- full_module_path = parent_module == 'REST' ? (Twilio::REST) : (Twilio::REST.const_get parent_module)
19
+ full_module_path = if parent_module == "REST"
20
+ Twilio::REST
21
+ else
22
+ Twilio::REST.const_get parent_module
23
+ end
20
24
 
21
25
  @instance_class = full_module_path.const_get instance_name
22
26
  @list_key, @instance_id_key = detwilify(resource_name), 'sid'
@@ -49,7 +53,7 @@ module Twilio
49
53
  client, list_class = @client, self.class
50
54
  resource_list.instance_eval do
51
55
  eigenclass = class << self; self; end
52
- eigenclass.send :define_method, :total, &lambda {response['total']}
56
+ eigenclass.send :define_method, :total, &lambda { response['total'] }
53
57
  eigenclass.send :define_method, :next_page, &lambda {
54
58
  if response['next_page_uri']
55
59
  list_class.new(response['next_page_uri'], client).list({}, true)
@@ -70,7 +74,7 @@ module Twilio
70
74
  # +total+ attribute as well.
71
75
  def total
72
76
  raise "Can't get a resource total without a REST Client" unless @client
73
- @client.get(@path, :page_size => 1)['total']
77
+ @client.get(@path, page_size: 1)['total']
74
78
  end
75
79
 
76
80
  ##
@@ -98,18 +102,22 @@ module Twilio
98
102
 
99
103
  def resource(*resources)
100
104
  custom_resource_names = {
101
- :sms => 'SMS',
102
- :sip => 'SIP',
105
+ sms: 'SMS',
106
+ sip: 'SIP'
103
107
  }
104
108
  resources.each do |r|
105
109
  resource = twilify r
106
110
  relative_path = custom_resource_names.fetch(r, resource)
107
111
  path = "#{@path}/#{relative_path}"
108
- enclosing_module = @submodule == nil ? (Twilio::REST) : (Twilio::REST.const_get(@submodule))
112
+ enclosing_module = if @submodule == nil
113
+ Twilio::REST
114
+ else
115
+ Twilio::REST.const_get(@submodule)
116
+ end
109
117
  resource_class = enclosing_module.const_get resource
110
118
  instance_variable_set("@#{r}", resource_class.new(path, @client))
111
119
  end
112
- self.class.instance_eval {attr_reader *resources}
120
+ self.class.instance_eval { attr_reader *resources }
113
121
  end
114
122
  end
115
123
  end