exotel 0.1.1 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Build Status](https://travis-ci.org/vijendra/exotel.png?branch=master)](https://travis-ci.org/vijendra/exotel)
|
3
|
-
|
4
|
-
|
2
|
+
[![Build Status](https://travis-ci.org/vijendra/exotel.png?branch=master)](https://travis-ci.org/vijendra/exotel) [![Code Climate](https://codeclimate.com/badge.png)](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
|