ctm 0.0.1

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.
@@ -0,0 +1 @@
1
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
@@ -0,0 +1,125 @@
1
+ CallTrackingMetrics Ruby API
2
+ ============================
3
+
4
+ Installation
5
+ ------------
6
+
7
+ gem install ctm
8
+
9
+
10
+ Usage
11
+ -----
12
+
13
+ ```ruby
14
+
15
+ require 'ctm'
16
+
17
+ # get an access token
18
+ access_token = CTM::Auth.authenticate(ENV['CTM_TOKEN'], ENV['CTM_SECRET'])
19
+
20
+ # see the list of accounts
21
+ puts CTM::Account.list(access_token).inspect
22
+
23
+ # use this access token globally, instead of passing it to each method
24
+ CTM::Auth.token = access_token
25
+
26
+ # get my first account
27
+ account = CTM::Account.first
28
+
29
+ # get an account by name
30
+ account = CTM::Account.find("name" => "My Account Name")
31
+
32
+ # get a list of numbers within this account, returns 10 at a time by default
33
+ numbers = account.numbers
34
+ puts numbers.first.inspect
35
+ puts numbers.total_entries.inspect
36
+ puts numbers.page.inspect
37
+ puts numbers.per_page.inspect
38
+ numbers.each {|number|
39
+ puts number.id
40
+ puts "#{number.name} #{number.number} -> #{number.formatted}"
41
+ }
42
+
43
+ # get the next 20 numbers on page 2
44
+ numbers = account.numbers(:page => 2, :per_page => 20)
45
+
46
+ # search for new numbers to purchase
47
+ numbers = account.numbers.search("+1", :areacode => "410")
48
+ numbers = account.numbers.search("+1", :tollfree => true, :areacode => "888")
49
+ numbers = account.number.search("+44", :contains => "55")
50
+
51
+ # purchase a new number
52
+ number = account.numbers.buy(numbers.first.digits)
53
+ if number.purchased?
54
+ puts "successfully purchased the number: #{number.digits_formated}"
55
+ else
56
+ puts "failed to purchase that number"
57
+ end
58
+
59
+ # release the number, removing it from the account
60
+ number.release!
61
+
62
+ # create a source from a predefined source
63
+ source = account.sources.create(predefined: 'google_adwords')
64
+
65
+ # list predefined sources
66
+ predefined = account.predefined
67
+
68
+ # customize a source
69
+ source = account.sources.find(:name => "Google Adwords")
70
+ source.landing_url = "utm_campaign=MyCampaign"
71
+ source.save
72
+
73
+ # assign a source to a number
74
+ source.numbers.add(number)
75
+
76
+ # get a list of receiving numbers
77
+ receiving_numbers = account.receiving_numbers
78
+
79
+ # add a receiving number, note +1 country code is required
80
+ receiving_number = account.receiving_numbers.create(name: "my number", number:"+15555555555")
81
+
82
+ # assign a receiving number to the tracking number
83
+ number.receiving_numbers.add(receiving_number)
84
+ # get the list of receiving numbers for this number
85
+ puts number.receiving_numbers.inspect
86
+ number.save
87
+
88
+ # modify the routing preference for the number
89
+ number.routing = :simultaneous # :round_robin, :least_connected
90
+ number.save
91
+
92
+ # add a new user to the account
93
+ account.users.create(first_name: 'First', last_name: 'Last', email: 'email@example.com', notify: true)
94
+
95
+ # list the users
96
+ users = account.users
97
+
98
+ # create a webhook to send call data at the start of the call
99
+ account.webhooks.create(weburl: "http://myhost.com/new_calls", position: 'start')
100
+
101
+ # create a webhook to send call data at the end of the call
102
+ account.webhooks.create(weburl: "http://myhost.com/new_calls", position: 'end')
103
+
104
+ # list webhooks
105
+ account.webhooks
106
+
107
+ # calls - list the calls
108
+ account.calls
109
+
110
+ call = account.calls.first
111
+
112
+ call.notes = "some notes to attach to the call"
113
+ call.save
114
+
115
+ # get sale record
116
+ call.sale
117
+
118
+ # create sale record, marking the call as a conversion
119
+ call.sale.create(name: "Who", score: 5, conversion: true, value: 34, date: '2013-04-24T00:00:00Z')
120
+ # or update the sale record
121
+ sale = call.sale
122
+ sale.name = "Todd"
123
+ sale.save
124
+
125
+ ```
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'rake/testtask'
4
+
5
+ task :default => :test
6
+
7
+ Rake::TestTask.new(:test) do |t|
8
+ t.test_files = FileList['test/*_test.rb']
9
+ t.verbose = false
10
+ end
data/TODO ADDED
@@ -0,0 +1,38 @@
1
+ * Accounts
2
+ x list accounts
3
+ - create account with shared billing
4
+ - create account without shared billing
5
+ * Numbers
6
+ x list numbers
7
+ x buy number
8
+ x search available numbers
9
+ x list receiving numbers
10
+ x add receiving number
11
+ x rem receiving number
12
+ x get assigned source
13
+ x add source
14
+ - rem source
15
+
16
+ * Receiving Numbers
17
+ x list receiving numbers
18
+ x add receiving number
19
+ x rem receiving number
20
+ * Sources
21
+ x list sources
22
+ x add source
23
+ x rem source
24
+ x list numbers for the source
25
+ * Users
26
+ x list users
27
+ x add user
28
+ x update user
29
+ x rem user
30
+ * Webhooks
31
+ x list webhooks for account
32
+ x add webhook
33
+ x rem webhook
34
+ * Calls
35
+ - list calls
36
+ - show call
37
+ - add sale to call
38
+ - rem sale from call
@@ -0,0 +1,20 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "ctm"
3
+ s.version = "0.0.1"
4
+ s.authors = ["CallTrackingMetrics", "Todd Fisher"]
5
+ s.email = "info@calltrackingmetrics.com"
6
+ s.files = `git ls-files`.split("\n")
7
+ s.test_files = `git ls-files -- {test}/*`.split("\n")
8
+ s.homepage = "http://github.com/calltracking/ctm-ruby"
9
+ s.require_path = "lib"
10
+ s.rubygems_version = "1.3.5"
11
+ s.summary = "API Library for CallTrackingMetrics"
12
+ s.add_runtime_dependency "phony"
13
+ s.add_runtime_dependency "httparty"
14
+ s.add_runtime_dependency "activesupport"
15
+ s.add_development_dependency "rack", '~> 1.3.0'
16
+ s.add_development_dependency "mocha"
17
+ s.add_development_dependency 'fakeweb', '~> 1.3.0'
18
+ s.add_development_dependency "rake"
19
+ end
20
+
@@ -0,0 +1,14 @@
1
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__),"..", "lib")))
2
+ require 'ctm'
3
+
4
+ access_token = CTM::Auth.authenticate(ENV['CTM_TOKEN'], ENV['CTM_SECRET'])
5
+ account = access_token.accounts.first
6
+
7
+ availble_numbers = account.numbers.search("US", :area_code => "410")
8
+ availble_numbers.each do|num|
9
+ puts "#{num.friendly_name} -> #{num.phone_number}"
10
+ end
11
+ number_to_buy = availble_numbers.first
12
+
13
+ number = account.numbers.buy("+15005550006")
14
+ puts "purchased: #{number.formatted} #{number.number}"
@@ -0,0 +1,38 @@
1
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__),"..", "lib")))
2
+ require 'ctm'
3
+
4
+ access_token = CTM::Auth.authenticate(ENV['CTM_TOKEN'], ENV['CTM_SECRET'])
5
+ puts "Accounts you have access to:"
6
+ access_token.accounts.each do|account|
7
+ puts "#{account.name} -> #{account.status}, #{account.balance}, #{account.stats.inspect}"
8
+ end
9
+ account = access_token.accounts.first
10
+
11
+ numbers = account.numbers
12
+ puts "Tracking Numbers #{numbers.total_entries} within the Account"
13
+ numbers.each do|number|
14
+ puts "#{number.id}: #{number.name} #{number.number} -> #{number.formatted}"
15
+ end
16
+ receiving_numbers = account.receiving_numbers
17
+ puts "Receiving Numbers #{receiving_numbers.total_entries} within the Account"
18
+ receiving_numbers.each do|number|
19
+ puts "#{number.id}: #{number.name} #{number.number} -> #{number.formatted}"
20
+ end
21
+
22
+ sources = account.sources
23
+ puts "Tracking Sources #{sources.total_entries} within the Account"
24
+ sources.each do|source|
25
+ puts "#{source.id}: #{source.name} #{source.referring_url} -> #{source.landing_url}"
26
+ end
27
+
28
+ users = account.users
29
+ puts "Users #{users.total_entries} within the Account"
30
+ users.each do|user|
31
+ puts "#{user.id}: #{user.name} #{user.email} -> #{user.role}"
32
+ end
33
+
34
+ webhooks = account.webhooks
35
+ puts "Webhooks #{webhooks.total_entries} within the Account"
36
+ webhooks.each do|wh|
37
+ puts "#{wh.id}: #{wh.weburl} #{wh.with_resource_url} -> #{wh.position}"
38
+ end
@@ -0,0 +1,45 @@
1
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__),"..", "lib")))
2
+ require 'ctm'
3
+
4
+ access_token = CTM::Auth.authenticate(ENV['CTM_TOKEN'], ENV['CTM_SECRET'])
5
+ account = access_token.accounts.first
6
+
7
+ numbers = account.numbers
8
+ puts "Tracking Numbers #{numbers.total_entries} within the Account"
9
+ numbers.each do|number|
10
+ puts "#{number.id}: #{number.name} #{number.number} -> #{number.formatted}"
11
+ end
12
+
13
+ number = numbers.first
14
+ # add receiving number
15
+ receiving_numbers = number.receiving_numbers
16
+ puts "Receiving Numbers #{receiving_numbers.total_entries} assigned to the tracking number"
17
+ receiving_numbers.each do|number|
18
+ puts "#{number.id}: #{number.name} #{number.number} -> #{number.formatted}"
19
+ end
20
+ receiving_number = account.receiving_numbers.find(:name => "laures phone").first
21
+ puts "Adding and removing: #{receiving_number.number}"
22
+ number.receiving_numbers.add(receiving_number)
23
+ number.receiving_numbers.rem(receiving_number)
24
+
25
+ # add tracking source
26
+ source = account.sources.find(:name => "Google Organic").first
27
+ puts source.name
28
+ source.numbers.each do|number|
29
+ puts "#{number.id}: #{number.name} #{number.number} -> #{number.formatted}"
30
+ end
31
+
32
+ source = account.sources.find(:name => "test source1").first
33
+ if !source
34
+ source = account.sources.create(:name => "test source1")
35
+ end
36
+
37
+ number = account.numbers.find(:name => "test number1").first
38
+ puts number.formatted
39
+
40
+ number.receiving_numbers.add(receiving_number)
41
+
42
+ source.numbers.add(number)
43
+ source.numbers.each do|number|
44
+ puts "#{number.id}: #{number.name} #{number.number} -> #{number.formatted}"
45
+ end
@@ -0,0 +1,25 @@
1
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__),"..", "lib")))
2
+ require 'ctm'
3
+
4
+ access_token = CTM::Auth.authenticate(ENV['CTM_TOKEN'], ENV['CTM_SECRET'])
5
+ account = access_token.accounts.first
6
+
7
+ receiving_numbers = account.receiving_numbers
8
+ puts "Receiving Numbers #{receiving_numbers.total_entries} within the Account"
9
+ receiving_numbers.each do|number|
10
+ puts "#{number.id}: #{number.name} #{number.number} -> #{number.formatted}"
11
+ end
12
+
13
+ begin
14
+ rn = account.receiving_numbers.create(:number => "+14109999999", :name => "test number")
15
+ rescue CTM::Error::Create => e
16
+ if e.message.match(/already exists/)
17
+ rn = account.receiving_numbers.find(:number => "+14109999999").first
18
+ end
19
+ end
20
+
21
+ puts rn.inspect
22
+ rn.name = "another test"
23
+ rn.save
24
+
25
+ rn.release!
@@ -0,0 +1,25 @@
1
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__),"..", "lib")))
2
+ require 'ctm'
3
+
4
+ access_token = CTM::Auth.authenticate(ENV['CTM_TOKEN'], ENV['CTM_SECRET'])
5
+ account = access_token.accounts.first
6
+
7
+ sources = account.sources
8
+ puts "Tracking Sources #{sources.total_entries} within the Account"
9
+ sources.each do|source|
10
+ puts "#{source.id}: #{source.name} #{source.referring_url} -> #{source.landing_url}"
11
+ end
12
+
13
+ source = account.sources.create(:name => "My Source",
14
+ :referring_url => "google",
15
+ :landing_url => "utm_campaign=paid",
16
+ :online => true)
17
+ puts source.name
18
+ puts source.referring_url
19
+ puts source.landing_url
20
+
21
+ source.name = "Foo bar"
22
+
23
+ source.save
24
+
25
+ source.release!
@@ -0,0 +1,31 @@
1
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__),"..", "lib")))
2
+ require 'ctm'
3
+ access_token = CTM::Auth.authenticate(ENV['CTM_TOKEN'], ENV['CTM_SECRET'])
4
+ account = access_token.accounts.first
5
+
6
+ # find user by email
7
+ users = account.users.find(:email => "todd@calltrackingmetrics.com")
8
+ users.each do|user|
9
+ puts "#{user.id}: #{user.name} #{user.email} -> #{user.role}"
10
+ end
11
+
12
+ # find by last name
13
+ users = account.users.find(:last_name => "fisher")
14
+ users.each do|user|
15
+ puts "#{user.id}: #{user.name} #{user.email} -> #{user.role}"
16
+ end
17
+
18
+ # add a new user
19
+ user = account.users.create(:email => "foo@bar11#{Time.now.to_i}.com",
20
+ :first_name => "Me",
21
+ :last_name => "You",
22
+ :password => "foobar1234",
23
+ :role => "call_manager")
24
+ # update user
25
+ user.first_name = "No"
26
+ user.last_name = "Yes"
27
+ user.role = "admin"
28
+ user.save
29
+
30
+ # remove user from account
31
+ user.release!
@@ -0,0 +1,16 @@
1
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__),"..", "lib")))
2
+ require 'ctm'
3
+
4
+ access_token = CTM::Auth.authenticate(ENV['CTM_TOKEN'], ENV['CTM_SECRET'])
5
+ account = access_token.accounts.first
6
+
7
+ webhooks = account.webhooks
8
+ puts "Webhooks #{webhooks.total_entries} within the Account"
9
+ webhooks.each do|wh|
10
+ puts "#{wh.id}: #{wh.weburl} #{wh.with_resource_url} -> #{wh.position}"
11
+ end
12
+
13
+ # get requests when the call starts
14
+ webhook = webhooks.create(:weburl => "http://example.com/myhook", :position => "start")
15
+
16
+ webhook.release!
@@ -0,0 +1,20 @@
1
+ module CTM ; end
2
+ require 'httparty'
3
+ require 'active_support/inflector'
4
+
5
+ require 'ctm/error'
6
+ require 'ctm/base'
7
+ require 'ctm/list'
8
+ require 'ctm/account'
9
+ require 'ctm/auth'
10
+ require 'ctm/available_number'
11
+ require 'ctm/call'
12
+ require 'ctm/number'
13
+ require 'ctm/number_list'
14
+ require 'ctm/receiving_number'
15
+ require 'ctm/receiving_number_list'
16
+ require 'ctm/sale'
17
+ require 'ctm/source'
18
+ require 'ctm/token'
19
+ require 'ctm/user'
20
+ require 'ctm/webhook'
@@ -0,0 +1,38 @@
1
+ module CTM
2
+ class Account < Base
3
+ attr_reader :id
4
+ attr_accessor :name, :status, :stats, :balance
5
+
6
+ # {"id"=>25, "name"=>"CallTrackingMetrics", "user_role"=>"admin", "status"=>"active",
7
+ # "stats"=>{"calls"=>{"2013-04-18"=>3, "2013-04-25"=>1}, "tracking_numbers"=>48},
8
+ # "url"=>"http://ctmdev.co/api/v1/accounts/25.json", "balance"=>{"cents"=>23739, "currency"=>"USD", "precision"=>2}}
9
+ def initialize(data, token=nil)
10
+ super(data, token)
11
+ @id = data['id']
12
+ @name = data['name']
13
+ @status = data['status']
14
+ @stats = data['stats']['calls']
15
+ @balance = "$" + (data['balance']['cents'].to_i / 100).to_s + "." + (data['balance']['cents'].to_i % 100).to_s
16
+ end
17
+
18
+ def numbers(options={})
19
+ CTM::NumberList.new(options.merge(:account_id => @id), @token)
20
+ end
21
+
22
+ def receiving_numbers(options={})
23
+ CTM::List.new('ReceivingNumber', options.merge(:account_id => @id), @token)
24
+ end
25
+
26
+ def sources(options={})
27
+ CTM::List.new('Source', options.merge(:account_id => @id), @token)
28
+ end
29
+
30
+ def users(options={})
31
+ CTM::List.new('User', options.merge(:account_id => @id), @token)
32
+ end
33
+
34
+ def webhooks(options={})
35
+ CTM::List.new('Webhook', options.merge(:account_id => @id), @token)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,24 @@
1
+ module CTM
2
+ class Auth
3
+ include HTTParty
4
+ base_uri ENV["CTM_URL"] || "api.calltrackingmetrics.com"
5
+
6
+ def self.token=(token)
7
+ @token = token
8
+ end
9
+
10
+ def self.token
11
+ @token
12
+ end
13
+
14
+ def self.authenticate(token, secret)
15
+ res = self.post("/api/v1/authentication", :body => {:token => token, :secret => secret})
16
+ if res.parsed_response && res.parsed_response['success']
17
+ CTM::Token.new(res.parsed_response)
18
+ else
19
+ raise CTM::Error::Auth.new("Failed to authenticate")
20
+ end
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ module CTM
2
+ class AvailableNumber < Base
3
+ attr_reader :friendly_name, :latitude, :longitude, :rate_center, :lata, :region, :postal_code, :iso_country, :phone_number
4
+
5
+ def initialize(data, token=nil)
6
+ super(data, token)
7
+ @friendly_name = data['friendly_name']
8
+ @latitude = data['latitude']
9
+ @longitude = data['longitude']
10
+ @lata = data['lata']
11
+ @region = data['region']
12
+ @postal_code = data['postal_code']
13
+ @iso_country = data['iso_country']
14
+ @phone_number = data['phone_number']
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,49 @@
1
+ module CTM
2
+ class Base
3
+ include HTTParty
4
+ base_uri ENV["CTM_URL"] || "api.calltrackingmetrics.com"
5
+
6
+ attr_reader :token, :account_id
7
+
8
+
9
+ def initialize(data, token=nil)
10
+ @token = token || CTM::Auth.token
11
+ @account_id = data['account_id']
12
+ @list_token_type = self.class.to_s.sub(/CTM::/,'').underscore.pluralize
13
+ if @account_id
14
+ @list_type_path = "accounts/#{@account_id}/#{@list_token_type}"
15
+ else
16
+ @list_type_path = @list_token_type
17
+ end
18
+ end
19
+
20
+ def save(options={})
21
+ puts "save: #{options.inspect}"
22
+ path_str = "/api/v1/#{@list_type_path}/#{@id}.json"
23
+ res = self.class.put(path_str, :body => options.merge(:auth_token => @token))
24
+ end
25
+
26
+ def release!
27
+ path_str = "/api/v1/#{@list_type_path}/#{@id}.json"
28
+ res = self.class.delete(path_str, :body => {:auth_token => @token})
29
+ end
30
+
31
+ def self.create(options)
32
+ list_type_path = options.delete(:list_type_path)
33
+ list_token_type = options.delete(:list_token_type)
34
+ account_id = options.delete(:account_id)
35
+ token = options.delete(:token)
36
+ path_str = "/api/v1/#{list_type_path}.json"
37
+ puts "create: #{self} -> #{options.inspect}"
38
+ res = self.post(path_str, :body => options.merge(:auth_token => token))
39
+ puts "result: #{res.parsed_response.inspect}"
40
+ puts "properties: #{list_type_path.inspect} -> #{list_token_type.inspect} -> #{account_id}"
41
+ if res.parsed_response['status'] == 'error'
42
+ raise CTM::Error::Create.new(res.parsed_response['reason'])
43
+ else
44
+ self.new(res.parsed_response[list_token_type.singularize], token)
45
+ end
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,11 @@
1
+ module CTM
2
+ class Call < Base
3
+ attr_reader :id
4
+
5
+ def initialize(data, token=nil)
6
+ super(data, token)
7
+ @id = data['id']
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ module CTM
2
+ class Error < Exception
3
+ class Auth < Exception
4
+ end
5
+ class List < Exception
6
+ end
7
+ class Buy < Exception
8
+ end
9
+ class Create < Exception
10
+ end
11
+ class Add < Exception
12
+ end
13
+ class Rem < Exception
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,80 @@
1
+ # Generic List Object to handle paginated lists of objects
2
+ module CTM
3
+ class List
4
+ include Enumerable
5
+
6
+ include HTTParty
7
+ base_uri ENV["CTM_URL"] || "api.calltrackingmetrics.com"
8
+
9
+ attr_reader :list_type, :token, :per_page, :page, :total_entries, :objects
10
+
11
+ # e.g. Account, token
12
+ def initialize(list_type, options={}, token=nil, fetched_objects=nil)
13
+ @list_type = list_type
14
+ @list_token_type = list_type.underscore.pluralize
15
+ @object_klass = CTM.module_eval(list_type)
16
+ @token = token || CTM::Auth.token
17
+ @account_id = options[:account_id]
18
+ if @account_id
19
+ @list_type_path = "accounts/#{@account_id}/#{@list_token_type}"
20
+ else
21
+ @list_type_path = @list_token_type
22
+ end
23
+ if fetched_objects
24
+ map_data(fetched_objects)
25
+ else
26
+ fetch_page(options)
27
+ end
28
+ end
29
+
30
+ def each &block
31
+ @objects.each do |obj|
32
+ if block_given?
33
+ block.call obj
34
+ else
35
+ yield obj
36
+ end
37
+ end
38
+ end
39
+
40
+ def create(options)
41
+ @object_klass.create(options.merge(:list_type_path => @list_type_path,
42
+ :list_token_type => @list_token_type,
43
+ :account_id => @account_id,
44
+ :token => @token))
45
+ end
46
+
47
+ def find(options)
48
+ first_name = options.delete(:first_name)
49
+ last_name = options.delete(:last_name)
50
+ options[:filter] = options.delete(:filter) || "#{first_name} #{last_name}".strip if first_name || last_name
51
+
52
+ fetch_page(options)
53
+ self
54
+ end
55
+
56
+ protected
57
+
58
+ def fetch_page(options={})
59
+ options = {:per_page => 10, :page => 1}.merge(options)
60
+ path_str = "/api/v1/#{@list_type_path}.json"
61
+ res = self.class.get(path_str, :query => options.merge(:auth_token => @token))
62
+ data = res.parsed_response
63
+ if data["status"] && data["status"] == "error"
64
+ puts data.inspect
65
+ raise CTM::Error::List.new(data["message"] || data["reason"])
66
+ end
67
+ map_data(data)
68
+ end
69
+
70
+ def map_data(data)
71
+ @page = data['page']
72
+ @per_page = data['per_page']
73
+ @total_entries = data['total_entries']
74
+ @objects = data[@list_token_type].map {|obj|
75
+ @object_klass.new(obj, @token)
76
+ }
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,25 @@
1
+ module CTM
2
+ class Number < Base
3
+ attr_reader :id, :account_id
4
+ attr_accessor :name, :number, :formatted, :split, :routing
5
+
6
+ def initialize(data, token=nil)
7
+ super(data, token)
8
+ @id = data['id']
9
+ @account_id = data['account_id']
10
+ @name = data['name']
11
+ @number = data['number']
12
+ @formatted = data['formatted']
13
+ @split = data['split']
14
+ @routing = data['routing']
15
+ end
16
+
17
+ def receiving_numbers(options={})
18
+ CTM::ReceivingNumberList.new(options.merge(:account_id => @account_id, :number_id => @id), @token)
19
+ end
20
+
21
+ def source
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,63 @@
1
+ module CTM
2
+ class NumberList < List
3
+ def initialize(options={}, token=nil)
4
+ super('Number', options, token)
5
+ @source_id = options[:source_id]
6
+ if @source_id && @account_id
7
+ @list_type_path = "accounts/#{@account_id}/sources/#{@source_id}/#{@list_token_type}"
8
+ elsif @account_id
9
+ @list_type_path = "accounts/#{@account_id}/#{@list_token_type}"
10
+ else
11
+ @list_type_path = @list_token_type
12
+ end
13
+ end
14
+
15
+ # find a number within the given country/region and options like area_code or containing with contains
16
+ def search(country_code, options={})
17
+ options = {:country_code => country_code}.merge(options)
18
+ path_str = "/api/v1/#{@list_type_path}/search.json"
19
+ res = self.class.get(path_str, :query => options.merge(:auth_token => @token))
20
+ data = res.parsed_response
21
+ if data["status"] == "success"
22
+ list_data = {'available_numbers' => data['results'].map {|res| res.merge('account_id' => @account_id) },
23
+ 'page' => 1,
24
+ 'per_page' => data['results'].size,
25
+ 'total_entries' => data['results'].size}
26
+ CTM::List.new('AvailableNumber', {:account_id => @account_id}, @token, list_data)
27
+ end
28
+ end
29
+
30
+ # buy number with the digits
31
+ def buy(digits)
32
+ path_str = "/api/v1/#{@list_type_path}.json"
33
+ res = self.class.post(path_str, :body => {:phone_number => digits}.merge(:auth_token => @token))
34
+ if res && res['status'] == 'success'
35
+ CTM::Number.new(res['number'], @token)
36
+ else
37
+ puts res.inspect
38
+ raise CTM::Error::Buy.new(res["reason"])
39
+ end
40
+ end
41
+
42
+ # add trackng number to tracking source
43
+ def add(number)
44
+ path_str = "/api/v1/#{@list_type_path}/#{number.id}/add.json"
45
+ puts "Add to #{@account_id}:#{@source_id} -> #{number.id} -> #{path_str}"
46
+ # accounts/25 /sources/5012 /numbers
47
+ # /api/v1/accounts/:account_id/sources/:source_id/numbers/:id/add
48
+ res = self.class.post(path_str, :body => {}.merge(:auth_token => @token))
49
+ if res && res['status'] == 'success'
50
+ CTM::Source.new(res['source'], @token)
51
+ else
52
+ puts res.inspect
53
+ raise CTM::Error::Add.new(res["reason"])
54
+ end
55
+ end
56
+
57
+ def rem
58
+ puts "Rem to #{@account_id}:#{@source_id} -> #{number.id} -> #{@list_type_path}"
59
+ # /api/v1/accounts/:account_id/sources/:source_id/numbers/:id/rem
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,25 @@
1
+ module CTM
2
+ class ReceivingNumber < Base
3
+ attr_reader :id, :account_id
4
+ attr_accessor :name, :number, :formatted, :split
5
+
6
+ def initialize(data, token=nil)
7
+ super(data, token)
8
+ @id = data['id']
9
+ @account_id = data['account_id']
10
+ @name = data['name']
11
+ @number = data['number']
12
+ @formatted = data['formatted']
13
+ @split = data['split']
14
+ end
15
+
16
+ def save
17
+ options = {
18
+ :name => @name,
19
+ :number => @number
20
+ }
21
+ super(options)
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,39 @@
1
+ module CTM
2
+ class ReceivingNumberList < List
3
+ def initialize(options={}, token=nil)
4
+ super('ReceivingNumber', options, token)
5
+ @account_id = options[:account_id]
6
+ @number_id = options[:number_id]
7
+ if @number_id && @account_id
8
+ @list_type_path = "accounts/#{@account_id}/numbers/#{@number_id}/#{@list_token_type}"
9
+ elsif @account_id
10
+ @list_type_path = "accounts/#{@account_id}/#{@list_token_type}"
11
+ else
12
+ @list_type_path = @list_token_type
13
+ end
14
+ end
15
+
16
+ def add(receiving_number)
17
+ path_str = "/api/v1/#{@list_type_path}/#{receiving_number.id}/add.json"
18
+ res = self.class.post(path_str, :body => {}.merge(:auth_token => @token))
19
+ if res && res['status'] == 'success'
20
+ CTM::Number.new(res['receiving_number'], @token)
21
+ else
22
+ puts res.inspect
23
+ raise CTM::Error::Add.new(res["reason"])
24
+ end
25
+ end
26
+
27
+ def rem(receiving_number)
28
+ path_str = "/api/v1/#{@list_type_path}/#{receiving_number.id}/rem.json"
29
+ res = self.class.delete(path_str, :body => {}.merge(:auth_token => @token))
30
+ if res && res['status'] == 'success'
31
+ CTM::Number.new(res['receiving_number'], @token)
32
+ else
33
+ puts res.inspect
34
+ raise CTM::Error::Add.new(res["reason"])
35
+ end
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,8 @@
1
+ module CTM
2
+ class Sale
3
+
4
+ def initialize
5
+ end
6
+
7
+ end
8
+ end
@@ -0,0 +1,33 @@
1
+ module CTM
2
+ class Source < Base
3
+ attr_reader :id, :account_id
4
+ attr_accessor :name, :referring_url, :landing_url, :position, :online
5
+
6
+ def initialize(data, token=nil)
7
+ super(data, token)
8
+ @id = data['id']
9
+ @account_id = data['account_id']
10
+ @name = data['name']
11
+ @referring_url = data['referring_url']
12
+ @landing_url = data['landing_url']
13
+ @position = data['position']
14
+ @online = data['online']
15
+ end
16
+
17
+ def save
18
+ options = {
19
+ :name => @name,
20
+ :position => @position,
21
+ :online => @online,
22
+ :referring_url => @referring_url,
23
+ :landing_url => @landing_url
24
+ }
25
+ super(options)
26
+ end
27
+
28
+ def numbers(options={})
29
+ CTM::NumberList.new(options.merge(:account_id => @account_id, :source_id => @id), @token)
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,15 @@
1
+ module CTM
2
+ class Token
3
+ attr_reader :token, :expires
4
+
5
+ def initialize(data)
6
+ @token = data['token']
7
+ @expires = data['expires']
8
+ end
9
+
10
+ def accounts(options={})
11
+ CTM::List.new('Account', options, @token)
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,30 @@
1
+ module CTM
2
+ class User < Base
3
+ attr_reader :id
4
+ attr_accessor :first_name, :last_name, :email, :role
5
+
6
+ def name
7
+ "#{first_name} #{last_name}"
8
+ end
9
+
10
+ def initialize(data, token=nil)
11
+ super(data, token)
12
+ @id = data['id']
13
+ @first_name = data['first_name']
14
+ @last_name = data['last_name']
15
+ @email = data['email']
16
+ @role = data['role']
17
+ end
18
+
19
+ def save
20
+ options = {
21
+ :first_name => @first_name,
22
+ :last_name => @last_name,
23
+ :email => @email,
24
+ :role => @role
25
+ }
26
+ super(options)
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,15 @@
1
+ module CTM
2
+ class Webhook < Base
3
+ attr_reader :id
4
+ attr_accessor :weburl, :with_resource_url, :position
5
+
6
+ def initialize(data, token=nil)
7
+ super(data, token)
8
+ @id = data['id']
9
+ @weburl = data['weburl']
10
+ @with_resource_url = data['with_resource_url']
11
+ @position = data['position']
12
+ end
13
+
14
+ end
15
+ end
metadata ADDED
@@ -0,0 +1,189 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ctm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - CallTrackingMetrics
9
+ - Todd Fisher
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-04-30 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: phony
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
31
+ - !ruby/object:Gem::Dependency
32
+ name: httparty
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: activesupport
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ - !ruby/object:Gem::Dependency
64
+ name: rack
65
+ requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ~>
69
+ - !ruby/object:Gem::Version
70
+ version: 1.3.0
71
+ type: :development
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ~>
77
+ - !ruby/object:Gem::Version
78
+ version: 1.3.0
79
+ - !ruby/object:Gem::Dependency
80
+ name: mocha
81
+ requirement: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ type: :development
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ - !ruby/object:Gem::Dependency
96
+ name: fakeweb
97
+ requirement: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ~>
101
+ - !ruby/object:Gem::Version
102
+ version: 1.3.0
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 1.3.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ description:
128
+ email: info@calltrackingmetrics.com
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - .gitignore
134
+ - Gemfile
135
+ - Gemfile.lock
136
+ - README.md
137
+ - Rakefile
138
+ - TODO
139
+ - ctm.gemspec
140
+ - examples/buy_numbers.rb
141
+ - examples/example.rb
142
+ - examples/manage_numbers.rb
143
+ - examples/manage_receivng_numbers.rb
144
+ - examples/manage_sources.rb
145
+ - examples/manage_users.rb
146
+ - examples/manage_webhooks.rb
147
+ - lib/ctm.rb
148
+ - lib/ctm/account.rb
149
+ - lib/ctm/auth.rb
150
+ - lib/ctm/available_number.rb
151
+ - lib/ctm/base.rb
152
+ - lib/ctm/call.rb
153
+ - lib/ctm/error.rb
154
+ - lib/ctm/list.rb
155
+ - lib/ctm/number.rb
156
+ - lib/ctm/number_list.rb
157
+ - lib/ctm/receiving_number.rb
158
+ - lib/ctm/receiving_number_list.rb
159
+ - lib/ctm/sale.rb
160
+ - lib/ctm/source.rb
161
+ - lib/ctm/token.rb
162
+ - lib/ctm/user.rb
163
+ - lib/ctm/webhook.rb
164
+ homepage: http://github.com/calltracking/ctm-ruby
165
+ licenses: []
166
+ post_install_message:
167
+ rdoc_options: []
168
+ require_paths:
169
+ - lib
170
+ required_ruby_version: !ruby/object:Gem::Requirement
171
+ none: false
172
+ requirements:
173
+ - - ! '>='
174
+ - !ruby/object:Gem::Version
175
+ version: '0'
176
+ required_rubygems_version: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ! '>='
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ requirements: []
183
+ rubyforge_project:
184
+ rubygems_version: 1.8.24
185
+ signing_key:
186
+ specification_version: 3
187
+ summary: API Library for CallTrackingMetrics
188
+ test_files: []
189
+ has_rdoc: