twitter-ads 0.3.4
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 +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +2 -0
- data/CONTRIBUTING.md +77 -0
- data/LICENSE +22 -0
- data/README.md +111 -0
- data/Rakefile +86 -0
- data/bin/twitter-ads +42 -0
- data/lib/twitter-ads.rb +54 -0
- data/lib/twitter-ads/account.rb +229 -0
- data/lib/twitter-ads/audiences/tailored_audience.rb +177 -0
- data/lib/twitter-ads/campaign/app_list.rb +42 -0
- data/lib/twitter-ads/campaign/campaign.rb +40 -0
- data/lib/twitter-ads/campaign/funding_instrument.rb +33 -0
- data/lib/twitter-ads/campaign/line_item.rb +91 -0
- data/lib/twitter-ads/campaign/promotable_user.rb +28 -0
- data/lib/twitter-ads/campaign/targeting_criteria.rb +77 -0
- data/lib/twitter-ads/campaign/tweet.rb +83 -0
- data/lib/twitter-ads/client.rb +92 -0
- data/lib/twitter-ads/creative/app_download_card.rb +44 -0
- data/lib/twitter-ads/creative/image_app_download_card.rb +44 -0
- data/lib/twitter-ads/creative/image_conversation_card.rb +44 -0
- data/lib/twitter-ads/creative/lead_gen_card.rb +46 -0
- data/lib/twitter-ads/creative/promoted_account.rb +38 -0
- data/lib/twitter-ads/creative/promoted_tweet.rb +87 -0
- data/lib/twitter-ads/creative/video.rb +43 -0
- data/lib/twitter-ads/creative/video_app_download_card.rb +47 -0
- data/lib/twitter-ads/creative/video_conversation_card.rb +46 -0
- data/lib/twitter-ads/creative/website_card.rb +48 -0
- data/lib/twitter-ads/cursor.rb +127 -0
- data/lib/twitter-ads/enum.rb +135 -0
- data/lib/twitter-ads/error.rb +93 -0
- data/lib/twitter-ads/http/request.rb +127 -0
- data/lib/twitter-ads/http/response.rb +74 -0
- data/lib/twitter-ads/http/ton_upload.rb +140 -0
- data/lib/twitter-ads/legacy.rb +7 -0
- data/lib/twitter-ads/resources/analytics.rb +90 -0
- data/lib/twitter-ads/resources/dsl.rb +108 -0
- data/lib/twitter-ads/resources/persistence.rb +43 -0
- data/lib/twitter-ads/resources/resource.rb +92 -0
- data/lib/twitter-ads/targeting/reach_estimate.rb +69 -0
- data/lib/twitter-ads/utils.rb +76 -0
- data/lib/twitter-ads/version.rb +6 -0
- data/spec/fixtures/accounts_all.json +65 -0
- data/spec/fixtures/accounts_features.json +18 -0
- data/spec/fixtures/accounts_load.json +19 -0
- data/spec/fixtures/app_lists_all.json +22 -0
- data/spec/fixtures/app_lists_load.json +31 -0
- data/spec/fixtures/campaigns_all.json +208 -0
- data/spec/fixtures/campaigns_load.json +27 -0
- data/spec/fixtures/funding_instruments_all.json +74 -0
- data/spec/fixtures/funding_instruments_load.json +28 -0
- data/spec/fixtures/line_items_all.json +292 -0
- data/spec/fixtures/line_items_load.json +36 -0
- data/spec/fixtures/placements.json +35 -0
- data/spec/fixtures/promotable_users_all.json +57 -0
- data/spec/fixtures/promotable_users_load.json +18 -0
- data/spec/fixtures/promoted_tweets_all.json +212 -0
- data/spec/fixtures/promoted_tweets_load.json +19 -0
- data/spec/fixtures/reach_estimate.json +19 -0
- data/spec/fixtures/tailored_audiences_all.json +67 -0
- data/spec/fixtures/tailored_audiences_load.json +29 -0
- data/spec/fixtures/tweet_preview.json +24 -0
- data/spec/fixtures/videos_all.json +50 -0
- data/spec/fixtures/videos_load.json +22 -0
- data/spec/quality_spec.rb +15 -0
- data/spec/shared/properties.rb +20 -0
- data/spec/spec_helper.rb +61 -0
- data/spec/support/helpers.rb +42 -0
- data/spec/twitter-ads/account_spec.rb +315 -0
- data/spec/twitter-ads/audiences/tailored_audience_spec.rb +45 -0
- data/spec/twitter-ads/campaign/app_list_spec.rb +108 -0
- data/spec/twitter-ads/campaign/line_item_spec.rb +95 -0
- data/spec/twitter-ads/campaign/reach_estimate_spec.rb +98 -0
- data/spec/twitter-ads/campaign/targeting_criteria_spec.rb +39 -0
- data/spec/twitter-ads/campaign/tweet_spec.rb +83 -0
- data/spec/twitter-ads/client_spec.rb +115 -0
- data/spec/twitter-ads/creative/app_download_card_spec.rb +44 -0
- data/spec/twitter-ads/creative/image_app_download_card_spec.rb +43 -0
- data/spec/twitter-ads/creative/image_conversation_card_spec.rb +40 -0
- data/spec/twitter-ads/creative/lead_gen_card_spec.rb +46 -0
- data/spec/twitter-ads/creative/promoted_account_spec.rb +30 -0
- data/spec/twitter-ads/creative/promoted_tweet_spec.rb +46 -0
- data/spec/twitter-ads/creative/video_app_download_card_spec.rb +42 -0
- data/spec/twitter-ads/creative/video_conversation_card_spec.rb +52 -0
- data/spec/twitter-ads/creative/video_legacy_spec.rb +43 -0
- data/spec/twitter-ads/creative/video_spec.rb +43 -0
- data/spec/twitter-ads/creative/website_card_spec.rb +37 -0
- data/spec/twitter-ads/cursor_spec.rb +67 -0
- data/spec/twitter-ads/placements_spec.rb +36 -0
- data/spec/twitter-ads/utils_spec.rb +101 -0
- data/twitter-ads.gemspec +37 -0
- metadata +247 -0
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# Copyright (C) 2015 Twitter, Inc.
|
|
3
|
+
|
|
4
|
+
module TwitterAds
|
|
5
|
+
class TailoredAudience
|
|
6
|
+
|
|
7
|
+
include TwitterAds::DSL
|
|
8
|
+
include TwitterAds::Resource
|
|
9
|
+
|
|
10
|
+
attr_reader :account
|
|
11
|
+
|
|
12
|
+
property :id, read_only: true
|
|
13
|
+
property :created_at, type: :time, read_only: true
|
|
14
|
+
property :updated_at, type: :time, read_only: true
|
|
15
|
+
property :deleted, type: :bool, read_only: true
|
|
16
|
+
|
|
17
|
+
property :name
|
|
18
|
+
property :list_type
|
|
19
|
+
|
|
20
|
+
property :audience_size, read_only: true
|
|
21
|
+
property :audience_type, read_only: true
|
|
22
|
+
property :metadata, read_only: true
|
|
23
|
+
property :partner_source, read_only: true
|
|
24
|
+
property :reasons_not_targetable, read_only: true
|
|
25
|
+
property :targetable, type: :bool, read_only: true
|
|
26
|
+
property :targetable_types, read_only: true
|
|
27
|
+
|
|
28
|
+
RESOURCE_COLLECTION = '/0/accounts/%{account_id}/tailored_audiences'.freeze # @api private
|
|
29
|
+
RESOURCE = '/0/accounts/%{account_id}/tailored_audiences/%{id}'.freeze # @api private
|
|
30
|
+
RESOURCE_UPDATE = '/0/accounts/%{account_id}/tailored_audience_changes'.freeze # @api private
|
|
31
|
+
GLOBAL_OPT_OUT =
|
|
32
|
+
'/0/accounts/%{account_id}/tailored_audiences/global_opt_out'.freeze # @api private
|
|
33
|
+
|
|
34
|
+
LIST_TYPES = %w(
|
|
35
|
+
EMAIL
|
|
36
|
+
DEVICE_ID
|
|
37
|
+
TWITTER_ID
|
|
38
|
+
HANDLE
|
|
39
|
+
PHONE_NUMBER
|
|
40
|
+
).freeze
|
|
41
|
+
|
|
42
|
+
OPERATIONS = %w(
|
|
43
|
+
ADD
|
|
44
|
+
REMOVE
|
|
45
|
+
REPLACE
|
|
46
|
+
).freeze
|
|
47
|
+
|
|
48
|
+
def initialize(account)
|
|
49
|
+
@account = account
|
|
50
|
+
self
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
class << self
|
|
54
|
+
|
|
55
|
+
# Creates a new tailored audience.
|
|
56
|
+
#
|
|
57
|
+
# @example
|
|
58
|
+
# audience = TailoredAudience.create(account, '/path/to/file', 'my list', 'EMAIL')
|
|
59
|
+
#
|
|
60
|
+
# @param account [Account] The account object instance.
|
|
61
|
+
# @param file_path [String] The path to the file to be uploaded.
|
|
62
|
+
# @param name [String] The tailored audience name.
|
|
63
|
+
# @param list_type [String] The tailored audience list type.
|
|
64
|
+
#
|
|
65
|
+
# @since 0.3.0
|
|
66
|
+
#
|
|
67
|
+
# @return [TailoredAudience] The newly created tailored audience instance.
|
|
68
|
+
def create(account, file_path, name, list_type)
|
|
69
|
+
upload = TwitterAds::TONUpload.new(account.client, file_path)
|
|
70
|
+
|
|
71
|
+
audience = new(account)
|
|
72
|
+
audience.send(:create_audience, name, list_type)
|
|
73
|
+
|
|
74
|
+
begin
|
|
75
|
+
audience.send(:update_audience, audience, upload.perform, list_type, 'ADD')
|
|
76
|
+
audience.reload!
|
|
77
|
+
rescue TwitterAds::ClientError => e
|
|
78
|
+
audience.delete!
|
|
79
|
+
raise e
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Updates the global opt-out list for the specified advertiser account.
|
|
84
|
+
#
|
|
85
|
+
# @example
|
|
86
|
+
# TailoredAudience.opt_out(account, '/path/to/file', 'EMAIL')
|
|
87
|
+
#
|
|
88
|
+
# @param account [Account] The account object instance.
|
|
89
|
+
# @param file_path [String] The path to the file to be uploaded.
|
|
90
|
+
# @param list_type [String] The tailored audience list type.
|
|
91
|
+
#
|
|
92
|
+
# @since 0.3.0
|
|
93
|
+
#
|
|
94
|
+
# @return [Boolean] The result of the opt-out update.
|
|
95
|
+
def opt_out(account, file_path, list_type)
|
|
96
|
+
upload = TwitterAds::TONUpload.new(account.client, file_path)
|
|
97
|
+
params = { input_file_path: upload.perform, list_type: list_type }
|
|
98
|
+
resource = GLOBAL_OPT_OUT % { account_id: account.id }
|
|
99
|
+
Request.new(account.client, :put, resource, params: params).perform
|
|
100
|
+
true
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Updates the current tailored audience instance.
|
|
106
|
+
#
|
|
107
|
+
# @example
|
|
108
|
+
# audience = account.tailored_audiences('xyz')
|
|
109
|
+
# audience.update('/path/to/file', 'EMAIL', 'REPLACE')
|
|
110
|
+
#
|
|
111
|
+
# @param file_path [String] The path to the file to be uploaded.
|
|
112
|
+
# @param list_type [String] The tailored audience list type.
|
|
113
|
+
# @param operation [String] The update operation type (Default: 'ADD').
|
|
114
|
+
#
|
|
115
|
+
# @since 0.3.0
|
|
116
|
+
#
|
|
117
|
+
# @return [TailoredAudience] [description]
|
|
118
|
+
def update(file_path, list_type, operation = 'ADD')
|
|
119
|
+
upload = TwitterAds::TONUpload.new(account.client, file_path)
|
|
120
|
+
update_audience(self, upload.perform, list_type, operation)
|
|
121
|
+
reload!
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Deletes the current tailored audience instance.
|
|
125
|
+
#
|
|
126
|
+
# @example
|
|
127
|
+
# audience.delete!
|
|
128
|
+
#
|
|
129
|
+
# Note: calls to this method are destructive and irreverisble.
|
|
130
|
+
#
|
|
131
|
+
# @since 0.3.0
|
|
132
|
+
#
|
|
133
|
+
# @return [self] Returns the tailored audience instance refreshed from the API.
|
|
134
|
+
def delete!
|
|
135
|
+
resource = RESOURCE % { account_id: account.id, id: id }
|
|
136
|
+
response = Request.new(account.client, :delete, resource).perform
|
|
137
|
+
from_response(response.body[:data])
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Returns the status of all changes for the current tailored audience instance.
|
|
141
|
+
#
|
|
142
|
+
# @example
|
|
143
|
+
# audience.status
|
|
144
|
+
#
|
|
145
|
+
# @since 0.3.0
|
|
146
|
+
#
|
|
147
|
+
# @return [Hash] Returns a hash object representing the tailored audience status.
|
|
148
|
+
def status
|
|
149
|
+
return nil unless id
|
|
150
|
+
resource = RESOURCE_UPDATE % { account_id: account.id }
|
|
151
|
+
request = Request.new(account.client, :get, resource, params: to_params)
|
|
152
|
+
Cursor.new(nil, request).to_a.select { |change| change[:tailored_audience_id] == id }
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
private
|
|
156
|
+
|
|
157
|
+
def create_audience(name, list_type)
|
|
158
|
+
params = { name: name, list_type: list_type }
|
|
159
|
+
resource = RESOURCE_COLLECTION % { account_id: account.id }
|
|
160
|
+
response = Request.new(account.client, :post, resource, params: params).perform
|
|
161
|
+
from_response(response.body[:data])
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def update_audience(audience, location, list_type, operation)
|
|
165
|
+
params = {
|
|
166
|
+
tailored_audience_id: audience.id,
|
|
167
|
+
input_file_path: location,
|
|
168
|
+
list_type: list_type,
|
|
169
|
+
operation: operation
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
resource = RESOURCE_UPDATE % { account_id: audience.account.id }
|
|
173
|
+
Request.new(audience.account.client, :post, resource, params: params).perform
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
end
|
|
177
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# Copyright (C) 2015 Twitter, Inc.
|
|
3
|
+
|
|
4
|
+
module TwitterAds
|
|
5
|
+
class AppList
|
|
6
|
+
|
|
7
|
+
include TwitterAds::DSL
|
|
8
|
+
include TwitterAds::Resource
|
|
9
|
+
|
|
10
|
+
attr_reader :account
|
|
11
|
+
|
|
12
|
+
property :id, read_only: true
|
|
13
|
+
property :apps, read_only: true
|
|
14
|
+
property :name, read_only: true
|
|
15
|
+
|
|
16
|
+
RESOURCE_COLLECTION = '/0/accounts/%{account_id}/app_lists'.freeze # @api private
|
|
17
|
+
RESOURCE = '/0/accounts/%{account_id}/app_lists/%{id}'.freeze # @api private
|
|
18
|
+
|
|
19
|
+
def initialize(account)
|
|
20
|
+
@account = account
|
|
21
|
+
self
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Creates a new App List
|
|
25
|
+
#
|
|
26
|
+
# @param name [String] The name for the app list to be created.
|
|
27
|
+
# @param ids [String] String or String Array of app IDs.
|
|
28
|
+
#
|
|
29
|
+
# @return [self] Returns the instance refreshed from the API
|
|
30
|
+
def create(name, *ids)
|
|
31
|
+
resource = self.class::RESOURCE_COLLECTION % { account_id: account.id }
|
|
32
|
+
params = to_params.merge!(app_store_identifiers: ids.join(','), name: name)
|
|
33
|
+
response = Request.new(account.client, :post, resource, params: params).perform
|
|
34
|
+
from_response(response.body[:data])
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def apps
|
|
38
|
+
reload! if @id && !@apps
|
|
39
|
+
@apps
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# Copyright (C) 2015 Twitter, Inc.
|
|
3
|
+
|
|
4
|
+
module TwitterAds
|
|
5
|
+
class Campaign
|
|
6
|
+
|
|
7
|
+
include TwitterAds::DSL
|
|
8
|
+
include TwitterAds::Resource
|
|
9
|
+
include TwitterAds::Persistence
|
|
10
|
+
|
|
11
|
+
attr_reader :account
|
|
12
|
+
|
|
13
|
+
property :id, read_only: true
|
|
14
|
+
property :reasons_not_servable, read_only: true
|
|
15
|
+
property :servable, read_only: true
|
|
16
|
+
property :deleted, type: :bool, read_only: true
|
|
17
|
+
property :created_at, type: :time, read_only: true
|
|
18
|
+
property :updated_at, type: :time, read_only: true
|
|
19
|
+
|
|
20
|
+
property :name
|
|
21
|
+
property :funding_instrument_id
|
|
22
|
+
property :end_time, type: :time
|
|
23
|
+
property :start_time, type: :time
|
|
24
|
+
property :paused, type: :bool
|
|
25
|
+
property :currency
|
|
26
|
+
property :standard_delivery
|
|
27
|
+
property :daily_budget_amount_local_micro
|
|
28
|
+
property :total_budget_amount_local_micro
|
|
29
|
+
|
|
30
|
+
RESOURCE_COLLECTION = '/0/accounts/%{account_id}/campaigns'.freeze # @api private
|
|
31
|
+
RESOURCE_STATS = '/0/stats/accounts/%{account_id}/campaigns'.freeze # @api private
|
|
32
|
+
RESOURCE = '/0/accounts/%{account_id}/campaigns/%{id}'.freeze # @api private
|
|
33
|
+
|
|
34
|
+
def initialize(account)
|
|
35
|
+
@account = account
|
|
36
|
+
self
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# Copyright (C) 2015 Twitter, Inc.
|
|
3
|
+
|
|
4
|
+
module TwitterAds
|
|
5
|
+
class FundingInstrument
|
|
6
|
+
|
|
7
|
+
include TwitterAds::DSL
|
|
8
|
+
include TwitterAds::Resource
|
|
9
|
+
|
|
10
|
+
attr_reader :account
|
|
11
|
+
|
|
12
|
+
property :id, read_only: true
|
|
13
|
+
property :name, read_only: true
|
|
14
|
+
property :cancelled, read_only: true
|
|
15
|
+
property :credit_limit_local_micro, read_only: true
|
|
16
|
+
property :currency, read_only: true
|
|
17
|
+
property :description, read_only: true
|
|
18
|
+
property :funded_amount_local_micro, read_only: true
|
|
19
|
+
property :type, read_only: true
|
|
20
|
+
property :created_at, type: :time, read_only: true
|
|
21
|
+
property :updated_at, type: :time, read_only: true
|
|
22
|
+
property :deleted, type: :bool, read_only: true
|
|
23
|
+
|
|
24
|
+
RESOURCE_COLLECTION = '/0/accounts/%{account_id}/funding_instruments'.freeze # @api private
|
|
25
|
+
RESOURCE = '/0/accounts/%{account_id}/funding_instruments/%{id}'.freeze # @api private
|
|
26
|
+
|
|
27
|
+
def initialize(account)
|
|
28
|
+
@account = account
|
|
29
|
+
self
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# Copyright (C) 2015 Twitter, Inc.
|
|
3
|
+
|
|
4
|
+
module TwitterAds
|
|
5
|
+
class LineItem
|
|
6
|
+
|
|
7
|
+
include TwitterAds::DSL
|
|
8
|
+
include TwitterAds::Resource
|
|
9
|
+
include TwitterAds::Persistence
|
|
10
|
+
include TwitterAds::Analytics
|
|
11
|
+
|
|
12
|
+
attr_reader :account
|
|
13
|
+
|
|
14
|
+
property :id, read_only: true
|
|
15
|
+
property :deleted, type: :bool, read_only: true
|
|
16
|
+
property :created_at, type: :time, read_only: true
|
|
17
|
+
property :updated_at, type: :time, read_only: true
|
|
18
|
+
|
|
19
|
+
property :name
|
|
20
|
+
property :campaign_id
|
|
21
|
+
property :advertiser_domain
|
|
22
|
+
property :categories
|
|
23
|
+
property :charge_by
|
|
24
|
+
property :include_sentiment
|
|
25
|
+
property :objective
|
|
26
|
+
property :optimization
|
|
27
|
+
property :paused, type: :bool
|
|
28
|
+
property :primary_web_event_tag
|
|
29
|
+
property :product_type
|
|
30
|
+
property :placements
|
|
31
|
+
property :bid_unit
|
|
32
|
+
property :automatically_select_bid
|
|
33
|
+
property :bid_amount_local_micro
|
|
34
|
+
property :total_budget_amount_local_micro
|
|
35
|
+
|
|
36
|
+
RESOURCE_COLLECTION = '/0/accounts/%{account_id}/line_items'.freeze # @api private
|
|
37
|
+
RESOURCE_STATS = '/0/stats/accounts/%{account_id}/line_items'.freeze # @api private
|
|
38
|
+
RESOURCE = '/0/accounts/%{account_id}/line_items/%{id}'.freeze # @api private
|
|
39
|
+
|
|
40
|
+
def initialize(account)
|
|
41
|
+
@account = account
|
|
42
|
+
self
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Overload for CUSTOM objective deprecation warning.
|
|
46
|
+
# @private
|
|
47
|
+
def objective=(value)
|
|
48
|
+
if value == TwitterAds::Objective::CUSTOM
|
|
49
|
+
TwitterAds::Utils.deprecated('TwitterAds::Objective::CUSTOM')
|
|
50
|
+
end
|
|
51
|
+
@objective = value
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
class << self
|
|
55
|
+
|
|
56
|
+
# Helper method to return a list a valid placement combinations by Product.
|
|
57
|
+
#
|
|
58
|
+
# @example
|
|
59
|
+
# LineItem.placements(Product::PROMOTED_TWEETS)
|
|
60
|
+
#
|
|
61
|
+
# @param product_type [Product] The enum value for the Product type being targeted.
|
|
62
|
+
#
|
|
63
|
+
# @return [Array] An array of valid placement combinations.
|
|
64
|
+
#
|
|
65
|
+
# @since 0.3.2
|
|
66
|
+
# @see https://dev.twitter.com/ads/reference/get/line_items/placements
|
|
67
|
+
def placements(client, product_type = nil)
|
|
68
|
+
resource = '/0/line_items/placements'
|
|
69
|
+
params = { product_type: product_type } if product_type
|
|
70
|
+
response = TwitterAds::Request.new(client, :get, resource, params: params).perform
|
|
71
|
+
response.body[:data][0][:placements]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Returns a collection of targeting criteria available to the current line item.
|
|
77
|
+
#
|
|
78
|
+
# @param id [String] The TargetingCriteria ID value.
|
|
79
|
+
# @param opts [Hash] A Hash of extended options.
|
|
80
|
+
# @option opts [Boolean] :with_deleted Indicates if deleted items should be included.
|
|
81
|
+
# @option opts [String] :sort_by The object param to sort the API response by.
|
|
82
|
+
#
|
|
83
|
+
# @since 0.3.1
|
|
84
|
+
#
|
|
85
|
+
# @return A Cursor or object instance.
|
|
86
|
+
def targeting_criteria(id = nil, opts = {})
|
|
87
|
+
id ? TargetingCriteria.load(account, id, opts) : TargetingCriteria.all(account, @id, opts)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# Copyright (C) 2015 Twitter, Inc.
|
|
3
|
+
|
|
4
|
+
module TwitterAds
|
|
5
|
+
class PromotableUser
|
|
6
|
+
|
|
7
|
+
include TwitterAds::DSL
|
|
8
|
+
include TwitterAds::Resource
|
|
9
|
+
|
|
10
|
+
attr_reader :account
|
|
11
|
+
|
|
12
|
+
property :id, read_only: true
|
|
13
|
+
property :promotable_user_type, read_only: true
|
|
14
|
+
property :user_id, read_only: true
|
|
15
|
+
property :created_at, type: :time, read_only: true
|
|
16
|
+
property :updated_at, type: :time, read_only: true
|
|
17
|
+
property :deleted, type: :bool, read_only: true
|
|
18
|
+
|
|
19
|
+
RESOURCE_COLLECTION = '/0/accounts/%{account_id}/promotable_users'.freeze # @api private
|
|
20
|
+
RESOURCE = '/0/accounts/%{account_id}/promotable_users/%{id}'.freeze # @api private
|
|
21
|
+
|
|
22
|
+
def initialize(account)
|
|
23
|
+
@account = account
|
|
24
|
+
self
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# Copyright (C) 2015 Twitter, Inc.
|
|
3
|
+
|
|
4
|
+
module TwitterAds
|
|
5
|
+
class TargetingCriteria
|
|
6
|
+
|
|
7
|
+
include TwitterAds::DSL
|
|
8
|
+
include TwitterAds::Persistence
|
|
9
|
+
include TwitterAds::Resource::InstanceMethods
|
|
10
|
+
|
|
11
|
+
attr_reader :account
|
|
12
|
+
|
|
13
|
+
property :id, read_only: true
|
|
14
|
+
property :name, read_only: true
|
|
15
|
+
property :localized_name, read_only: true
|
|
16
|
+
property :created_at, type: :time, read_only: true
|
|
17
|
+
property :updated_at, type: :time, read_only: true
|
|
18
|
+
property :deleted, type: :bool, read_only: true
|
|
19
|
+
|
|
20
|
+
property :line_item_id
|
|
21
|
+
property :targeting_type
|
|
22
|
+
property :targeting_value
|
|
23
|
+
property :tailored_audience_expansion, type: :bool
|
|
24
|
+
property :tailored_audience_type
|
|
25
|
+
|
|
26
|
+
RESOURCE_COLLECTION = '/0/accounts/%{account_id}/targeting_criteria'.freeze # @api private
|
|
27
|
+
RESOURCE = '/0/accounts/%{account_id}/targeting_criteria/%{id}'.freeze # @api private
|
|
28
|
+
|
|
29
|
+
def initialize(account)
|
|
30
|
+
@account = account
|
|
31
|
+
self
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class << self
|
|
35
|
+
|
|
36
|
+
# Returns a Cursor instance for a given resource.
|
|
37
|
+
#
|
|
38
|
+
# @param account [Account] The Account object instance.
|
|
39
|
+
# @param line_item_id [String] The line item ID string.
|
|
40
|
+
# @param opts [Hash] An optional Hash of extended options.
|
|
41
|
+
# @option opts [Boolean] :with_deleted Indicates if deleted items should be included.
|
|
42
|
+
# @option opts [String] :sort_by The object param to sort the API response by.
|
|
43
|
+
#
|
|
44
|
+
# @return [Cursor] A Cusor object ready to iterate through the API response.
|
|
45
|
+
#
|
|
46
|
+
# @since 0.3.1
|
|
47
|
+
# @see Cursor
|
|
48
|
+
# @see https://dev.twitter.com/ads/basics/sorting Sorting
|
|
49
|
+
def all(account, line_item_id, opts = {})
|
|
50
|
+
params = { line_item_id: line_item_id }.merge!(opts)
|
|
51
|
+
resource = RESOURCE_COLLECTION % { account_id: account.id }
|
|
52
|
+
request = Request.new(account.client, :get, resource, params: params)
|
|
53
|
+
Cursor.new(self, request, init_with: [account])
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Returns an object instance for a given resource.
|
|
57
|
+
#
|
|
58
|
+
# @param account [Account] The Account object instance.
|
|
59
|
+
# @param id [String] The ID of the specific object to be loaded.
|
|
60
|
+
# @param opts [Hash] An optional Hash of extended options.
|
|
61
|
+
# @option opts [Boolean] :with_deleted Indicates if deleted items should be included.
|
|
62
|
+
# @option opts [String] :sort_by The object param to sort the API response by.
|
|
63
|
+
#
|
|
64
|
+
# @return [self] The object instance for the specified resource.
|
|
65
|
+
#
|
|
66
|
+
# @since 0.3.1
|
|
67
|
+
def load(account, id, opts = {})
|
|
68
|
+
params = { with_deleted: true }.merge!(opts)
|
|
69
|
+
resource = RESOURCE % { account_id: account.id, id: id }
|
|
70
|
+
response = Request.new(account.client, :get, resource, params: params).perform
|
|
71
|
+
new(account).from_response(response.body[:data])
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
end
|
|
77
|
+
end
|