twitter_ads 0.0.4 → 0.0.5

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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZjE0ZmFmYWFmMmJiYzc5MzFjY2E5YmI5M2FjZjlmN2ViM2ZkZTQwYQ==
4
+ YWU0OWMyZGY5MWFhMzIzNDhkZDM1OTNjOTI2OWZjMGY4MjFhMTY3ZA==
5
5
  data.tar.gz: !binary |-
6
- OWU0OGJmM2VmMGFjMWFkMDIyMjA0Zjk4NjU5NjFmYmY4NDZlYzA1NQ==
6
+ OTUyYTM2MjdhMmYxZmI5YWFkOTA3YTY0OGQ0NjlmNGJkNGE2N2RjMg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MTcwMDE4MjgwYTY3ZDgyM2Y0YWZiZWMyNjkyM2U5NmU1ZWJhNGVlNGU5ZWQy
10
- ODUzZjIwYzk1Zjk0ZmFkZDBkZDJkNmNmMTYzZGZiZTc5Zjc0YzBlNGE2OGYx
11
- NGYyNTg0MjFhMjM4MDJjNTMxZGFkYjRlYzQxMTk1ZTdlMmUyZTQ=
9
+ YjAzNGQxYzYxODUxOWEyZWQwOTNiN2VmYmI2MzRjYTJmM2UzMjVhNGQ3NDE0
10
+ NTFmNDZiMDRkYWZkZDc2MGIwZDRlNmVkZTRkNmYzODBjYWJlMWNkMGYzZjEz
11
+ NTVlY2Y0ZDE4NjUxMTQ0MGM4ZGQ3ODMyOTAzMDFlNjUzODMxZWM=
12
12
  data.tar.gz: !binary |-
