exotel 0.1.1 → 0.2
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/.travis.yml +1 -1
- data/Gemfile.lock +8 -4
- data/README.md +44 -19
- data/exotel.gemspec +1 -0
- data/lib/exotel.rb +1 -0
- data/lib/exotel/call.rb +100 -0
- data/lib/exotel/config.rb +2 -0
- data/lib/exotel/response.rb +35 -11
- data/lib/exotel/sms.rb +26 -5
- data/lib/exotel/version.rb +1 -1
- data/test/exotel/call_test.rb +105 -0
- data/test/exotel/sms_test.rb +24 -4
- data/test/fixtures/call.xml +28 -0
- data/test/fixtures/call_dnd.xml +6 -0
- data/test/helper.rb +1 -0
- metadata +19 -4
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
exotel (0.
|
4
|
+
exotel (0.2)
|
5
5
|
httparty (>= 0.9.0)
|
6
6
|
|
7
7
|
GEM
|
@@ -9,11 +9,14 @@ GEM
|
|
9
9
|
specs:
|
10
10
|
addressable (2.3.2)
|
11
11
|
crack (0.3.1)
|
12
|
-
httparty (0.
|
12
|
+
httparty (0.10.2)
|
13
13
|
multi_json (~> 1.0)
|
14
|
-
multi_xml
|
14
|
+
multi_xml (>= 0.5.2)
|
15
|
+
metaclass (0.0.1)
|
16
|
+
mocha (0.13.0)
|
17
|
+
metaclass (~> 0.0.1)
|
15
18
|
multi_json (1.5.0)
|
16
|
-
multi_xml (0.5.
|
19
|
+
multi_xml (0.5.2)
|
17
20
|
webmock (1.9.0)
|
18
21
|
addressable (>= 2.2.7)
|
19
22
|
crack (>= 0.1.7)
|
@@ -24,4 +27,5 @@ PLATFORMS
|
|
24
27
|
DEPENDENCIES
|
25
28
|
bundler (>= 1.0.0)
|
26
29
|
exotel!
|
30
|
+
mocha
|
27
31
|
webmock
|
data/README.md
CHANGED
@@ -1,30 +1,55 @@
|
|
1
1
|
# exotel - A ruby wrapper for the Exotel API
|
2
|
-
[](https://travis-ci.org/vijendra/exotel)
|
3
|
-
|
4
|
-
|
2
|
+
[](https://travis-ci.org/vijendra/exotel) [](https://codeclimate.com/github/vijendra/exotel)
|
3
|
+
|
4
|
+
## Installation
|
5
5
|
gem install exotel
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
## Usage
|
8
|
+
**Configure authentication keys**
|
9
|
+
|
10
10
|
Exotel.configure do |c|
|
11
11
|
c.exotel_sid = "Your exotel sid"
|
12
12
|
c.exotel_token = "Your exotel token"
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
response =
|
18
|
-
sms_id = response.sid
|
15
|
+
**To send SMS**
|
16
|
+
|
17
|
+
response = Exotel::Sms.send(:from => 'FROM_NUMBER', :to => 'TO_NUMBER', :body => 'MESSAGE BODY')
|
18
|
+
sms_id = response.sid #sid is used to find the delivery status and other details of the message in future.
|
19
|
+
|
20
|
+
**To get the details/check the delivery status of a sms**
|
21
|
+
|
22
|
+
sms = Exotel::Sms.details(sms_id)
|
23
|
+
status = response.status
|
24
|
+
date_sent = response.date_sent
|
19
25
|
|
20
|
-
|
21
|
-
|
22
|
-
response =
|
26
|
+
**To connect a customer to an agent in your company**
|
27
|
+
|
28
|
+
response = Exotel::Call.connect_to_agent(:to => 'Your Exotel Virtual Number', :from => 'The customer phone number that will be called', :caller_id => 'Your Exotel Number', :call_type => 'trans or promo')
|
29
|
+
call_id = response.sid #sid is used to find the details of the call. Ex: Total price of teh call.
|
30
|
+
|
31
|
+
For complete details about the parameters refer exotel api doc.
|
32
|
+
http://goo.gl/nx4Tf
|
33
|
+
|
34
|
+
**To connect a customer to an existing App/Flow**
|
35
|
+
|
36
|
+
response = Exotel::Call.connect_to_agent(:to => 'Your Exotel Virtual Number', :from => 'The customer phone number that will be called', :caller_id => 'Your Exotel Number', :call_type => 'trans or promo'. :flow_id => 'App/Flow id to be connected')
|
37
|
+
call_id = response.sid #sid is used to find the details of the call. Ex: Total price of teh call.
|
38
|
+
|
39
|
+
For complete details about the parameters refer exotel api doc.
|
40
|
+
http://goo.gl/0zxMx
|
41
|
+
|
42
|
+
**To get the details of a call**
|
43
|
+
|
44
|
+
sms = Exotel::Call.details(call_id)
|
45
|
+
price = response.price
|
23
46
|
status = response.status
|
24
|
-
|
25
|
-
|
47
|
+
duration = response.duration
|
48
|
+
|
49
|
+
**DND numbers**
|
50
|
+
|
51
|
+
response.status = 'DND'
|
52
|
+
response.message will be some thing like 'Call to ****** cannot be made because of TRAI NDNC regulations'
|
53
|
+
|
54
|
+
## Run tests
|
26
55
|
rake test
|
27
|
-
|
28
|
-
======
|
29
|
-
# TODO
|
30
|
-
Cover exotel call
|
data/exotel.gemspec
CHANGED
data/lib/exotel.rb
CHANGED
data/lib/exotel/call.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'httparty'
|
3
|
+
module Exotel
|
4
|
+
class Call
|
5
|
+
include HTTParty
|
6
|
+
base_uri "https://twilix.exotel.in/v1/Accounts"
|
7
|
+
|
8
|
+
def initialize; end
|
9
|
+
|
10
|
+
#TODO check if this is a good decision to provide a wrapper.
|
11
|
+
def self.connect_to_flow(params={})
|
12
|
+
self.new.connect_to_flow(params)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.connect_to_agent(params={})
|
16
|
+
self.new.connect_to_agent(params)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.details(params={})
|
20
|
+
self.new.details(params)
|
21
|
+
end
|
22
|
+
|
23
|
+
def connect_to_flow(params={})
|
24
|
+
if valid?(params, {:type => 'flow'})
|
25
|
+
params = transfrom_params(params, {:type => 'flow'})
|
26
|
+
make_call(params)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def connect_to_agent(params={})
|
31
|
+
if valid?(params, {:type => 'agent'})
|
32
|
+
params = transfrom_params(params, {:type => 'agent'})
|
33
|
+
make_call(params)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def details(sid)
|
38
|
+
response = self.class.get("/#{Exotel.exotel_sid}/Calls/#{sid}", :basic_auth => auth)
|
39
|
+
handle_response(response)
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
def make_call(params)
|
45
|
+
response = self.class.post(URI.escape("/#{Exotel.exotel_sid}/Calls/connect"), {:body => params, :basic_auth => auth })
|
46
|
+
handle_response(response)
|
47
|
+
end
|
48
|
+
|
49
|
+
def valid?(params, options)
|
50
|
+
mandatory_keys = [:from, :to, :caller_id, :call_type]
|
51
|
+
mandatory_keys << :flow_id if options[:type] == 'flow'
|
52
|
+
|
53
|
+
unless mandatory_keys.all?{|key| params.keys.include?(key)}
|
54
|
+
raise Exotel::ParamsError, "Missing one or many required parameters."
|
55
|
+
end
|
56
|
+
valid_call_type?(params)
|
57
|
+
return true
|
58
|
+
end
|
59
|
+
|
60
|
+
def valid_call_type?(params)
|
61
|
+
raise Exotel::ParamsError, "Call Type is not valid" unless ['trans', 'promo'].include?(params[:call_type])
|
62
|
+
end
|
63
|
+
|
64
|
+
def auth
|
65
|
+
{:username => Exotel.exotel_sid, :password => Exotel.exotel_token}
|
66
|
+
end
|
67
|
+
|
68
|
+
def flow_url(flow_id)
|
69
|
+
"http://my.exotel.in/exoml/start/#{flow_id}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def transfrom_params(params, options)
|
73
|
+
if options[:type] == 'flow'
|
74
|
+
#Construct flow url and delete flow_id.
|
75
|
+
params = params.merge(:URL => flow_url(params[:flow_id]))
|
76
|
+
params.delete(:flow_id)
|
77
|
+
end
|
78
|
+
|
79
|
+
#Keys are converted to camelcase
|
80
|
+
params.inject({}){ |h, (key, value)| h[camelcase_key(key)] = value; h }
|
81
|
+
end
|
82
|
+
|
83
|
+
def camelcase_key(key)
|
84
|
+
key.to_s.split('_').map(&:capitalize).join.to_sym #Input: call_type, Output: :CallType
|
85
|
+
end
|
86
|
+
|
87
|
+
def handle_response(response)
|
88
|
+
case response.code.to_i
|
89
|
+
when 200...300 then Exotel::Response.new(response)
|
90
|
+
when 401 then raise Exotel::AuthenticationError, "#{response.body} Verify your sid and token."
|
91
|
+
when 403 then Exotel::Response.new(response)
|
92
|
+
else
|
93
|
+
raise Exotel::UnexpectedError, response.body
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
|
data/lib/exotel/config.rb
CHANGED
data/lib/exotel/response.rb
CHANGED
@@ -1,21 +1,45 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
module Exotel
|
3
3
|
class Response
|
4
|
-
attr_accessor :sid, :date_created, :date_updated, :status, :date_sent, :to, :from, :body
|
5
4
|
|
6
5
|
def initialize(response)
|
7
6
|
#To handle unexpected parsing from httparty
|
8
7
|
response = MultiXml.parse(response) unless response.is_a?(Hash)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
8
|
+
response_base = response['TwilioResponse']
|
9
|
+
unless response_base.include?('RestException')
|
10
|
+
set_response_data(response_base)
|
11
|
+
else
|
12
|
+
set_response_error(response_base)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def set_response_data(response_base)
|
17
|
+
(response_base['Call'] or response_base['SMSMessage']).each do |key, value|
|
18
|
+
set_variable(key, value)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def set_response_error(response_base)
|
23
|
+
response_base['RestException'].each do |key, value|
|
24
|
+
set_variable(key, value)
|
25
|
+
instance_variable_set('@status', 'DND') #Override
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def set_variable(key, value)
|
30
|
+
attr_name = underscore_format(key)
|
31
|
+
self.class.send(:attr_accessor, attr_name) #Set accessors dynamically
|
32
|
+
instance_variable_set("@#{attr_name}", value)
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
#TODO: CamelCase to underscore: check if we have to add this to string class.
|
38
|
+
def underscore_format(string)
|
39
|
+
string.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
40
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
41
|
+
tr("-", "_").
|
42
|
+
downcase
|
19
43
|
end
|
20
44
|
end
|
21
45
|
end
|
data/lib/exotel/sms.rb
CHANGED
@@ -5,14 +5,22 @@ module Exotel
|
|
5
5
|
include HTTParty
|
6
6
|
base_uri "https://twilix.exotel.in/v1/Accounts"
|
7
7
|
|
8
|
-
def initialize
|
8
|
+
def initialize; end
|
9
|
+
|
10
|
+
def self.send(params={})
|
11
|
+
self.new.send(params)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.details(params={})
|
15
|
+
self.new.details(params)
|
9
16
|
end
|
10
17
|
|
11
18
|
def send(params={})
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
19
|
+
if valid?(params)
|
20
|
+
params = transfrom_params(params)
|
21
|
+
response = self.class.post("/#{Exotel.exotel_sid}/Sms/send", {:body => params, :basic_auth => auth })
|
22
|
+
handle_response(response)
|
23
|
+
end
|
16
24
|
end
|
17
25
|
|
18
26
|
def details(sid)
|
@@ -22,6 +30,19 @@ module Exotel
|
|
22
30
|
|
23
31
|
protected
|
24
32
|
|
33
|
+
def valid?(params)
|
34
|
+
unless [:from, :to, :body].all?{|key| params.keys.include?(key)}
|
35
|
+
raise Exotel::ParamsError, "Missing one or many required parameters."
|
36
|
+
else
|
37
|
+
true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def transfrom_params(params)
|
42
|
+
#Keys are converted to camelcase
|
43
|
+
params.inject({}){ |h, (key, value)| h[key.to_s.capitalize.to_sym] = value; h }
|
44
|
+
end
|
45
|
+
|
25
46
|
def auth
|
26
47
|
{:username => Exotel.exotel_sid, :password => Exotel.exotel_token}
|
27
48
|
end
|
data/lib/exotel/version.rb
CHANGED
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Exotel::Call do
|
4
|
+
it 'should have a version' do
|
5
|
+
Exotel::Call.must_include HTTParty
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should have the correct base_uri' do
|
9
|
+
Exotel::Call.base_uri.must_equal "https://twilix.exotel.in/v1/Accounts"
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '.connect_to_flow' do
|
13
|
+
before do
|
14
|
+
@params = {:from => '01234', :to => '04321', :caller_id => '04321', :call_type => 'trans', :flow_id => '3432'}
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should pass the call to an object" do
|
18
|
+
Exotel::Call.any_instance.expects(:connect_to_flow)
|
19
|
+
Exotel::Call.connect_to_flow
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'success' do
|
23
|
+
before do
|
24
|
+
base_path = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
25
|
+
stub_request(:post, "https://test_sid:test_token@twilix.exotel.in/v1/Accounts/#{Exotel.exotel_sid}/Calls/connect").
|
26
|
+
with(:body => {:From => '01234', :To => '04321', :CallerId => '04321', :CallType => 'trans', :Url => 'http://my.exotel.in/exoml/start/3432' }).
|
27
|
+
to_return(:status => 200, :body => File.new(base_path + '/fixtures/call.xml'))
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should return the response object" do
|
31
|
+
call = Exotel::Call.new
|
32
|
+
response = call.connect_to_flow(@params)
|
33
|
+
response.class.must_equal Exotel::Response
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should set the response object values" do
|
37
|
+
call = Exotel::Call.new
|
38
|
+
response = call.connect_to_flow(@params)
|
39
|
+
response.sid.must_equal 'CAe1644a7eed5088b159577c5802d8be38'
|
40
|
+
response.date_created.must_equal 'Tue, 10 Aug 2010 08:02:17'
|
41
|
+
response.date_updated.must_equal 'Tue, 10 Aug 2010 08:02:47'
|
42
|
+
response.start_time.must_equal 'Tue, 10 Aug 2010 08:02:31 +0000'
|
43
|
+
response.end_time.must_equal 'Tue, 10 Aug 2010 08:02:47 +0000'
|
44
|
+
response.status.must_equal 'completed'
|
45
|
+
response.from.must_equal '01234'
|
46
|
+
response.to.must_equal '04321'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe 'autentication failed' do
|
51
|
+
before do
|
52
|
+
base_path = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
53
|
+
stub_request(:post, "https://test_sid:test_token@twilix.exotel.in/v1/Accounts/#{Exotel.exotel_sid}/Calls/connect").
|
54
|
+
with(:body => {:From => '01234', :To => '04321', :CallerId => '04321', :CallType => 'trans', :Url => 'http://my.exotel.in/exoml/start/3432'}).
|
55
|
+
to_return(:status => 401, :body => 'Authentication is required to view this page.')
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should raise the authentication error" do
|
59
|
+
call = Exotel::Call.new
|
60
|
+
proc{call.connect_to_flow(@params)}.
|
61
|
+
must_raise Exotel::AuthenticationError
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'missing parameters' do
|
66
|
+
before do
|
67
|
+
@call = Exotel::Call.new
|
68
|
+
end
|
69
|
+
|
70
|
+
[:from, :to, :caller_id, :call_type, :flow_id].each do |param|
|
71
|
+
it "should raise the missing params error when #{param} is missing" do
|
72
|
+
@params.delete(param)
|
73
|
+
proc{@call.connect_to_flow(@params)}.must_raise Exotel::ParamsError
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should raise the params exception for invalid :call_type" do
|
78
|
+
@params[:call_type] = 'invalid'
|
79
|
+
proc{@call.connect_to_flow(@params)}.must_raise Exotel::ParamsError
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#details' do
|
85
|
+
before do
|
86
|
+
base_path = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
87
|
+
stub_request(:get, "https://test_sid:test_token@twilix.exotel.in/v1/Accounts/#{Exotel.exotel_sid}/Calls/CAe1644a7eed5088b159577c5802d8be38").
|
88
|
+
to_return(:status => 200, :body => File.new(base_path + '/fixtures/call.xml'))
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should return the response object" do
|
92
|
+
response = Exotel::Call.details('CAe1644a7eed5088b159577c5802d8be38')
|
93
|
+
response.class.must_equal Exotel::Response
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should set the response object values" do
|
97
|
+
response = Exotel::Call.details('CAe1644a7eed5088b159577c5802d8be38')
|
98
|
+
response.sid.must_equal 'CAe1644a7eed5088b159577c5802d8be38'
|
99
|
+
response.status.must_equal 'completed'
|
100
|
+
response.price.must_equal '2.3'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
data/test/exotel/sms_test.rb
CHANGED
@@ -23,7 +23,7 @@ describe Exotel::Sms do
|
|
23
23
|
before do
|
24
24
|
base_path = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
25
25
|
stub_request(:post, "https://test_sid:test_token@twilix.exotel.in/v1/Accounts/#{Exotel.exotel_sid}/Sms/send").
|
26
|
-
with(:body =>
|
26
|
+
with(:body => {:From => '1234', :To => '4321', :Body => 'Test sms'}).
|
27
27
|
to_return(:status => 200, :body => File.new(base_path + '/fixtures/sms.xml'))
|
28
28
|
end
|
29
29
|
|
@@ -51,16 +51,36 @@ describe Exotel::Sms do
|
|
51
51
|
before do
|
52
52
|
base_path = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
53
53
|
stub_request(:post, "https://test_sid:test_token@twilix.exotel.in/v1/Accounts/#{Exotel.exotel_sid}/Sms/send").
|
54
|
-
with(:body =>
|
54
|
+
with(:body => {:From => '1234', :To => '4321', :Body => 'Test sms'}).
|
55
55
|
to_return(:status => 401, :body => 'Authentication is required to view this page.')
|
56
56
|
end
|
57
57
|
|
58
|
-
it "should
|
58
|
+
it "should raise the authentication error" do
|
59
59
|
sms = Exotel::Sms.new
|
60
60
|
proc{sms.send(:from => '1234', :to => '4321', :body => 'Test sms')}.
|
61
61
|
must_raise Exotel::AuthenticationError
|
62
62
|
end
|
63
63
|
end
|
64
|
+
|
65
|
+
describe 'missing parameters' do
|
66
|
+
it "should raise the missing params error when :from is missing" do
|
67
|
+
sms = Exotel::Sms.new
|
68
|
+
proc{sms.send(:to => '4321', :body => 'Test sms')}.
|
69
|
+
must_raise Exotel::ParamsError
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should raise the missing params error when :to is missing" do
|
73
|
+
sms = Exotel::Sms.new
|
74
|
+
proc{sms.send(:from => '1234', :body => 'Test sms')}.
|
75
|
+
must_raise Exotel::ParamsError
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should raise the missing params error when :body is missing" do
|
79
|
+
sms = Exotel::Sms.new
|
80
|
+
proc{sms.send(:to => '4321', :from => '1234')}.
|
81
|
+
must_raise Exotel::ParamsError
|
82
|
+
end
|
83
|
+
end
|
64
84
|
end
|
65
85
|
|
66
86
|
describe '#details' do
|
@@ -98,7 +118,7 @@ describe Exotel::Sms do
|
|
98
118
|
to_return(:status => 401, :body => 'Authentication is required to view this page.')
|
99
119
|
end
|
100
120
|
|
101
|
-
it "should
|
121
|
+
it "should raise the authentication error" do
|
102
122
|
sms = Exotel::Sms.new
|
103
123
|
proc{sms.details('SM872fb94e3b358913777cdb313f25b46f')}.
|
104
124
|
must_raise Exotel::AuthenticationError
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<TwilioResponse>
|
2
|
+
<Call>
|
3
|
+
<Sid>CAe1644a7eed5088b159577c5802d8be38</Sid>
|
4
|
+
<DateCreated>Tue, 10 Aug 2010 08:02:17</DateCreated>
|
5
|
+
<DateUpdated>Tue, 10 Aug 2010 08:02:47</DateUpdated>
|
6
|
+
<ParentCallSid/>
|
7
|
+
<AccountSid>AC5ea872f6da5a21de157d80997a64bd33</AccountSid>
|
8
|
+
<To>04321</To>
|
9
|
+
<From>01234</From>
|
10
|
+
<PhoneNumberSid></PhoneNumberSid>
|
11
|
+
<Status>completed</Status>
|
12
|
+
<StartTime>Tue, 10 Aug 2010 08:02:31 +0000</StartTime>
|
13
|
+
<EndTime>Tue, 10 Aug 2010 08:02:47 +0000</EndTime>
|
14
|
+
<Duration>16</Duration>
|
15
|
+
<Price>2.3</Price>
|
16
|
+
<Flags>
|
17
|
+
<Flag>outbound-api</Flag>
|
18
|
+
</Flags>
|
19
|
+
<ApiVersion>2008-08-01</ApiVersion>
|
20
|
+
<ForwardedFrom/>
|
21
|
+
<CallerName/>
|
22
|
+
<Uri>/2010-04-01/Accounts/AC5ea872f6da5a21de157d80997a64bd33/Calls/CAe1644a7eed5088b159577c5802d8be38</Uri>
|
23
|
+
<SubresourceUris>
|
24
|
+
<Notifications>/2010-04-01/Accounts/AC5ea872f6da5a21de157d80997a64bd33/Calls/CAe1644a7eed5088b159577c5802d8be38/Notifications</Notifications>
|
25
|
+
<Recordings>/2010-04-01/Accounts/AC5ea872f6da5a21de157d80997a64bd33/Calls/CAe1644a7eed5088b159577c5802d8be38/Recordings</Recordings>
|
26
|
+
</SubresourceUris>
|
27
|
+
</Call>
|
28
|
+
</TwilioResponse>
|
data/test/helper.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: exotel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: "0.2"
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Vijendra Rao
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date:
|
13
|
+
date: 2013-02-23 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -35,16 +35,27 @@ dependencies:
|
|
35
35
|
type: :development
|
36
36
|
version_requirements: *id002
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
|
-
name:
|
38
|
+
name: mocha
|
39
39
|
prerelease: false
|
40
40
|
requirement: &id003 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: "0"
|
46
|
+
type: :development
|
47
|
+
version_requirements: *id003
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: httparty
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
41
52
|
none: false
|
42
53
|
requirements:
|
43
54
|
- - ">="
|
44
55
|
- !ruby/object:Gem::Version
|
45
56
|
version: 0.9.0
|
46
57
|
type: :runtime
|
47
|
-
version_requirements: *
|
58
|
+
version_requirements: *id004
|
48
59
|
description: Exotel api wrapper.
|
49
60
|
email:
|
50
61
|
- vijendrakarkala@gmail.com
|
@@ -63,12 +74,16 @@ files:
|
|
63
74
|
- Rakefile
|
64
75
|
- exotel.gemspec
|
65
76
|
- lib/exotel.rb
|
77
|
+
- lib/exotel/call.rb
|
66
78
|
- lib/exotel/config.rb
|
67
79
|
- lib/exotel/response.rb
|
68
80
|
- lib/exotel/sms.rb
|
69
81
|
- lib/exotel/version.rb
|
82
|
+
- test/exotel/call_test.rb
|
70
83
|
- test/exotel/exotel_test.rb
|
71
84
|
- test/exotel/sms_test.rb
|
85
|
+
- test/fixtures/call.xml
|
86
|
+
- test/fixtures/call_dnd.xml
|
72
87
|
- test/fixtures/sms.xml
|
73
88
|
- test/helper.rb
|
74
89
|
homepage: https://github.com/vijendra/exotel
|