twilio-rb 0.2.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +34 -0
- data/lib/twilio/account.rb +20 -0
- data/lib/twilio/call.rb +22 -0
- data/lib/twilio/resource.rb +24 -34
- data/lib/twilio/sms.rb +4 -0
- metadata +5 -4
data/README.md
CHANGED
@@ -3,6 +3,18 @@
|
|
3
3
|
|
4
4
|
Interact with the Twilio API in a nice Ruby way
|
5
5
|
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
The library has been packaged as a gem and is available from rubygems.org
|
9
|
+
|
10
|
+
<pre>gem install twilio-rb</pre>
|
11
|
+
|
12
|
+
## Usage
|
13
|
+
|
14
|
+
Require the library in your script as
|
15
|
+
|
16
|
+
<pre>require 'twilio'</pre>
|
17
|
+
|
6
18
|
## Configuration
|
7
19
|
|
8
20
|
Configuration for this library is encapsulated within `Twilio::Config`. One needs to setup with an Account SID and an Auth Token, e.g.
|
@@ -15,6 +27,28 @@ end</pre>
|
|
15
27
|
|
16
28
|
Any method that calls the Twilio API will raise `Twilio::ConfigurationError` if either Account SID or Auth Token are not configured.
|
17
29
|
|
30
|
+
## The Account object
|
31
|
+
|
32
|
+
The Twilio API in its current incarnation supports one Twilio account per Account SID, and so the Twilio::Account object correspondingly is a singleton object.
|
33
|
+
|
34
|
+
To access properties of the account the property name should be called as a method on the object itself, e.g.
|
35
|
+
|
36
|
+
<pre>Twilio::Account.friendly_name</pre>
|
37
|
+
|
38
|
+
The first time a method is invoked on the object an API call is made to retrieve the data. The methods themselves are not defined until they are called, i.e. lazy evaluation. This strategy means that addtional properties added to subsequent versions of the API should not break the library.
|
39
|
+
|
40
|
+
To reload the data when needed `Twilio::Account.reload!` will make another API call and update its own internal state.
|
41
|
+
|
42
|
+
Predicate methods i.e. those ending in `?` map directly to the status of the account, e.g. `Twilio::Account.suspended?` returns true if Twilio have suspended your account. Again, all of these methods are defined on the fly.
|
43
|
+
|
44
|
+
The only account property that can be modified via the REST API is the friendly name, e.g.
|
45
|
+
|
46
|
+
<pre>Twilio::Account.friendly_name = "I'm so vain, I had to change my name!"</pre>
|
47
|
+
|
48
|
+
This will update the API immediately with a PUT request.
|
49
|
+
|
50
|
+
Please refer to the Twilio REST API documentation for an up to date list of properties.
|
51
|
+
|
18
52
|
## Making a telephone call
|
19
53
|
|
20
54
|
The API used to make a telephone call is similar to interacting with an ActiveRecord model object.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Twilio
|
2
|
+
module Account
|
3
|
+
include Twilio::Resource
|
4
|
+
@attributes = {}
|
5
|
+
|
6
|
+
def attributes
|
7
|
+
@attributes.empty? ? reload! : @attributes
|
8
|
+
end
|
9
|
+
|
10
|
+
def reload!
|
11
|
+
handle_response get "/Accounts/#{Twilio::ACCOUNT_SID}.json"
|
12
|
+
end
|
13
|
+
|
14
|
+
def friendly_name=(name)
|
15
|
+
handle_response put "/Accounts/#{Twilio::ACCOUNT_SID}.json", :body => { :friendly_name => name }
|
16
|
+
end
|
17
|
+
|
18
|
+
extend self
|
19
|
+
end
|
20
|
+
end
|
data/lib/twilio/call.rb
CHANGED
@@ -2,6 +2,13 @@ module Twilio
|
|
2
2
|
class Call
|
3
3
|
include Twilio::Resource
|
4
4
|
|
5
|
+
def initialize(attrs ={}) #:nodoc:
|
6
|
+
@attributes = Hash[attrs.map { |k,v| [k.to_s.camelize, v.to_s] }]
|
7
|
+
normalize_http_verbs!
|
8
|
+
escape_send_digits! if attributes.include? 'SendDigits'
|
9
|
+
normalize_if_machine_parameter!
|
10
|
+
end
|
11
|
+
|
5
12
|
# Dials the call
|
6
13
|
def save
|
7
14
|
handle_response self.class.post "/Accounts/#{Twilio::ACCOUNT_SID}/Calls.json", :body => attributes
|
@@ -25,6 +32,21 @@ module Twilio
|
|
25
32
|
|
26
33
|
private
|
27
34
|
|
35
|
+
def normalize_http_verbs! #:nodoc:
|
36
|
+
# Twilio accepts a HTTP method for use with various callbacks. The API documentation
|
37
|
+
# indicates that the HTTP verbs are to be passed as upcase.
|
38
|
+
attributes.each { |k,v| v.upcase! if k =~ /Method$/ }
|
39
|
+
end
|
40
|
+
|
41
|
+
def escape_send_digits! #:nodoc:
|
42
|
+
# A pound, i.e. "#" has special meaning in a URL so it must be escaped
|
43
|
+
attributes.update 'SendDigits' => CGI.escape(attributes['SendDigits'])
|
44
|
+
end
|
45
|
+
|
46
|
+
def normalize_if_machine_parameter! #:nodoc:
|
47
|
+
attributes['IfMachine'].capitalize! if attributes['IfMachine']
|
48
|
+
end
|
49
|
+
|
28
50
|
def state_guard(&blk)
|
29
51
|
if self[:status] # If this attribute exists it is assumed the API call to create a call has been made, and the object is in the correct state to make request.
|
30
52
|
blk.call
|
data/lib/twilio/resource.rb
CHANGED
@@ -2,13 +2,6 @@ require 'active_support/core_ext/string/inflections' # Chill! we only use the bi
|
|
2
2
|
|
3
3
|
module Twilio
|
4
4
|
module Resource
|
5
|
-
def initialize(attrs ={}) #:nodoc:
|
6
|
-
@attributes = Hash[attrs.map { |k,v| [k.to_s.camelize, v.to_s] }]
|
7
|
-
normalize_http_verbs!
|
8
|
-
escape_send_digits! if attributes.include? 'SendDigits'
|
9
|
-
normalize_if_machine_parameter!
|
10
|
-
end
|
11
|
-
|
12
5
|
# Convenience for accessing attributes. Attributes can be accessed either using the
|
13
6
|
# preferred symbol style, e.g. :if_machine or using the Twilio stringified attribute
|
14
7
|
# style, e.g. 'IfMachine'
|
@@ -29,31 +22,19 @@ module Twilio
|
|
29
22
|
if res.code.to_s =~ /^(4|5)\d\d/
|
30
23
|
raise Twilio::APIError.new "Error ##{res.parsed_response['code']}: #{res.parsed_response['message']}"
|
31
24
|
else
|
32
|
-
attributes.update Hash[res.parsed_response.map { |k,v| [k.camelize, v] }] # params are camelized in requests, yet underscored in the repsonse. inconsistency FTW!
|
25
|
+
@attributes.update Hash[res.parsed_response.map { |k,v| [k.camelize, v] }] # params are camelized in requests, yet underscored in the repsonse. inconsistency FTW!
|
33
26
|
end
|
34
27
|
end
|
35
28
|
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
attributes.each { |k,v| v.upcase! if k =~ /Method$/ }
|
40
|
-
end
|
41
|
-
|
42
|
-
def escape_send_digits! #:nodoc:
|
43
|
-
# A pound, i.e. "#" has special meaning in a URL so it must be escaped
|
44
|
-
attributes.update 'SendDigits' => CGI.escape(attributes['SendDigits'])
|
45
|
-
end
|
46
|
-
|
47
|
-
def normalize_if_machine_parameter! #:nodoc:
|
48
|
-
attributes['IfMachine'].capitalize! if attributes['IfMachine']
|
49
|
-
end
|
50
|
-
|
51
|
-
def method_missing(meth, *args, &blk) #:nodoc
|
52
|
-
meth = meth.to_s.camelize
|
53
|
-
if meth.to_s =~ /\=$/
|
29
|
+
def method_missing(id, *args, &blk) #:nodoc
|
30
|
+
meth = id.to_s
|
31
|
+
if meth =~ /\=$/
|
54
32
|
add_attr_writer meth
|
55
33
|
send meth, args.first
|
56
|
-
elsif
|
34
|
+
elsif meth =~ /^#{meth}\?/i
|
35
|
+
add_predicate meth
|
36
|
+
send meth
|
37
|
+
elsif self[id]
|
57
38
|
add_attr_reader meth
|
58
39
|
send meth
|
59
40
|
else
|
@@ -61,16 +42,21 @@ module Twilio
|
|
61
42
|
end
|
62
43
|
end
|
63
44
|
|
45
|
+
def add_predicate(attribute)
|
46
|
+
metaclass.class_eval do
|
47
|
+
define_method(attribute) { self[:status] =~ /^#{attribute.gsub '?', ''}/i ? true : false }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
64
51
|
def add_attr_writer(attribute) #:nodoc
|
65
52
|
metaclass.class_eval do
|
66
|
-
attribute
|
67
|
-
define_method("#{attribute}=") { |value| attributes[attribute] = value } unless respond_to? "#{attribute}="
|
53
|
+
define_method(attribute) { |value| self[attribute.to_s.gsub(/\=$/, '').to_sym] = value } unless respond_to? attribute
|
68
54
|
end
|
69
55
|
end
|
70
56
|
|
71
57
|
def add_attr_reader(attribute) #:nodoc
|
72
58
|
metaclass.class_eval do
|
73
|
-
define_method(attribute) {
|
59
|
+
define_method(attribute) { self[attribute.to_sym] } unless respond_to? attribute
|
74
60
|
end
|
75
61
|
end
|
76
62
|
|
@@ -89,10 +75,14 @@ module Twilio
|
|
89
75
|
class << base
|
90
76
|
def create(attrs={})
|
91
77
|
new(attrs).tap { |c| c.save }
|
92
|
-
end
|
93
|
-
|
94
|
-
|
95
|
-
|
78
|
+
end if instance_of? Class # Don't want this mixed into singleton objects e.g. Twilio::Account
|
79
|
+
|
80
|
+
# decorate http methods with authentication
|
81
|
+
%w<post get put delete>.each do |meth|
|
82
|
+
define_method(meth) do |*args| # splatted args necessary hack since <= 1.8.7 does not support optional block args
|
83
|
+
opts = args[1] || {}
|
84
|
+
super args.first, opts.merge(:basic_auth => { :username => Twilio::ACCOUNT_SID, :password => Twilio::AUTH_TOKEN })
|
85
|
+
end
|
96
86
|
end
|
97
87
|
end
|
98
88
|
end
|
data/lib/twilio/sms.rb
CHANGED
@@ -2,6 +2,10 @@ module Twilio
|
|
2
2
|
class SMS
|
3
3
|
include Twilio::Resource
|
4
4
|
|
5
|
+
def initialize(attrs ={}) #:nodoc:
|
6
|
+
@attributes = Hash[attrs.map { |k,v| [k.to_s.camelize, v.to_s] }]
|
7
|
+
end
|
8
|
+
|
5
9
|
# Sends the SMS message
|
6
10
|
def save
|
7
11
|
handle_response self.class.post "/Accounts/#{Twilio::ACCOUNT_SID}/SMS/Messages.json", :body => attributes
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 3
|
8
|
+
- 1
|
9
|
+
version: 0.3.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Stevie Graham
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-09-
|
17
|
+
date: 2010-09-30 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -102,6 +102,7 @@ extra_rdoc_files: []
|
|
102
102
|
|
103
103
|
files:
|
104
104
|
- README.md
|
105
|
+
- lib/twilio/account.rb
|
105
106
|
- lib/twilio/call.rb
|
106
107
|
- lib/twilio/config.rb
|
107
108
|
- lib/twilio/resource.rb
|