13
- MWRlNDg0NzA2NGNjNmI4Mjg2MzM0ODgwYmQ0MjdmM2E5YmM5MThiZWZhY2Yw
14
- YmEyODIzZjg2NGYwMjAyNzEyZTI5NzZkY2EwNzE4NTk4M2VmOWY1N2RmNTE0
15
- MzRhMDc2YjcwZTU2MTM4NTYwMjhmMWViYTJkYTRkYmEyYzE1ZjE=
13
+ ODI3ZjljNDU0Yzk2OTczNmVlMThiMjBiNGQ3MGFiZTA2YzlkZDhiMDZmZDdi
14
+ ZWQ3NzQxM2UwNGU2YjI0NTYzMzJhNjdiMzk2M2MyYWEwYzRjZmVhZGExYjQ2
15
+ MDZkMDk3NzZlODUzMzA3OWMxNDI0Y2M4MThiOGNhZmFhZTEwOWM=
@@ -0,0 +1,43 @@
1
+ #
2
+ # @ Seevibes 2015
3
+ # Author Thomas Landspurg
4
+ #
5
+ # thomas@seevibes.com
6
+ #
7
+ #
8
+
9
+
10
+ module TwitterAds
11
+
12
+
13
+ class Account < RestResource
14
+
15
+ attr_reader
16
+
17
+ def initialize(client, account)
18
+ @client = client
19
+ @attributes = account
20
+ init
21
+ @prefix = "accounts/#{@id}/"
22
+ @ops = {
23
+ :get => [
24
+ :promoted_accounts, :promoted_tweets, :tailored_audience_changes,
25
+ :targeting_criteria, :app_lists, :campaigns, :funding_instruments,
26
+ :line_items, :promoted_accounts, :promotable_users, :reach_estimate,
27
+ :targeting_suggestions,:tailored_audiences
28
+ ],
29
+ :post => [:tailored_audiences, :tailored_audience_changes, :campaigns],
30
+ :put => [:campaigns, :promoted_tweets, :targeting_criteria, 'tailored_audiences__global_opt_out'],
31
+ :delete => [:tailored_audiences, :campaigns, :promoted_tweets, :targeting_criteria]
32
+ }
33
+ end
34
+ def tailored_audiences
35
+ get('tailored_audiences').map{ |ta| TailoredAudience.new(self, ta)}
36
+ end
37
+
38
+ def tailored_audience tailored_audience_id
39
+ TwitterAds::TailoredAudience.new(self, {'id' => tailored_audience_id})
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,39 @@
1
+ #
2
+ # @ Seevibes 2015
3
+ # Author Thomas Landspurg
4
+ #
5
+ # thomas@seevibes.com
6
+ #
7
+ #
8
+
9
+ module TwitterAds
10
+
11
+
12
+ class Client < RestResource
13
+ attr_reader :config, :access_token, :ops
14
+
15
+ def initialize(params)
16
+ @config = params
17
+ @ops = { get: [:bidding_rules, :iab_categories] }
18
+ @attributes={}
19
+ consumer = OAuth::Consumer.new(params[:consumer_key], params[:consumer_secret], site: "https://#{ADS_API_ENDPOINT}")
20
+ consumer.http.use_ssl = true
21
+ consumer.http.set_debug_output(STDERR)
22
+ consumer.http.verify_mode = OpenSSL::SSL::VERIFY_NONE
23
+ @client = self # To manage rest resource
24
+ @access_token = OAuth::AccessToken.new(consumer, params[:access_token], params[:access_secret])
25
+ end
26
+
27
+ # return the list of available accounts
28
+ def accounts
29
+ @cached_accounts = get('accounts').map { |account| Account.new(self, account) } unless @cached_accounts
30
+ @cached_accounts
31
+ end
32
+
33
+ # Create an account based on his id
34
+ def account(account_id)
35
+ TwitterAds::Account.new(self, {'id' => account_id})
36
+ end
37
+ end
38
+
39
+ end
@@ -0,0 +1,109 @@
1
+ #
2
+ # @ Seevibes 2015
3
+ # Author Thomas Landspurg
4
+ #
5
+ # thomas@seevibes.com
6
+ #
7
+ #
8
+
9
+
10
+ module TwitterAds
11
+
12
+
13
+
14
+ # Common class to manage access to recourse
15
+ # Need access to client, prefix, and ops available on this ressource
16
+ #
17
+ # provide operation oauth autenthificated operation (get/post/put/delete)
18
+ # as well as dynamically discovered opertions, using the ops instance variable
19
+ #
20
+ class RestResource
21
+ @prefix = ''
22
+ attr :access_token, :prefix, :client, :attributes, :id, :name
23
+
24
+ def init
25
+ @id = @attributes['id']
26
+ @name = @attributes['name']
27
+ end
28
+
29
+ # Utility funciton to do a get on the RES API
30
+ def get(action = '', params = nil)
31
+ do_request :get, action, params
32
+ end
33
+
34
+ def post(action, params = nil)
35
+ do_request :post, action, params
36
+ end
37
+
38
+ def put(action, params = nil)
39
+ do_request :put, action, params
40
+ end
41
+
42
+ def delete(action = '', params = nil)
43
+ do_request :delete, action, params
44
+ end
45
+
46
+ def do_request(verb, action, params)
47
+ url = "https://#{ADS_API_ENDPOINT}/0/#{prefix}#{action}"
48
+ url = url[0..-2] if url[-1] == '/'
49
+
50
+ # TODO: add a logger
51
+ puts "Doing request:#{verb} #{prefix} #{action} #{params} URL:#{url}" if TRACE
52
+ res = ::MultiJson.load(@client.access_token.request(verb, url, params).body)
53
+
54
+ # TODO: pretty format the errors
55
+ raise AdsError, res['errors'].first['code'] if res['errors']
56
+ res['data']
57
+ end
58
+
59
+
60
+ # Dynamic check of methods
61
+ # tab_ops contain the list of allowed method and verbs
62
+ # prefix the prefix to add to the method
63
+ #
64
+ def check_method(tab_ops, prefix, method_sym, do_call, *arguments, &block)
65
+ method_sym = method_sym.id2name
66
+ verb = :get
67
+ [:post, :get, :delete, :put].each do |averb|
68
+ if method_sym.start_with? averb.id2name
69
+ verb = averb
70
+ method_sym[averb.id2name + '_'] = ''
71
+ break
72
+ end
73
+ end
74
+ if tab_ops[verb].include? method_sym.to_sym
75
+ if do_call
76
+ params = arguments.first
77
+ method = prefix + method_sym
78
+ method += "/#{params.shift}" if params.first && params.first.class != Hash
79
+ return do_request verb, method, params.shift
80
+ else
81
+ return nil
82
+ end
83
+ end
84
+ nil
85
+ end
86
+
87
+ def method_missing(method_sym, *arguments, &block)
88
+ # the first argument is a Symbol, so you need to_s it if you want to pattern match
89
+ check_method(@ops, '', method_sym, true, arguments, block) || super
90
+ end
91
+
92
+ def respond_to?(method_sym)
93
+ if check_method(@ops, '', method_sym.to_sym, false, '', nil)
94
+ return true
95
+ end
96
+ super
97
+ end
98
+
99
+ def as_json
100
+ @attributes
101
+ end
102
+
103
+ def refresh
104
+ @attributes = get('')
105
+ init
106
+ end
107
+ end
108
+
109
+ end
@@ -0,0 +1,27 @@
1
+ #
2
+ # @ Seevibes 2015
3
+ # Author Thomas Landspurg
4
+ #
5
+ # thomas@seevibes.com
6
+ #
7
+ #
8
+
9
+ module TwitterAds
10
+
11
+ class TailoredAudience < RestResource
12
+
13
+ attr_reader :account
14
+
15
+ def initialize(account,tailored_audience_hash)
16
+ @account = account
17
+ @client = account.client
18
+ @attributes = tailored_audience_hash
19
+ init
20
+ @prefix = "accounts/#{account.id}/tailored_audiences/#{@id}"
21
+ puts "Prefix: #{@prefix}"
22
+ @ops = {
23
+ }
24
+ end
25
+
26
+ end
27
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twitter_ads
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Landspurg
@@ -31,6 +31,10 @@ extensions: []
31
31
  extra_rdoc_files: []
32
32
  files:
33
33
  - lib/twitter_ads.rb
34
+ - lib/twitter_ads/account.rb
35
+ - lib/twitter_ads/client.rb
36
+ - lib/twitter_ads/rest_ressource.rb
37
+ - lib/twitter_ads/tailored_audience.rb
34
38
  homepage: https://github.com/seevibes/twitter_ads
35
39
  licenses:
36
40
  - MIT