twilio_resource 0.1.0
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/README.md +78 -0
- data/lib/twilio_resource.rb +27 -0
- data/lib/twilio_resource/account.rb +6 -0
- data/lib/twilio_resource/base.rb +83 -0
- data/lib/twilio_resource/call.rb +20 -0
- data/lib/twilio_resource/exceptions.rb +39 -0
- data/lib/twilio_resource/incoming_phone_number.rb +6 -0
- data/lib/twilio_resource/local_incoming_phone_number.rb +14 -0
- data/lib/twilio_resource/toll_free_incoming_phone_number.rb +14 -0
- data/lib/twilio_resource/twilio_format.rb +56 -0
- data/test/account_test.rb +17 -0
- data/test/call_test.rb +33 -0
- data/test/incoming_phone_number_test.rb +20 -0
- data/test/local_incoming_phone_number_test.rb +39 -0
- data/test/test_helper.rb +7 -0
- data/test/toll_free_incoming_phone_number_test.rb +25 -0
- data/test/twilio_mock.rb +334 -0
- metadata +95 -0
data/README.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
Description
|
|
2
|
+
-----------
|
|
3
|
+
|
|
4
|
+
TwilioResource is a wrapper around the [Twilio API](http://www.twilio.com/docs/api/2008-08-01/rest/)
|
|
5
|
+
using Rails' ActiveResource. This allows you to treat Twilio objects
|
|
6
|
+
as if they're local ActiveRecord models:
|
|
7
|
+
|
|
8
|
+
phone = TwilioResource::LocalIncomingPhoneNumber.new(:url => 'http://www.example.com',
|
|
9
|
+
:area_code => '206',
|
|
10
|
+
:method => 'GET',
|
|
11
|
+
:friendly_name =g> "My First Phone Number",
|
|
12
|
+
:account_id => Twilio::Base.user)
|
|
13
|
+
phone.save
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
The wrapper doesn't support the entire Twilio API, but it should be
|
|
17
|
+
simple enough to add new functionality as needed by following the
|
|
18
|
+
models that are already built.
|
|
19
|
+
|
|
20
|
+
Supported Functionality
|
|
21
|
+
=======================
|
|
22
|
+
- Requesting, listing, and deleting new local and toll-free numbers
|
|
23
|
+
- Placing and listing calls made to a phone number
|
|
24
|
+
|
|
25
|
+
Todo
|
|
26
|
+
----
|
|
27
|
+
- Conference resource
|
|
28
|
+
- Redirecting calls
|
|
29
|
+
- Support data returned in xml attributes
|
|
30
|
+
- SMS resource
|
|
31
|
+
- Recordings, Transcriptions, and Notifications
|
|
32
|
+
- Wrap more exceptions
|
|
33
|
+
- Add documentation on supported attributes to the ActiveResource models
|
|
34
|
+
|
|
35
|
+
Setup
|
|
36
|
+
=====
|
|
37
|
+
|
|
38
|
+
Before you start using TwilioResource, you have to give it your Twilio
|
|
39
|
+
login credentials. You can do this in your Rails initializer:
|
|
40
|
+
|
|
41
|
+
require 'twilio_resource'
|
|
42
|
+
TwilioResource.setup('token', 'sid')
|
|
43
|
+
|
|
44
|
+
Examples
|
|
45
|
+
========
|
|
46
|
+
|
|
47
|
+
Requesting a new phone number:
|
|
48
|
+
|
|
49
|
+
phone = TwilioResource::LocalIncomingPhoneNumber.new(:url => 'http://www.example.com',
|
|
50
|
+
:area_code => '206',
|
|
51
|
+
:method => 'GET',
|
|
52
|
+
:friendly_name => "My First Phone Number",
|
|
53
|
+
:account_id => Twilio::Base.user)
|
|
54
|
+
phone.save
|
|
55
|
+
|
|
56
|
+
Requesting a new toll-free phone number:
|
|
57
|
+
|
|
58
|
+
phone = TwilioResource::TollFreeIncomingPhoneNumber.new(:url => 'http://www.example.com',
|
|
59
|
+
:area_code => '206',
|
|
60
|
+
:method => 'GET',
|
|
61
|
+
:friendly_name => "My First Phone Number",
|
|
62
|
+
:account_id => Twilio::Base.user)
|
|
63
|
+
phone.save
|
|
64
|
+
|
|
65
|
+
Retrieving a list of completed calls to a given phone number:
|
|
66
|
+
|
|
67
|
+
TwilioResource::Call.find(:all, :params => {
|
|
68
|
+
:account_id => Twilio::Base.user,
|
|
69
|
+
:status => Twilio::Call::COMPLETE,
|
|
70
|
+
:called => '2065551212'})
|
|
71
|
+
|
|
72
|
+
Placing a call:
|
|
73
|
+
|
|
74
|
+
TwilioResource::Call.new({
|
|
75
|
+
:account_id => Twilio::Base.user,
|
|
76
|
+
:caller => '2065551111',
|
|
77
|
+
:called => '2065551212',
|
|
78
|
+
:url => 'http://example.com/call.xml'})
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'logger'
|
|
2
|
+
require 'activeresource'
|
|
3
|
+
|
|
4
|
+
require 'twilio_resource/twilio_format'
|
|
5
|
+
require 'twilio_resource/exceptions'
|
|
6
|
+
|
|
7
|
+
module TwilioResource
|
|
8
|
+
|
|
9
|
+
class << self
|
|
10
|
+
attr_accessor :logger
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Sets up the credentials the ActiveResources will use to access the
|
|
14
|
+
# twilio API. Optionally takes a +logger+, which defaults to +STDOUT+.
|
|
15
|
+
def self.setup(sid, token, logger = nil)
|
|
16
|
+
@logger = logger || Logger.new(STDOUT)
|
|
17
|
+
TwilioResource::Base.sid = sid
|
|
18
|
+
TwilioResource::Base.token = token
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
require 'twilio_resource/base'
|
|
23
|
+
require 'twilio_resource/account'
|
|
24
|
+
require 'twilio_resource/call'
|
|
25
|
+
require 'twilio_resource/incoming_phone_number'
|
|
26
|
+
require 'twilio_resource/local_incoming_phone_number'
|
|
27
|
+
require 'twilio_resource/toll_free_incoming_phone_number'
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Encapsulates the changes that need to be made to active_resource's
|
|
2
|
+
# defaults in order to communicate with Twilio. There are a few main
|
|
3
|
+
# issues with ActiveResource's defaults:
|
|
4
|
+
#
|
|
5
|
+
# 1. Twilio's urls don't take an extension. ActiveResource requires
|
|
6
|
+
# endpoints to have an extension corresponding to the type of data,
|
|
7
|
+
# for example: +resource.xml+ or +resource.json+. Twilio's are
|
|
8
|
+
# always xml, but have no extension.
|
|
9
|
+
#
|
|
10
|
+
# 2. Twilio uses capitalized names in their URLs. For instance,
|
|
11
|
+
# instead of '/account/1/calls/1', they use '/Account/1/Calls/1'.
|
|
12
|
+
#
|
|
13
|
+
# 3. Twilio takes form encoded params, like token=blah&sid=foo, but
|
|
14
|
+
# returns data in XML. These changes are encapsulated in
|
|
15
|
+
# ActiveResource::Formats::TwilioFormat.
|
|
16
|
+
#
|
|
17
|
+
# All of the Twilio ActiveResource classes inherit from this class.
|
|
18
|
+
class TwilioResource::Base < ActiveResource::Base
|
|
19
|
+
|
|
20
|
+
class << self
|
|
21
|
+
attr_accessor :sid
|
|
22
|
+
attr_accessor :token
|
|
23
|
+
|
|
24
|
+
alias_method :user, :sid
|
|
25
|
+
alias_method :user=, :sid=
|
|
26
|
+
alias_method :password, :token
|
|
27
|
+
alias_method :password=, :token=
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Have to override this to make empty extensions work (without the dot)
|
|
31
|
+
def self.element_path(id, prefix_options = {}, query_options = nil)
|
|
32
|
+
prefix_options, query_options = split_options(prefix_options) if query_options.nil?
|
|
33
|
+
extension = format.extension.blank? ? "" : ".#{format.extension}"
|
|
34
|
+
path = "#{prefix(prefix_options)}#{collection_name}/#{id}#{extension}#{query_string(query_options)}"
|
|
35
|
+
TwilioResource.logger.info("Request: #{path}")
|
|
36
|
+
path
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Have to override this to make empty extensions work (without the dot)
|
|
40
|
+
def self.collection_path(prefix_options = {}, query_options = nil)
|
|
41
|
+
prefix_options, query_options = split_options(prefix_options) if query_options.nil?
|
|
42
|
+
extension = format.extension.blank? ? "" : ".#{format.extension}"
|
|
43
|
+
path = "#{prefix(prefix_options)}#{collection_name}#{extension}#{query_string(query_options)}"
|
|
44
|
+
TwilioResource.logger.info("Request: #{path}")
|
|
45
|
+
path
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Have to override this to make empty extensions work (without the dot)
|
|
49
|
+
def self.custom_method_collection_url(method_name, options = {})
|
|
50
|
+
prefix_options, query_options = split_options(options)
|
|
51
|
+
extension = format.extension.blank? ? "" : ".#{format.extension}"
|
|
52
|
+
path = "#{prefix(prefix_options)}#{collection_name}/#{method_name}#{extension}#{query_string(query_options)}"
|
|
53
|
+
TwilioResource.logger.info("Request: #{path}")
|
|
54
|
+
path
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Twilio uses capitalized path names
|
|
58
|
+
def self.element_name
|
|
59
|
+
super.camelize
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def self.query_string(params)
|
|
63
|
+
# camelize all the param keys, because that's what Twilio expects
|
|
64
|
+
fixed_params_list = params.map {|k, v| [k.to_s.camelize, v]}.flatten
|
|
65
|
+
fixed_params_hash = Hash[*fixed_params_list] # Hash really needs a decent #map
|
|
66
|
+
super(fixed_params_hash)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# we should wrap the exceptions we can
|
|
70
|
+
def save(*params)
|
|
71
|
+
begin
|
|
72
|
+
super(*params)
|
|
73
|
+
rescue => e
|
|
74
|
+
raise TwilioResource::Exception.find_exception(e)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
self.site = "https://api.twilio.com"
|
|
81
|
+
self.prefix = '/2008-08-01/'
|
|
82
|
+
self.format = :twilio
|
|
83
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
|
|
2
|
+
# Encapsulates a Twilio call resource. Documentation:
|
|
3
|
+
# - http://www.twilio.com/docs/api/2008-08-01/rest/call
|
|
4
|
+
# - http://www.twilio.com/docs/api/2008-08-01/rest/making_calls
|
|
5
|
+
class TwilioResource::Call < TwilioResource::Base
|
|
6
|
+
self.prefix = superclass.prefix_source + 'Accounts/:account_id/'
|
|
7
|
+
|
|
8
|
+
NOT_DIALED = 0
|
|
9
|
+
IN_PROGRESS = 1
|
|
10
|
+
COMPLETE = 2
|
|
11
|
+
|
|
12
|
+
# Returns the status of the call. Can be
|
|
13
|
+
# TwilioResource::Call::NOT_DIALED,
|
|
14
|
+
# TwilioResource::Call::IN_PROGRESS, or
|
|
15
|
+
# TwilioResource::Call::COMPLETE
|
|
16
|
+
def status
|
|
17
|
+
attributes["status"].to_i if attributes["status"]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module TwilioResource
|
|
2
|
+
end
|
|
3
|
+
|
|
4
|
+
# Wraps Twilio exceptions with a ruby exception class. Currently supports:
|
|
5
|
+
#
|
|
6
|
+
# - Error 21452 - No Phone Numbers Found
|
|
7
|
+
class TwilioResource::Exception < StandardError
|
|
8
|
+
|
|
9
|
+
# Given a twilio error xml response, returns the corresponding
|
|
10
|
+
# exception if it is mapped, or the xml response otherwise.
|
|
11
|
+
def self.find_exception(e)
|
|
12
|
+
new_exception = if e.respond_to?(:response)
|
|
13
|
+
exception_data = Hash.from_xml(e.response.body)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
code = exception_data['twilio_response'] &&
|
|
17
|
+
exception_data['twilio_response']['rest_exception'] &&
|
|
18
|
+
exception_data['twilio_response']['rest_exception']['code']
|
|
19
|
+
exception_klass = twilio_exceptions[code.to_i] if code
|
|
20
|
+
exception_klass.nil? ? e : exception_klass.new
|
|
21
|
+
else
|
|
22
|
+
e
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Hash mapping error codes to exception classes.
|
|
27
|
+
def self.twilio_exceptions
|
|
28
|
+
{
|
|
29
|
+
21452 => TwilioResource::NoPhoneNumbersFoundException,
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class TwilioResource::NoPhoneNumbersFoundException < TwilioResource::Exception
|
|
36
|
+
def message
|
|
37
|
+
"No phone numbers found"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Represents a Twilio-controlled phone number that can receive
|
|
2
|
+
# incoming phone calls. Documentation is at
|
|
3
|
+
# http://www.twilio.com/docs/api/2008-08-01/rest/incoming-phone-numbers
|
|
4
|
+
class TwilioResource::IncomingPhoneNumber < TwilioResource::Base
|
|
5
|
+
self.prefix = superclass.prefix_source + 'Accounts/:account_id/'
|
|
6
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Represents a Twilio-controlled "local" phone number that can receive
|
|
2
|
+
# incoming phone calls. If there are no numbers available in the
|
|
3
|
+
# specified area code, #save will throw a
|
|
4
|
+
# TwilioResource::NoPhoneNumbersFoundException. Documentation is at
|
|
5
|
+
# http://www.twilio.com/docs/api/2008-08-01/rest/incoming-phone-numbers
|
|
6
|
+
class TwilioResource::LocalIncomingPhoneNumber < TwilioResource::IncomingPhoneNumber
|
|
7
|
+
|
|
8
|
+
self.prefix = superclass.prefix_source + 'IncomingPhoneNumbers/'
|
|
9
|
+
|
|
10
|
+
def self.collection_name
|
|
11
|
+
'Local'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Represents a Twilio-controlled toll-free phone number that can receive
|
|
2
|
+
# incoming phone calls. If there are no numbers available in the
|
|
3
|
+
# specified area code, #save will throw a
|
|
4
|
+
# TwilioResource::NoPhoneNumbersFoundException. Documentation is at
|
|
5
|
+
# http://www.twilio.com/docs/api/2008-08-01/rest/incoming-phone-numbers
|
|
6
|
+
class TwilioResource::TollFreeIncomingPhoneNumber < TwilioResource::IncomingPhoneNumber
|
|
7
|
+
|
|
8
|
+
self.prefix = superclass.prefix_source + 'IncomingPhoneNumbers/'
|
|
9
|
+
|
|
10
|
+
def self.collection_name
|
|
11
|
+
'TollFree'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module ActiveResource
|
|
2
|
+
module Formats
|
|
3
|
+
module TwilioFormat
|
|
4
|
+
extend self
|
|
5
|
+
|
|
6
|
+
def extension
|
|
7
|
+
""
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def mime_type
|
|
11
|
+
'application/x-www-form-urlencoded'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# twilio uses camelcase for all of its params, and uses a query string for posts.
|
|
15
|
+
def encode(hash, options = {})
|
|
16
|
+
camelized_hash = ActiveSupport::OrderedHash.new
|
|
17
|
+
hash.each do |k, v|
|
|
18
|
+
camelized_hash[k.camelize] = v
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
TwilioResource.logger.info("Request: #{camelized_hash.to_query}")
|
|
22
|
+
camelized_hash.to_query
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def decode(xml)
|
|
26
|
+
TwilioResource.logger.debug("Response: #{xml}")
|
|
27
|
+
from_xml_data(Hash.from_xml(xml))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
# Manipulate from_xml Hash, because twilio doesn't format their
|
|
32
|
+
# xml in the way active_resource expects it.
|
|
33
|
+
def from_xml_data(data)
|
|
34
|
+
if data.is_a?(Hash) && data['twilio_response']
|
|
35
|
+
from_xml_data(data['twilio_response'])
|
|
36
|
+
else
|
|
37
|
+
data.each do |k, v|
|
|
38
|
+
# convert array-like things to actual arrays. twilio
|
|
39
|
+
# paginates their arrays, so it's easy to detect here. If
|
|
40
|
+
# it's the empty set, initialize it to an array so
|
|
41
|
+
# active_resource doesn't throw a fit.
|
|
42
|
+
if v["page"]
|
|
43
|
+
array_data = v[k.singularize]
|
|
44
|
+
data[k] = [array_data].flatten.compact
|
|
45
|
+
elsif v.blank?
|
|
46
|
+
data[k] = []
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
# now we have "calls" => [c1, c2, ...], but active_resource
|
|
50
|
+
# expects [c1, c2, c3]
|
|
51
|
+
data.values.first
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'twilio_mock'
|
|
3
|
+
|
|
4
|
+
class TwilioResource::AccountTest < Test::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
super
|
|
8
|
+
TwilioMock.setup_remote_fixtures
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_find_account
|
|
12
|
+
TwilioResource::Base.user = 1
|
|
13
|
+
account = TwilioResource::Account.find(1)
|
|
14
|
+
assert_equal "2", account.status
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
data/test/call_test.rb
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'twilio_mock'
|
|
3
|
+
|
|
4
|
+
class TwilioResource::CallTest < Test::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
super
|
|
8
|
+
TwilioMock.setup_remote_fixtures
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_find_all
|
|
12
|
+
calls = TwilioResource::Call.find(:all, :params => {:account_id => 1})
|
|
13
|
+
assert_equal 2, calls.length
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# what the hell, twilio? who uses capitalization to distinguish
|
|
17
|
+
# between param types? you, that's who.
|
|
18
|
+
def test_find_by_status
|
|
19
|
+
calls = TwilioResource::Call.find(:all, :params => {:account_id => 1, :status => TwilioResource::Call::COMPLETE})
|
|
20
|
+
assert_equal TwilioResource::Call::COMPLETE, calls.first.status
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_find_by_start_time
|
|
24
|
+
calls = TwilioResource::Call.find(:all, :params => {:account_id => 1, :start_time => '2009-09-01'})
|
|
25
|
+
assert_equal 1, calls.length
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_no_results
|
|
29
|
+
calls = TwilioResource::Call.find(:all, :params => {:account_id => 1, :status => TwilioResource::Call::COMPLETE, :start_time => '2009-09-01'})
|
|
30
|
+
assert_equal 0, calls.length
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'twilio_mock'
|
|
3
|
+
|
|
4
|
+
class TwilioResource::IncomingPhoneNumberTest < Test::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
super
|
|
8
|
+
TwilioMock.setup_remote_fixtures
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_find
|
|
12
|
+
local_number = TwilioResource::IncomingPhoneNumber.find(1, :params => {:account_id => 1})
|
|
13
|
+
assert_equal '4158675309', local_number.phone_number
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def test_delete_from_class
|
|
17
|
+
assert TwilioResource::IncomingPhoneNumber.delete(1, :account_id => 1)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'twilio_mock'
|
|
3
|
+
|
|
4
|
+
class TwilioResource::LocalIncomingPhoneNumberTest < Test::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
super
|
|
8
|
+
TwilioMock.setup_remote_fixtures
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_provision_local_number
|
|
12
|
+
phone = TwilioResource::LocalIncomingPhoneNumber.new(:url => "http://example.com/calls",
|
|
13
|
+
:area_code => "206",
|
|
14
|
+
:method => 'POST',
|
|
15
|
+
:friendly_name => "My Local Number",
|
|
16
|
+
:account_id => 1)
|
|
17
|
+
assert_equal "AreaCode=206&FriendlyName=My+Local+Number&Method=POST&Url=http%3A%2F%2Fexample.com%2Fcalls", phone.encode
|
|
18
|
+
phone.save
|
|
19
|
+
|
|
20
|
+
assert_equal '2064567890', phone.phone_number
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_save_with_unavailable_number_throws_exception
|
|
24
|
+
TwilioResource::Base.user = 2
|
|
25
|
+
phone = TwilioResource::LocalIncomingPhoneNumber.new(:url => "http://example.com/calls",
|
|
26
|
+
:area_code => "815",
|
|
27
|
+
:method => 'POST',
|
|
28
|
+
:friendly_name => "My Local Number",
|
|
29
|
+
:account_id => TwilioResource::Base.user)
|
|
30
|
+
assert_equal "AreaCode=815&FriendlyName=My+Local+Number&Method=POST&Url=http%3A%2F%2Fexample.com%2Fcalls", phone.encode
|
|
31
|
+
assert_raises TwilioResource::NoPhoneNumbersFoundException do
|
|
32
|
+
phone.save
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# test find, update
|
|
38
|
+
|
|
39
|
+
end
|
data/test/test_helper.rb
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'twilio_mock'
|
|
3
|
+
|
|
4
|
+
class TwilioResource::TollFreeIncomingPhoneNumberTest < Test::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
super
|
|
8
|
+
TwilioMock.setup_remote_fixtures
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_provision_toll_free_number
|
|
12
|
+
TwilioResource::Base.user = 1
|
|
13
|
+
phone = TwilioResource::TollFreeIncomingPhoneNumber.new(:url => "http://example.com/calls",
|
|
14
|
+
:method => 'POST',
|
|
15
|
+
:friendly_name => "My Local Number",
|
|
16
|
+
:account_id => TwilioResource::Base.user)
|
|
17
|
+
assert_equal "FriendlyName=My+Local+Number&Method=POST&Url=http%3A%2F%2Fexample.com%2Fcalls", phone.encode
|
|
18
|
+
phone.save
|
|
19
|
+
|
|
20
|
+
assert_equal '8774567890', phone.phone_number
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# test find, update
|
|
24
|
+
|
|
25
|
+
end
|
data/test/twilio_mock.rb
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
require 'active_resource/http_mock'
|
|
2
|
+
|
|
3
|
+
class TwilioMock
|
|
4
|
+
|
|
5
|
+
def self.setup_remote_fixtures
|
|
6
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
|
7
|
+
mock.get '/2008-08-01/Accounts/1', auth_get(1), main_account
|
|
8
|
+
mock.post '/2008-08-01/Accounts/1/IncomingPhoneNumbers/Local', auth_post(1), local_number_provision_success
|
|
9
|
+
mock.post '/2008-08-01/Accounts/2/IncomingPhoneNumbers/Local', auth_post(2), no_local_number, 400
|
|
10
|
+
mock.post '/2008-08-01/Accounts/1/IncomingPhoneNumbers/TollFree', auth_post(1), toll_free_number_provision_success
|
|
11
|
+
|
|
12
|
+
mock.get '/2008-08-01/Accounts/1/Calls', auth_get(1), all_calls
|
|
13
|
+
mock.get '/2008-08-01/Accounts/1/Calls?StartTime=2009-09-01', auth_get(1), recent_calls
|
|
14
|
+
mock.get '/2008-08-01/Accounts/1/Calls?Status=2', auth_get(1), succeeded_recent_calls
|
|
15
|
+
mock.get '/2008-08-01/Accounts/1/Calls?StartTime=2009-09-01&Status=2', auth_get(1), no_calls
|
|
16
|
+
|
|
17
|
+
mock.get '/2008-08-01/Accounts/1/IncomingPhoneNumbers/1', auth_get(1), phone_number_data
|
|
18
|
+
mock.delete '/2008-08-01/Accounts/1/IncomingPhoneNumbers/1', auth_delete(1), phone_number_delete_success
|
|
19
|
+
mock.delete '/2008-08-01/Accounts/2/IncomingPhoneNumbers/2', auth_delete(2), "", 404
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.auth_delete(account_id)
|
|
26
|
+
old_account_id = TwilioResource::Base.user
|
|
27
|
+
TwilioResource::Base.user = account_id
|
|
28
|
+
auth = TwilioResource::Account.connection.send(:build_request_headers, {}, :delete)
|
|
29
|
+
TwilioResource::Base.user = old_account_id
|
|
30
|
+
auth
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.auth_post(account_id)
|
|
34
|
+
old_account_id = TwilioResource::Base.user
|
|
35
|
+
TwilioResource::Base.user = account_id
|
|
36
|
+
auth = TwilioResource::Account.connection.send(:build_request_headers, {}, :post)
|
|
37
|
+
TwilioResource::Base.user = old_account_id
|
|
38
|
+
auth
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.auth_get(account_id)
|
|
42
|
+
old_account_id = TwilioResource::Base.user
|
|
43
|
+
TwilioResource::Base.user = account_id
|
|
44
|
+
auth = TwilioResource::Account.connection.send(:build_request_headers, {}, :get)
|
|
45
|
+
TwilioResource::Base.user = old_account_id
|
|
46
|
+
auth
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def self.phone_number_data
|
|
50
|
+
<<END
|
|
51
|
+
<TwilioResponse>
|
|
52
|
+
<IncomingPhoneNumber>
|
|
53
|
+
<Sid>PNe536dfda7c6184afab78d980cb8cdf43</Sid>
|
|
54
|
+
<AccountSid>AC35542fc30a091bed0c1ed511e1d9935d</AccountSid>
|
|
55
|
+
<FriendlyName>My Home Phone Number</FriendlyName>
|
|
56
|
+
<PhoneNumber>4158675309</PhoneNumber>
|
|
57
|
+
<Url>http://mycompany.com/handleMainLineCall.asp</Url>
|
|
58
|
+
<Method>GET</Method>
|
|
59
|
+
<DateCreated>Tue, 01 Apr 2008 11:26:32 -0700</DateCreated>
|
|
60
|
+
<DateUpdated>Tue, 01 Apr 2008 11:26:32 -0700</DateUpdated>
|
|
61
|
+
</IncomingPhoneNumber>
|
|
62
|
+
</TwilioResponse>
|
|
63
|
+
END
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.main_account
|
|
67
|
+
<<END
|
|
68
|
+
<TwilioResponse>
|
|
69
|
+
<Account>
|
|
70
|
+
<Sid>AC309475e5fede1b49e100272a8640f438</Sid>
|
|
71
|
+
<FriendlyName>My Twilio Account</FriendlyName>
|
|
72
|
+
<Status>2</Status>
|
|
73
|
+
<StatusText>Active</StatusText>
|
|
74
|
+
<DateCreated>Wed, 02 Apr 2008 17:33:38 -0700</DateCreated>
|
|
75
|
+
<DateUpdated>Wed, 02 Apr 2008 17:34:18 -0700</DateUpdated>
|
|
76
|
+
<AuthToken>3a2630a909aadbf60266234756fb15a0</AuthToken>
|
|
77
|
+
</Account>
|
|
78
|
+
</TwilioResponse>
|
|
79
|
+
END
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def self.phone_number_delete_success
|
|
83
|
+
<<END
|
|
84
|
+
<TwilioResponse />
|
|
85
|
+
END
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def self.all_calls
|
|
89
|
+
<<END
|
|
90
|
+
<TwilioResponse>
|
|
91
|
+
<Calls page="0" numpages="1" pagesize="50" total="38" start="0" end="37">
|
|
92
|
+
<Call>
|
|
93
|
+
<Sid>CA42ed11f93dc08b952027ffbc406d0868</Sid>
|
|
94
|
+
<DateCreated>Sat, 07 Feb 2009 13:15:19 -0800</DateCreated>
|
|
95
|
+
<DateUpdated>Sat, 07 Feb 2009 13:15:19 -0800</DateUpdated>
|
|
96
|
+
<CallSegmentSid/>
|
|
97
|
+
<AccountSid>AC309475e5fede1b49e100272a8640f438</AccountSid>
|
|
98
|
+
<Called>4159633717</Called>
|
|
99
|
+
<Caller>4156767925</Caller>
|
|
100
|
+
<PhoneNumberSid>PN01234567890123456789012345678900</PhoneNumberSid>
|
|
101
|
+
<Status>2</Status>
|
|
102
|
+
<StartTime>Thu, 03 Apr 2008 04:36:33 -0400</StartTime>
|
|
103
|
+
<EndTime>Thu, 03 Apr 2008 04:36:47 -0400</EndTime>
|
|
104
|
+
<Duration>14</Duration>
|
|
105
|
+
<Price/>
|
|
106
|
+
<Flags>1</Flags>
|
|
107
|
+
</Call>
|
|
108
|
+
<Call>
|
|
109
|
+
<Sid>CA751e8fa0a0105cf26a0d7a9775fb4bfb</Sid>
|
|
110
|
+
<DateCreated>Sat, 07 Feb 2009 13:15:19 -0800</DateCreated>
|
|
111
|
+
<DateUpdated>Sat, 07 Feb 2009 13:15:19 -0800</DateUpdated>
|
|
112
|
+
<CallSegmentSid/>
|
|
113
|
+
<AccountSid>AC309475e5fede1b49e100272a8640f438</AccountSid>
|
|
114
|
+
<Called>2064287985</Called>
|
|
115
|
+
<Caller>4156767925</Caller>
|
|
116
|
+
<PhoneNumberSid>PNd59c2ba27ef48264773edb90476d1674</PhoneNumberSid>
|
|
117
|
+
<Status>2</Status>
|
|
118
|
+
<StartTime>Thu, 03 Apr 2008 01:37:05 -0400</StartTime>
|
|
119
|
+
<EndTime>Thu, 03 Apr 2008 01:37:40 -0400</EndTime>
|
|
120
|
+
<Duration>35</Duration>
|
|
121
|
+
<Price/>
|
|
122
|
+
<Flags>1</Flags>
|
|
123
|
+
</Call>
|
|
124
|
+
</Calls>
|
|
125
|
+
</TwilioResponse>
|
|
126
|
+
END
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def self.succeeded_calls
|
|
130
|
+
<<END
|
|
131
|
+
<TwilioResponse>
|
|
132
|
+
<Calls page="0" numpages="1" pagesize="50" total="38" start="0" end="37">
|
|
133
|
+
<Call>
|
|
134
|
+
<Sid>CA42ed11f93dc08b952027ffbc406d0868</Sid>
|
|
135
|
+
<DateCreated>Sat, 07 Feb 2009 13:15:19 -0800</DateCreated>
|
|
136
|
+
<DateUpdated>Sat, 07 Feb 2009 13:15:19 -0800</DateUpdated>
|
|
137
|
+
<CallSegmentSid/>
|
|
138
|
+
<AccountSid>AC309475e5fede1b49e100272a8640f438</AccountSid>
|
|
139
|
+
<Called>4159633717</Called>
|
|
140
|
+
<Caller>4156767925</Caller>
|
|
141
|
+
<PhoneNumberSid>PN01234567890123456789012345678900</PhoneNumberSid>
|
|
142
|
+
<Status>2</Status>
|
|
143
|
+
<StartTime>Thu, 03 Apr 2008 04:36:33 -0400</StartTime>
|
|
144
|
+
<EndTime>Thu, 03 Apr 2008 04:36:47 -0400</EndTime>
|
|
145
|
+
<Duration>14</Duration>
|
|
146
|
+
<Price/>
|
|
147
|
+
<Flags>1</Flags>
|
|
148
|
+
</Call>
|
|
149
|
+
<Call>
|
|
150
|
+
<Sid>1000</Sid>
|
|
151
|
+
<DateCreated>Sat, 07 Feb 2009 13:15:19 -0800</DateCreated>
|
|
152
|
+
<DateUpdated>Sat, 07 Feb 2009 13:15:19 -0800</DateUpdated>
|
|
153
|
+
<CallSegmentSid>10001</CallSegmentSid>
|
|
154
|
+
<AccountSid>AC309475e5fede1b49e100272a8640f438</AccountSid>
|
|
155
|
+
<Called>4159633717</Called>
|
|
156
|
+
<Caller>4156767925</Caller>
|
|
157
|
+
<PhoneNumberSid>ABC123</PhoneNumberSid>
|
|
158
|
+
<Status>2</Status>
|
|
159
|
+
<StartTime>Thu, 03 Apr 2008 04:36:33 -0400</StartTime>
|
|
160
|
+
<EndTime>Thu, 03 Apr 2008 04:36:47 -0400</EndTime>
|
|
161
|
+
<Duration>14</Duration>
|
|
162
|
+
<Price/>
|
|
163
|
+
<Flags>1</Flags>
|
|
164
|
+
</Call>
|
|
165
|
+
<Call>
|
|
166
|
+
<Sid>1001</Sid>
|
|
167
|
+
<DateCreated>Sat, 07 Feb 2009 13:15:19 -0800</DateCreated>
|
|
168
|
+
<DateUpdated>Sat, 07 Feb 2009 13:15:19 -0800</DateUpdated>
|
|
169
|
+
<CallSegmentSid>10002</CallSegmentSid>
|
|
170
|
+
<AccountSid>AC309475e5fede1b49e100272a8640f438</AccountSid>
|
|
171
|
+
<Called>4159633717</Called>
|
|
172
|
+
<Caller>4156767925</Caller>
|
|
173
|
+
<PhoneNumberSid>ABC123</PhoneNumberSid>
|
|
174
|
+
<Status>2</Status>
|
|
175
|
+
<StartTime>Thu, 03 Apr 2008 04:36:33 -0400</StartTime>
|
|
176
|
+
<EndTime>Thu, 03 Apr 2008 04:36:47 -0400</EndTime>
|
|
177
|
+
<Duration>14</Duration>
|
|
178
|
+
<Price/>
|
|
179
|
+
<Flags>1</Flags>
|
|
180
|
+
</Call>
|
|
181
|
+
<Call>
|
|
182
|
+
<Sid>1002</Sid>
|
|
183
|
+
<DateCreated>Sat, 07 Feb 2009 13:15:19 -0800</DateCreated>
|
|
184
|
+
<DateUpdated>Sat, 07 Feb 2009 13:15:19 -0800</DateUpdated>
|
|
185
|
+
<CallSegmentSid>10003</CallSegmentSid>
|
|
186
|
+
<AccountSid>AC309475e5fede1b49e100272a8640f438</AccountSid>
|
|
187
|
+
<Called>4159633717</Called>
|
|
188
|
+
<Caller>4156767925</Caller>
|
|
189
|
+
<PhoneNumberSid>ABC123</PhoneNumberSid>
|
|
190
|
+
<Status>2</Status>
|
|
191
|
+
<StartTime>Thu, 03 Apr 2008 04:36:33 -0400</StartTime>
|
|
192
|
+
<EndTime>Thu, 03 Apr 2008 04:36:47 -0400</EndTime>
|
|
193
|
+
<Duration>14</Duration>
|
|
194
|
+
<Price/>
|
|
195
|
+
<Flags>1</Flags>
|
|
196
|
+
</Call>
|
|
197
|
+
<Call>
|
|
198
|
+
<Sid>1003</Sid>
|
|
199
|
+
<DateCreated>Sat, 07 Feb 2009 13:15:19 -0800</DateCreated>
|
|
200
|
+
<DateUpdated>Sat, 07 Feb 2009 13:15:19 -0800</DateUpdated>
|
|
201
|
+
<CallSegmentSid>10004</CallSegmentSid>
|
|
202
|
+
<AccountSid>AC309475e5fede1b49e100272a8640f438</AccountSid>
|
|
203
|
+
<Called>4159633717</Called>
|
|
204
|
+
<Caller>4156767925</Caller>
|
|
205
|
+
<PhoneNumberSid>UNKNOWN</PhoneNumberSid>
|
|
206
|
+
<Status>2</Status>
|
|
207
|
+
<StartTime>Thu, 03 Apr 2008 04:36:33 -0400</StartTime>
|
|
208
|
+
<EndTime>Thu, 03 Apr 2008 04:36:47 -0400</EndTime>
|
|
209
|
+
<Duration>14</Duration>
|
|
210
|
+
<Price/>
|
|
211
|
+
<Flags>1</Flags>
|
|
212
|
+
</Call>
|
|
213
|
+
<Call>
|
|
214
|
+
<Sid>AVENDORIDAVENDORIDAVENDORID</Sid>
|
|
215
|
+
<DateCreated>Sat, 07 Feb 2009 13:15:19 -0800</DateCreated>
|
|
216
|
+
<DateUpdated>Sat, 07 Feb 2009 13:15:19 -0800</DateUpdated>
|
|
217
|
+
<CallSegmentSid>10004</CallSegmentSid>
|
|
218
|
+
<AccountSid>AC309475e5fede1b49e100272a8640f438</AccountSid>
|
|
219
|
+
<Called>4159633717</Called>
|
|
220
|
+
<Caller>4156767925</Caller>
|
|
221
|
+
<PhoneNumberSid>ABC123</PhoneNumberSid>
|
|
222
|
+
<Status>2</Status>
|
|
223
|
+
<StartTime>Thu, 03 Apr 2008 04:36:33 -0400</StartTime>
|
|
224
|
+
<EndTime>Thu, 03 Apr 2008 04:36:47 -0400</EndTime>
|
|
225
|
+
<Duration>14</Duration>
|
|
226
|
+
<Price/>
|
|
227
|
+
<Flags>1</Flags>
|
|
228
|
+
</Call>
|
|
229
|
+
</Calls>
|
|
230
|
+
</TwilioResponse>
|
|
231
|
+
END
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def self.recent_calls
|
|
235
|
+
<<END
|
|
236
|
+
<TwilioResponse>
|
|
237
|
+
<Calls page="0" numpages="1" pagesize="50" total="38" start="0" end="37">
|
|
238
|
+
<Call>
|
|
239
|
+
<Sid>CA42ed11f93dc08b952027ffbc406d0868</Sid>
|
|
240
|
+
<DateCreated>Sat, 07 Feb 2009 13:15:19 -0800</DateCreated>
|
|
241
|
+
<DateUpdated>Sat, 07 Feb 2009 13:15:19 -0800</DateUpdated>
|
|
242
|
+
<CallSegmentSid/>
|
|
243
|
+
<AccountSid>AC309475e5fede1b49e100272a8640f438</AccountSid>
|
|
244
|
+
<Called>4159633717</Called>
|
|
245
|
+
<Caller>4156767925</Caller>
|
|
246
|
+
<PhoneNumberSid>PN01234567890123456789012345678900</PhoneNumberSid>
|
|
247
|
+
<Status>1</Status>
|
|
248
|
+
<StartTime>Thu, 03 Apr 2008 04:36:33 -0400</StartTime>
|
|
249
|
+
<EndTime>Thu, 03 Apr 2008 04:36:47 -0400</EndTime>
|
|
250
|
+
<Duration>14</Duration>
|
|
251
|
+
<Price/>
|
|
252
|
+
<Flags>1</Flags>
|
|
253
|
+
</Call>
|
|
254
|
+
</Calls>
|
|
255
|
+
</TwilioResponse>
|
|
256
|
+
END
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def self.succeeded_recent_calls
|
|
261
|
+
<<END
|
|
262
|
+
<TwilioResponse>
|
|
263
|
+
<Calls page="0" numpages="1" pagesize="50" total="38" start="0" end="37">
|
|
264
|
+
<Call>
|
|
265
|
+
<Sid>CA42ed11f93dc08b952027ffbc406d0868</Sid>
|
|
266
|
+
<DateCreated>Sat, 07 Feb 2009 13:15:19 -0800</DateCreated>
|
|
267
|
+
<DateUpdated>Sat, 07 Feb 2009 13:15:19 -0800</DateUpdated>
|
|
268
|
+
<CallSegmentSid>8142ed11f93dc08b952027ffbc406d0868</CallSegmentSid>
|
|
269
|
+
<AccountSid>AC309475e5fede1b49e100272a8640f438</AccountSid>
|
|
270
|
+
<Called>4159633717</Called>
|
|
271
|
+
<Caller>4156767925</Caller>
|
|
272
|
+
<PhoneNumberSid>PN01234567890123456789012345678900</PhoneNumberSid>
|
|
273
|
+
<Status>2</Status>
|
|
274
|
+
<StartTime>Thu, 03 Apr 2008 04:36:33 -0400</StartTime>
|
|
275
|
+
<EndTime>Thu, 03 Apr 2008 04:36:47 -0400</EndTime>
|
|
276
|
+
<Duration>14</Duration>
|
|
277
|
+
<Price/>
|
|
278
|
+
<Flags>1</Flags>
|
|
279
|
+
</Call>
|
|
280
|
+
</Calls>
|
|
281
|
+
</TwilioResponse>
|
|
282
|
+
END
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def self.no_calls
|
|
286
|
+
<<END
|
|
287
|
+
<TwilioResponse>
|
|
288
|
+
<Calls page="0" numpages="1" pagesize="50" total="38" start="0" end="37">
|
|
289
|
+
</Calls>
|
|
290
|
+
</TwilioResponse>
|
|
291
|
+
END
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def self.local_number_provision_success
|
|
295
|
+
<<END
|
|
296
|
+
<TwilioResponse>
|
|
297
|
+
<IncomingPhoneNumber>
|
|
298
|
+
<Sid>PNe536dfda7c6184afab78d980cb8cdf43</Sid>
|
|
299
|
+
<AccountSid>AC35542fc30a091bed0c1ed511e1d9935d</AccountSid>
|
|
300
|
+
<FriendlyName>My Local Number</FriendlyName>
|
|
301
|
+
<PhoneNumber>2064567890</PhoneNumber>
|
|
302
|
+
<Url>http://example.com/calls</Url>
|
|
303
|
+
<Method>GET</Method>
|
|
304
|
+
<DateCreated>Tue, 01 Apr 2008 11:26:32 -0700</DateCreated>
|
|
305
|
+
<DateUpdated>Tue, 01 Apr 2008 11:26:32 -0700</DateUpdated>
|
|
306
|
+
</IncomingPhoneNumber>
|
|
307
|
+
</TwilioResponse>
|
|
308
|
+
END
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
def self.toll_free_number_provision_success
|
|
312
|
+
<<END
|
|
313
|
+
<TwilioResponse>
|
|
314
|
+
<IncomingPhoneNumber>
|
|
315
|
+
<Sid>PNe536dfda7c6184afab78d980cb8cdf43</Sid>
|
|
316
|
+
<AccountSid>AC35542fc30a091bed0c1ed511e1d9935d</AccountSid>
|
|
317
|
+
<FriendlyName>My Toll Free Number</FriendlyName>
|
|
318
|
+
<PhoneNumber>8774567890</PhoneNumber>
|
|
319
|
+
<Url>http://example.com/calls</Url>
|
|
320
|
+
<Method>GET</Method>
|
|
321
|
+
<DateCreated>Tue, 01 Apr 2008 11:26:32 -0700</DateCreated>
|
|
322
|
+
<DateUpdated>Tue, 01 Apr 2008 11:26:32 -0700</DateUpdated>
|
|
323
|
+
</IncomingPhoneNumber>
|
|
324
|
+
</TwilioResponse>
|
|
325
|
+
END
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
def self.no_local_number
|
|
329
|
+
<<END
|
|
330
|
+
<TwilioResponse><RestException><Status>400</Status><Message>No phone numbers found</Message><Code>21452</Code><MoreInfo>http://www.twilio.com/docs/errors/21452</MoreInfo></RestException></TwilioResponse>
|
|
331
|
+
END
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: twilio_resource
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
prerelease: false
|
|
5
|
+
segments:
|
|
6
|
+
- 0
|
|
7
|
+
- 1
|
|
8
|
+
- 0
|
|
9
|
+
version: 0.1.0
|
|
10
|
+
platform: ruby
|
|
11
|
+
authors:
|
|
12
|
+
- Justin Weiss
|
|
13
|
+
autorequire:
|
|
14
|
+
bindir: bin
|
|
15
|
+
cert_chain: []
|
|
16
|
+
|
|
17
|
+
date: 2010-06-16 00:00:00 -07:00
|
|
18
|
+
default_executable:
|
|
19
|
+
dependencies:
|
|
20
|
+
- !ruby/object:Gem::Dependency
|
|
21
|
+
name: activeresource
|
|
22
|
+
prerelease: false
|
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
24
|
+
requirements:
|
|
25
|
+
- - ">="
|
|
26
|
+
- !ruby/object:Gem::Version
|
|
27
|
+
segments:
|
|
28
|
+
- 2
|
|
29
|
+
- 3
|
|
30
|
+
- 2
|
|
31
|
+
version: 2.3.2
|
|
32
|
+
type: :runtime
|
|
33
|
+
version_requirements: *id001
|
|
34
|
+
description:
|
|
35
|
+
email: justin@uberweiss.org
|
|
36
|
+
executables: []
|
|
37
|
+
|
|
38
|
+
extensions: []
|
|
39
|
+
|
|
40
|
+
extra_rdoc_files:
|
|
41
|
+
- README.md
|
|
42
|
+
files:
|
|
43
|
+
- lib/twilio_resource/account.rb
|
|
44
|
+
- lib/twilio_resource/base.rb
|
|
45
|
+
- lib/twilio_resource/call.rb
|
|
46
|
+
- lib/twilio_resource/exceptions.rb
|
|
47
|
+
- lib/twilio_resource/incoming_phone_number.rb
|
|
48
|
+
- lib/twilio_resource/local_incoming_phone_number.rb
|
|
49
|
+
- lib/twilio_resource/toll_free_incoming_phone_number.rb
|
|
50
|
+
- lib/twilio_resource/twilio_format.rb
|
|
51
|
+
- lib/twilio_resource.rb
|
|
52
|
+
- test/account_test.rb
|
|
53
|
+
- test/call_test.rb
|
|
54
|
+
- test/incoming_phone_number_test.rb
|
|
55
|
+
- test/local_incoming_phone_number_test.rb
|
|
56
|
+
- test/test_helper.rb
|
|
57
|
+
- test/toll_free_incoming_phone_number_test.rb
|
|
58
|
+
- test/twilio_mock.rb
|
|
59
|
+
- README.md
|
|
60
|
+
has_rdoc: true
|
|
61
|
+
homepage: http://github.com/justinweiss/twilio_resource
|
|
62
|
+
licenses: []
|
|
63
|
+
|
|
64
|
+
post_install_message:
|
|
65
|
+
rdoc_options: []
|
|
66
|
+
|
|
67
|
+
require_paths:
|
|
68
|
+
- lib
|
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - ">="
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
segments:
|
|
74
|
+
- 0
|
|
75
|
+
version: "0"
|
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
|
+
requirements:
|
|
78
|
+
- - ">="
|
|
79
|
+
- !ruby/object:Gem::Version
|
|
80
|
+
segments:
|
|
81
|
+
- 0
|
|
82
|
+
version: "0"
|
|
83
|
+
requirements: []
|
|
84
|
+
|
|
85
|
+
rubyforge_project:
|
|
86
|
+
rubygems_version: 1.3.6
|
|
87
|
+
signing_key:
|
|
88
|
+
specification_version: 3
|
|
89
|
+
summary: An ActiveResource API wrapper for Twilio
|
|
90
|
+
test_files:
|
|
91
|
+
- test/account_test.rb
|
|
92
|
+
- test/call_test.rb
|
|
93
|
+
- test/incoming_phone_number_test.rb
|
|
94
|
+
- test/local_incoming_phone_number_test.rb
|
|
95
|
+
- test/toll_free_incoming_phone_number_test.rb
|