twitter-ads 6.0.1 → 9.0.0
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 +5 -5
- data/LICENSE +1 -2
- data/README.md +1 -1
- data/lib/twitter-ads.rb +5 -4
- data/lib/twitter-ads/account.rb +4 -23
- data/lib/twitter-ads/audiences/{tailored_audience.rb → custom_audience.rb} +85 -30
- data/lib/twitter-ads/{targeting_criteria/behavior_taxonomy.rb → campaign/advertiser_business_categories.rb} +6 -6
- data/lib/twitter-ads/campaign/content_categories.rb +23 -0
- data/lib/twitter-ads/campaign/line_item.rb +6 -6
- data/lib/twitter-ads/campaign/targeting_criteria.rb +1 -0
- data/lib/twitter-ads/client.rb +1 -1
- data/lib/twitter-ads/creative/cards.rb +56 -0
- data/lib/twitter-ads/creative/media_creative.rb +1 -1
- data/lib/twitter-ads/creative/promoted_tweet.rb +1 -1
- data/lib/twitter-ads/enum.rb +29 -34
- data/lib/twitter-ads/http/request.rb +7 -1
- data/lib/twitter-ads/resources/analytics.rb +1 -0
- data/lib/twitter-ads/targeting/audience_summary.rb +47 -0
- data/lib/twitter-ads/targeting_criteria/event.rb +1 -0
- data/lib/twitter-ads/version.rb +1 -1
- data/spec/fixtures/audience_summary.json +14 -0
- data/spec/fixtures/custom_audiences_all.json +67 -0
- data/spec/fixtures/{tailored_audiences_load.json → custom_audiences_load.json} +0 -0
- data/spec/fixtures/line_items_all.json +2 -10
- data/spec/fixtures/line_items_load.json +0 -1
- data/spec/fixtures/tailored_audiences_all.json +3 -0
- data/spec/fixtures/targeted_audiences.json +33 -0
- data/spec/spec_helper.rb +1 -4
- data/spec/twitter-ads/account_spec.rb +11 -11
- data/spec/twitter-ads/audiences/{tailored_audience_spec.rb → custom_audience_spec.rb} +3 -2
- data/spec/twitter-ads/campaign/line_item_spec.rb +6 -3
- data/spec/twitter-ads/campaign/targeting_criteria_spec.rb +1 -0
- data/spec/twitter-ads/creative/media_creative_spec.rb +1 -1
- data/spec/twitter-ads/creative/promoted_tweet_spec.rb +18 -0
- data/spec/twitter-ads/targeting/audience_summary_spec.rb +41 -0
- metadata +53 -47
- data/lib/twitter-ads/targeting/reach_estimate.rb +0 -78
- data/lib/twitter-ads/targeting_criteria/behavior.rb +0 -27
- data/spec/twitter-ads/campaign/reach_estimate_spec.rb +0 -103
data/lib/twitter-ads/client.rb
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Copyright (C) 2019 Twitter, Inc.
|
3
|
+
|
4
|
+
module TwitterAds
|
5
|
+
module Creative
|
6
|
+
|
7
|
+
class Cards
|
8
|
+
|
9
|
+
include TwitterAds::DSL
|
10
|
+
include TwitterAds::Resource
|
11
|
+
include TwitterAds::Persistence
|
12
|
+
|
13
|
+
attr_reader :account
|
14
|
+
|
15
|
+
property :card_uri, read_only: true
|
16
|
+
property :created_at, type: :time, read_only: true
|
17
|
+
property :deleted, type: :bool, read_only: true
|
18
|
+
property :updated_at, type: :time, read_only: true
|
19
|
+
# these are writable, but not in the sense that they can be set on an object and then saved
|
20
|
+
property :name, read_only: true
|
21
|
+
property :components, read_only: true
|
22
|
+
|
23
|
+
RESOURCE = "/#{TwitterAds::API_VERSION}/" +
|
24
|
+
'accounts/%{account_id}/cards' # @api private
|
25
|
+
|
26
|
+
def load(*)
|
27
|
+
raise ArgumentError.new(
|
28
|
+
"'Cards' object has no attribute 'load'")
|
29
|
+
end
|
30
|
+
|
31
|
+
def reload(*)
|
32
|
+
raise ArgumentError.new(
|
33
|
+
"'Cards' object has no attribute 'reload'")
|
34
|
+
end
|
35
|
+
|
36
|
+
def create(account, name, components)
|
37
|
+
resource = RESOURCE % { account_id: account.id }
|
38
|
+
params = { 'name': name, 'components': components }
|
39
|
+
headers = { 'Content-Type' => 'application/json' }
|
40
|
+
response = Request.new(account.client,
|
41
|
+
:post,
|
42
|
+
resource,
|
43
|
+
headers: headers,
|
44
|
+
body: params.to_json).perform
|
45
|
+
from_response(response.body[:data])
|
46
|
+
end
|
47
|
+
|
48
|
+
def initialize(account)
|
49
|
+
@account = account
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -16,7 +16,7 @@ module TwitterAds
|
|
16
16
|
property :created_at, type: :time, read_only: true
|
17
17
|
property :deleted, type: :bool, read_only: true
|
18
18
|
property :id, read_only: true
|
19
|
-
property :
|
19
|
+
property :entity_status, read_only: true
|
20
20
|
property :updated_at, type: :time, read_only: true
|
21
21
|
|
22
22
|
property :account_media_id
|
@@ -48,7 +48,7 @@ module TwitterAds
|
|
48
48
|
|
49
49
|
# convert to `tweet_ids` param
|
50
50
|
params = to_params
|
51
|
-
params[:tweet_ids] =
|
51
|
+
params[:tweet_ids] = params.delete(:tweet_id) if params.key?(:tweet_id)
|
52
52
|
|
53
53
|
if @id
|
54
54
|
raise TwitterAds::NotFound.new(nil, 'Method PUT not allowed.', 404)
|
data/lib/twitter-ads/enum.rb
CHANGED
@@ -9,13 +9,12 @@ module TwitterAds
|
|
9
9
|
module Objective
|
10
10
|
APP_ENGAGEMENTS = 'APP_ENGAGEMENTS'
|
11
11
|
APP_INSTALLS = 'APP_INSTALLS'
|
12
|
+
ENGAGEMENTS = 'ENGAGEMENTS'
|
12
13
|
FOLLOWERS = 'FOLLOWERS'
|
13
|
-
|
14
|
-
|
14
|
+
PREROLL_VIEWS = 'PREROLL_VIEWS'
|
15
|
+
REACH = 'REACH'
|
15
16
|
VIDEO_VIEWS = 'VIDEO_VIEWS'
|
16
17
|
WEBSITE_CLICKS = 'WEBSITE_CLICKS'
|
17
|
-
WEBSITE_CONVERSIONS = 'WEBSITE_CONVERSIONS'
|
18
|
-
|
19
18
|
end
|
20
19
|
|
21
20
|
module Product
|
@@ -24,10 +23,15 @@ module TwitterAds
|
|
24
23
|
end
|
25
24
|
|
26
25
|
module Placement
|
27
|
-
ALL_ON_TWITTER
|
28
|
-
TWITTER_SEARCH
|
29
|
-
TWITTER_TIMELINE
|
30
|
-
PUBLISHER_NETWORK
|
26
|
+
ALL_ON_TWITTER = 'ALL_ON_TWITTER'
|
27
|
+
TWITTER_SEARCH = 'TWITTER_SEARCH'
|
28
|
+
TWITTER_TIMELINE = 'TWITTER_TIMELINE'
|
29
|
+
PUBLISHER_NETWORK = 'PUBLISHER_NETWORK'
|
30
|
+
TAP_FULL = 'TAP_FULL'
|
31
|
+
TAP_FULL_LANDSCAPE = 'TAP_FULL_LANDSCAPE'
|
32
|
+
TAP_BANNER = 'TAP_BANNER'
|
33
|
+
TAP_NATIVE = 'TAP_NATIVE'
|
34
|
+
TAP_MRECT = 'TAP_MRECT'
|
31
35
|
end
|
32
36
|
|
33
37
|
module Placement
|
@@ -55,32 +59,31 @@ module TwitterAds
|
|
55
59
|
end
|
56
60
|
end
|
57
61
|
|
58
|
-
module
|
59
|
-
|
60
|
-
|
61
|
-
ENGAGEMENT
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
62
|
+
module Goal
|
63
|
+
APP_CLICKS = 'APP_CLICKS'
|
64
|
+
APP_INSTALLS = 'APP_INSTALLS'
|
65
|
+
ENGAGEMENT = 'ENGAGEMENT'
|
66
|
+
FOLLOWERS = 'FOLLOWERS'
|
67
|
+
LINK_CLICKS = 'LINK_CLICKS'
|
68
|
+
MAX_REACH = 'MAX_REACH'
|
69
|
+
PREROLL = 'PREROLL'
|
70
|
+
PREROLL_STARTS = 'PREROLL_STARTS'
|
71
|
+
REACH_WITH_ENGAGEMENT = 'REACH_WITH_ENGAGEMENT'
|
72
|
+
VIDEO_VIEW = 'VIDEO_VIEW'
|
66
73
|
VIEW_3S_100PCT = 'VIEW_3S_100PCT'
|
74
|
+
VIEW_6S = 'VIEW_6S'
|
75
|
+
VIEW_15S = 'VIEW_15S'
|
76
|
+
WEBSITE_CONVERSIONS = 'WEBSITE_CONVERSIONS'
|
67
77
|
end
|
68
78
|
|
69
|
-
module
|
79
|
+
module BidStrategy
|
70
80
|
MAX = 'MAX'
|
71
81
|
AUTO = 'AUTO'
|
72
82
|
TARGET = 'TARGET'
|
73
83
|
end
|
74
84
|
|
75
|
-
module
|
76
|
-
APP_CLICK
|
77
|
-
APP_INSTALL = 'APP_INSTALL'
|
78
|
-
ENGAGEMENT = 'ENGAGEMENT'
|
79
|
-
FOLLOW = 'FOLLOW'
|
80
|
-
LEAD = 'LEAD'
|
81
|
-
LINK_CLICK = 'LINK_CLICK'
|
82
|
-
VIEW = 'VIEW'
|
83
|
-
VIEW_3S_100PCT = 'VIEW_3S_100PCT'
|
85
|
+
module PayBy
|
86
|
+
APP_CLICK = 'APP_CLICK'
|
84
87
|
end
|
85
88
|
|
86
89
|
module MetricGroup
|
@@ -143,14 +146,6 @@ module TwitterAds
|
|
143
146
|
VIDEO = 'VIDEO'
|
144
147
|
end
|
145
148
|
|
146
|
-
module Optimizations
|
147
|
-
APP_CLICKS = 'APP_CLICKS'
|
148
|
-
APP_INSTALLS = 'APP_INSTALLS'
|
149
|
-
DEFAULT = 'DEFAULT'
|
150
|
-
ENGAGEMENTS = 'ENGAGEMENTS'
|
151
|
-
WEBSITE_CONVERSIONS = 'WEBSITE_CONVERSIONS'
|
152
|
-
end
|
153
|
-
|
154
149
|
module Granularity
|
155
150
|
HOUR = 'HOUR'
|
156
151
|
DAY = 'DAY'
|
@@ -107,11 +107,17 @@ module TwitterAds
|
|
107
107
|
Response.new(response.code, response.each {}, response.body)
|
108
108
|
end
|
109
109
|
|
110
|
+
def escape_params(input)
|
111
|
+
input.map do |key, value|
|
112
|
+
"#{CGI.escape key.to_s}=#{CGI.escape value.to_s}"
|
113
|
+
end.join('&')
|
114
|
+
end
|
115
|
+
|
110
116
|
def http_request
|
111
117
|
request_url = @resource
|
112
118
|
|
113
119
|
if @options[:params] && !@options[:params].empty?
|
114
|
-
request_url += "?#{
|
120
|
+
request_url += "?#{escape_params(@options[:params])}"
|
115
121
|
end
|
116
122
|
|
117
123
|
request = HTTP_METHOD[@method].new(request_url)
|
@@ -30,6 +30,7 @@ module TwitterAds
|
|
30
30
|
property :metric_groups, read_only: true
|
31
31
|
|
32
32
|
ANALYTICS_MAP = {
|
33
|
+
'TwitterAds::Account' => Entity::ACCOUNT,
|
33
34
|
'TwitterAds::Campaign' => Entity::CAMPAIGN,
|
34
35
|
'TwitterAds::LineItem' => Entity::LINE_ITEM,
|
35
36
|
'TwitterAds::OrganicTweet' => Entity::ORGANIC_TWEET,
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Copyright (C) 2019 Twitter, Inc.
|
3
|
+
|
4
|
+
module TwitterAds
|
5
|
+
module AudienceSummary
|
6
|
+
|
7
|
+
include TwitterAds::DSL
|
8
|
+
include TwitterAds::Resource
|
9
|
+
|
10
|
+
RESOURCE = "/#{TwitterAds::API_VERSION}/" \
|
11
|
+
'accounts/%{account_id}/audience_summary'
|
12
|
+
|
13
|
+
property :audience_size, read_only: true
|
14
|
+
|
15
|
+
class << self
|
16
|
+
|
17
|
+
# Get an audience summary for the specified targeting criteria.
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# TwitterAds::AudienceSummary.fetch(
|
21
|
+
# account,
|
22
|
+
# params: {targeting_criteria:[{targeting_type:'LOCATION',
|
23
|
+
# targeting_value:'96683cc9126741d1'}]}
|
24
|
+
# )
|
25
|
+
#
|
26
|
+
# @param params [Hash] A hash of input targeting criteria values
|
27
|
+
#
|
28
|
+
# @return [Hash] A hash containing the min and max audience size.
|
29
|
+
#
|
30
|
+
# @since 7.0.0
|
31
|
+
# @see https://developer.twitter.com/en/docs/ads/campaign-management/api-reference/audience-summary
|
32
|
+
def fetch(account, params)
|
33
|
+
resource = RESOURCE % { account_id: account.id }
|
34
|
+
headers = { 'Content-Type' => 'application/json' }
|
35
|
+
|
36
|
+
response = TwitterAds::Request.new(account.client,
|
37
|
+
:post,
|
38
|
+
resource,
|
39
|
+
headers: headers,
|
40
|
+
body: params.to_json).perform
|
41
|
+
response.body[:data]
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -21,6 +21,7 @@ module TwitterAds
|
|
21
21
|
property :gender_breakdown_percentage, read_only: true
|
22
22
|
property :device_breakdown_percentage, read_only: true
|
23
23
|
property :country_breakdown_percentage, read_only: true
|
24
|
+
property :targeting_value, read_only: true
|
24
25
|
|
25
26
|
RESOURCE_COLLECTION = "/#{TwitterAds::API_VERSION}/" \
|
26
27
|
'targeting_criteria/events' # @api private
|
data/lib/twitter-ads/version.rb
CHANGED
@@ -0,0 +1,67 @@
|
|
1
|
+
{
|
2
|
+
"request": {
|
3
|
+
"params": {
|
4
|
+
"account_id": "2iqph"
|
5
|
+
}
|
6
|
+
},
|
7
|
+
"data": [
|
8
|
+
{
|
9
|
+
"targetable": false,
|
10
|
+
"name": "TA #2",
|
11
|
+
"targetable_types": [
|
12
|
+
"WEB",
|
13
|
+
"EXCLUDED_WEB"
|
14
|
+
],
|
15
|
+
"audience_type": "WEB",
|
16
|
+
"id": "abc2",
|
17
|
+
"reasons_not_targetable": [
|
18
|
+
"TOO_SMALL"
|
19
|
+
],
|
20
|
+
"list_type": null,
|
21
|
+
"created_at": "2014-03-09T20:35:41Z",
|
22
|
+
"updated_at": "2014-06-11T09:38:06Z",
|
23
|
+
"partner_source": "OTHER",
|
24
|
+
"deleted": false,
|
25
|
+
"audience_size": null
|
26
|
+
},
|
27
|
+
{
|
28
|
+
"targetable": true,
|
29
|
+
"name": "TA #1",
|
30
|
+
"targetable_types": [
|
31
|
+
"CRM",
|
32
|
+
"EXCLUDED_CRM"
|
33
|
+
],
|
34
|
+
"audience_type": "CRM",
|
35
|
+
"id": "abc1",
|
36
|
+
"reasons_not_targetable": [],
|
37
|
+
"list_type": "DEVICE_ID",
|
38
|
+
"created_at": "2014-05-22T17:37:12Z",
|
39
|
+
"updated_at": "2014-05-22T21:05:33Z",
|
40
|
+
"partner_source": "OTHER",
|
41
|
+
"deleted": false,
|
42
|
+
"audience_size": null
|
43
|
+
},
|
44
|
+
{
|
45
|
+
"targetable": false,
|
46
|
+
"name": "TA #3",
|
47
|
+
"targetable_types": [
|
48
|
+
"CRM",
|
49
|
+
"EXCLUDED_CRM"
|
50
|
+
],
|
51
|
+
"audience_type": "CRM",
|
52
|
+
"id": "abc3",
|
53
|
+
"reasons_not_targetable": [
|
54
|
+
"TOO_SMALL"
|
55
|
+
],
|
56
|
+
"list_type": "EMAIL",
|
57
|
+
"created_at": "2014-05-22T21:43:45Z",
|
58
|
+
"updated_at": "2014-05-23T02:27:31Z",
|
59
|
+
"partner_source": "OTHER",
|
60
|
+
"deleted": false,
|
61
|
+
"audience_size": null
|
62
|
+
}
|
63
|
+
],
|
64
|
+
"data_type": "tailored_audiences",
|
65
|
+
"total_count": 3,
|
66
|
+
"next_cursor": null
|
67
|
+
}
|
File without changes
|
@@ -29,7 +29,6 @@
|
|
29
29
|
"currency": "USD",
|
30
30
|
"created_at": "2011-07-11T20:36:11Z",
|
31
31
|
"updated_at": "2011-09-04T19:39:51Z",
|
32
|
-
"include_sentiment": null,
|
33
32
|
"campaign_id": "2wap7",
|
34
33
|
"deleted": false
|
35
34
|
},
|
@@ -57,7 +56,6 @@
|
|
57
56
|
"currency": "USD",
|
58
57
|
"created_at": "2011-07-13T20:56:39Z",
|
59
58
|
"updated_at": "2011-09-04T19:39:04Z",
|
60
|
-
"include_sentiment": null,
|
61
59
|
"campaign_id": "2wamv",
|
62
60
|
"deleted": false
|
63
61
|
},
|
@@ -85,7 +83,6 @@
|
|
85
83
|
"currency": "USD",
|
86
84
|
"created_at": "2011-07-14T00:04:47Z",
|
87
85
|
"updated_at": "2011-09-04T19:39:39Z",
|
88
|
-
"include_sentiment": null,
|
89
86
|
"campaign_id": "2wai9",
|
90
87
|
"deleted": false
|
91
88
|
},
|
@@ -113,7 +110,6 @@
|
|
113
110
|
"currency": "USD",
|
114
111
|
"created_at": "2011-08-22T22:42:18Z",
|
115
112
|
"updated_at": "2011-09-04T19:40:02Z",
|
116
|
-
"include_sentiment": null,
|
117
113
|
"campaign_id": "2of1n",
|
118
114
|
"deleted": false
|
119
115
|
},
|
@@ -141,7 +137,7 @@
|
|
141
137
|
"currency": "JPY",
|
142
138
|
"created_at": "2011-08-26T20:51:14Z",
|
143
139
|
"updated_at": "2011-08-26T21:30:25Z",
|
144
|
-
|
140
|
+
|
145
141
|
"campaign_id": "2w9n1",
|
146
142
|
"deleted": true
|
147
143
|
},
|
@@ -169,7 +165,7 @@
|
|
169
165
|
"currency": "USD",
|
170
166
|
"created_at": "2011-08-26T21:38:51Z",
|
171
167
|
"updated_at": "2011-08-26T22:24:37Z",
|
172
|
-
|
168
|
+
|
173
169
|
"campaign_id": "2vuug",
|
174
170
|
"deleted": true
|
175
171
|
},
|
@@ -197,7 +193,6 @@
|
|
197
193
|
"currency": "JPY",
|
198
194
|
"created_at": "2011-08-26T22:28:55Z",
|
199
195
|
"updated_at": "2011-09-04T19:38:46Z",
|
200
|
-
"include_sentiment": null,
|
201
196
|
"campaign_id": "2vuj3",
|
202
197
|
"deleted": false
|
203
198
|
},
|
@@ -225,7 +220,6 @@
|
|
225
220
|
"currency": "USD",
|
226
221
|
"created_at": "2011-09-01T17:25:04Z",
|
227
222
|
"updated_at": "2011-09-16T02:56:55Z",
|
228
|
-
"include_sentiment": null,
|
229
223
|
"campaign_id": "2v3c4",
|
230
224
|
"deleted": true
|
231
225
|
},
|
@@ -253,7 +247,6 @@
|
|
253
247
|
"currency": "JPY",
|
254
248
|
"created_at": "2011-09-06T17:42:52Z",
|
255
249
|
"updated_at": "2011-09-30T18:54:18Z",
|
256
|
-
"include_sentiment": null,
|
257
250
|
"campaign_id": "2ttv3",
|
258
251
|
"deleted": false
|
259
252
|
},
|
@@ -281,7 +274,6 @@
|
|
281
274
|
"currency": "USD",
|
282
275
|
"created_at": "2011-09-06T22:44:13Z",
|
283
276
|
"updated_at": "2011-09-20T01:32:27Z",
|
284
|
-
"include_sentiment": null,
|
285
277
|
"campaign_id": "2ttv3",
|
286
278
|
"deleted": true
|
287
279
|
}
|