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.
Files changed (39) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE +1 -2
  3. data/README.md +1 -1
  4. data/lib/twitter-ads.rb +5 -4
  5. data/lib/twitter-ads/account.rb +4 -23
  6. data/lib/twitter-ads/audiences/{tailored_audience.rb → custom_audience.rb} +85 -30
  7. data/lib/twitter-ads/{targeting_criteria/behavior_taxonomy.rb → campaign/advertiser_business_categories.rb} +6 -6
  8. data/lib/twitter-ads/campaign/content_categories.rb +23 -0
  9. data/lib/twitter-ads/campaign/line_item.rb +6 -6
  10. data/lib/twitter-ads/campaign/targeting_criteria.rb +1 -0
  11. data/lib/twitter-ads/client.rb +1 -1
  12. data/lib/twitter-ads/creative/cards.rb +56 -0
  13. data/lib/twitter-ads/creative/media_creative.rb +1 -1
  14. data/lib/twitter-ads/creative/promoted_tweet.rb +1 -1
  15. data/lib/twitter-ads/enum.rb +29 -34
  16. data/lib/twitter-ads/http/request.rb +7 -1
  17. data/lib/twitter-ads/resources/analytics.rb +1 -0
  18. data/lib/twitter-ads/targeting/audience_summary.rb +47 -0
  19. data/lib/twitter-ads/targeting_criteria/event.rb +1 -0
  20. data/lib/twitter-ads/version.rb +1 -1
  21. data/spec/fixtures/audience_summary.json +14 -0
  22. data/spec/fixtures/custom_audiences_all.json +67 -0
  23. data/spec/fixtures/{tailored_audiences_load.json → custom_audiences_load.json} +0 -0
  24. data/spec/fixtures/line_items_all.json +2 -10
  25. data/spec/fixtures/line_items_load.json +0 -1
  26. data/spec/fixtures/tailored_audiences_all.json +3 -0
  27. data/spec/fixtures/targeted_audiences.json +33 -0
  28. data/spec/spec_helper.rb +1 -4
  29. data/spec/twitter-ads/account_spec.rb +11 -11
  30. data/spec/twitter-ads/audiences/{tailored_audience_spec.rb → custom_audience_spec.rb} +3 -2
  31. data/spec/twitter-ads/campaign/line_item_spec.rb +6 -3
  32. data/spec/twitter-ads/campaign/targeting_criteria_spec.rb +1 -0
  33. data/spec/twitter-ads/creative/media_creative_spec.rb +1 -1
  34. data/spec/twitter-ads/creative/promoted_tweet_spec.rb +18 -0
  35. data/spec/twitter-ads/targeting/audience_summary_spec.rb +41 -0
  36. metadata +53 -47
  37. data/lib/twitter-ads/targeting/reach_estimate.rb +0 -78
  38. data/lib/twitter-ads/targeting_criteria/behavior.rb +0 -27
  39. data/spec/twitter-ads/campaign/reach_estimate_spec.rb +0 -103
@@ -3,7 +3,7 @@
3
3
 
4
4
  module TwitterAds
5
5
 
6
- API_VERSION = '6'
6
+ API_VERSION = '9'
7
7
 
8
8
  # The Ads API Client class which functions as a
9
9
  # container for basic API consumer information.
@@ -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 :serving_status, read_only: true
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] = *params.delete(:tweet_id) if params.key?(:tweet_id)
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)
@@ -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
- LEAD_GENERATION = 'LEAD_GENERATION'
14
- TWEET_ENGAGEMENTS = 'TWEET_ENGAGEMENTS'
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 = 'ALL_ON_TWITTER'
28
- TWITTER_SEARCH = 'TWITTER_SEARCH'
29
- TWITTER_TIMELINE = 'TWITTER_TIMELINE'
30
- PUBLISHER_NETWORK = '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 BidUnit
59
- APP_CLICK = 'APP_CLICK'
60
- APP_INSTALL = 'APP_INSTALL'
61
- ENGAGEMENT = 'ENGAGEMENT'
62
- FOLLOW = 'FOLLOW'
63
- LEAD = 'LEAD'
64
- LINK_CLICK = 'LINK_CLICK'
65
- VIEW = 'VIEW'
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 BidType
79
+ module BidStrategy
70
80
  MAX = 'MAX'
71
81
  AUTO = 'AUTO'
72
82
  TARGET = 'TARGET'
73
83
  end
74
84
 
75
- module ChargeBy
76
- APP_CLICK = '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 += "?#{URI.encode_www_form(@options[:params])}"
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
@@ -2,5 +2,5 @@
2
2
  # Copyright (C) 2019 Twitter, Inc.
3
3
 
4
4
  module TwitterAds
5
- VERSION = '6.0.1'
5
+ VERSION = '9.0.0'
6
6
  end
@@ -0,0 +1,14 @@
1
+ {
2
+ "request": {
3
+ "params": {
4
+ "targeting_criteria": null,
5
+ "account_id": "2iqph"
6
+ }
7
+ },
8
+ "data": {
9
+ "audience_size": {
10
+ "min": 41133600,
11
+ "max": 50274400
12
+ }
13
+ }
14
+ }
@@ -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
+ }
@@ -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
- "include_sentiment": "POSITIVE_ONLY",
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
- "include_sentiment": "POSITIVE_ONLY",
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
  }