twitter-ads 8.0.0 → 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 +4 -4
- data/lib/twitter-ads.rb +2 -1
- data/lib/twitter-ads/account.rb +4 -4
- data/lib/twitter-ads/audiences/{tailored_audience.rb → custom_audience.rb} +30 -30
- data/lib/twitter-ads/campaign/line_item.rb +4 -5
- data/lib/twitter-ads/client.rb +1 -1
- data/lib/twitter-ads/creative/cards.rb +56 -0
- data/lib/twitter-ads/enum.rb +17 -26
- data/lib/twitter-ads/resources/analytics.rb +1 -0
- data/lib/twitter-ads/version.rb +1 -1
- data/spec/fixtures/custom_audiences_all.json +67 -0
- data/spec/fixtures/{tailored_audiences_load.json → custom_audiences_load.json} +0 -0
- data/spec/twitter-ads/account_spec.rb +11 -11
- data/spec/twitter-ads/audiences/custom_audience_spec.rb +46 -0
- data/spec/twitter-ads/campaign/line_item_spec.rb +6 -2
- metadata +46 -43
- data/spec/twitter-ads/audiences/tailored_audience_spec.rb +0 -68
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ab4c35b2b3ff9a24fb3475717b923563c484d80b2ac7e981c18570ddbaebdbc
|
4
|
+
data.tar.gz: e5f228604a745b96a063c59d80248bd976f27a4cc43243cd34a0f45a55548cb0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d17c433739bebd2d74a7c62c20e58819f5f4ea29e241b3dd53ec4baeba4e55213761a27f40833d497b356638a8057770ab7a16f73578df96732555f511ddd43c
|
7
|
+
data.tar.gz: 2aff371a6a36636f82adce64fa00766bcd6e5257a6c288ea58f06740df3bb879008bc1e2afe8b286c8b0b1e431ce5bf413a011562cae9e5594f65133f5d63752
|
data/lib/twitter-ads.rb
CHANGED
@@ -29,7 +29,7 @@ require 'twitter-ads/http/response'
|
|
29
29
|
|
30
30
|
require 'twitter-ads/restapi.rb'
|
31
31
|
|
32
|
-
require 'twitter-ads/audiences/
|
32
|
+
require 'twitter-ads/audiences/custom_audience'
|
33
33
|
|
34
34
|
require 'twitter-ads/campaign/app_list'
|
35
35
|
require 'twitter-ads/campaign/campaign'
|
@@ -58,6 +58,7 @@ require 'twitter-ads/targeting_criteria/app_store_category'
|
|
58
58
|
|
59
59
|
require 'twitter-ads/creative/account_media'
|
60
60
|
require 'twitter-ads/creative/cards_fetch'
|
61
|
+
require 'twitter-ads/creative/cards'
|
61
62
|
require 'twitter-ads/creative/image_app_download_card'
|
62
63
|
require 'twitter-ads/creative/image_conversation_card'
|
63
64
|
require 'twitter-ads/creative/media_creative'
|
data/lib/twitter-ads/account.rb
CHANGED
@@ -232,9 +232,9 @@ module TwitterAds
|
|
232
232
|
load_resource(AppList, id, opts)
|
233
233
|
end
|
234
234
|
|
235
|
-
# Returns a collection of
|
235
|
+
# Returns a collection of custom audiences available to the current account.
|
236
236
|
#
|
237
|
-
# @param id [String] The
|
237
|
+
# @param id [String] The CustomAudience ID value.
|
238
238
|
# @param opts [Hash] A Hash of extended options.
|
239
239
|
# @option opts [Boolean] :with_deleted Indicates if deleted items should be included.
|
240
240
|
# @option opts [String] :sort_by The object param to sort the API response by.
|
@@ -242,8 +242,8 @@ module TwitterAds
|
|
242
242
|
# @since 0.3.0
|
243
243
|
#
|
244
244
|
# @return A Cursor or object instance.
|
245
|
-
def
|
246
|
-
load_resource(
|
245
|
+
def custom_audiences(id = nil, opts = {})
|
246
|
+
load_resource(CustomAudience, id, opts)
|
247
247
|
end
|
248
248
|
|
249
249
|
def authenticated_user_access
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# Copyright (C) 2019 Twitter, Inc.
|
3
3
|
|
4
4
|
module TwitterAds
|
5
|
-
class
|
5
|
+
class CustomAudience
|
6
6
|
|
7
7
|
include TwitterAds::DSL
|
8
8
|
include TwitterAds::Resource
|
@@ -19,19 +19,19 @@ module TwitterAds
|
|
19
19
|
|
20
20
|
property :audience_size, read_only: true
|
21
21
|
property :audience_type, read_only: true
|
22
|
-
property :metadata, read_only: true
|
23
|
-
property :owner_account_id, read_only: true
|
24
22
|
property :partner_source, read_only: true
|
25
23
|
property :reasons_not_targetable, read_only: true
|
26
24
|
property :targetable, type: :bool, read_only: true
|
27
25
|
property :targetable_types, read_only: true
|
26
|
+
property :permission_level, read_only: true
|
27
|
+
property :owner_account_id, read_only: true
|
28
28
|
|
29
29
|
RESOURCE_COLLECTION = "/#{TwitterAds::API_VERSION}/" \
|
30
|
-
'accounts/%{account_id}/
|
30
|
+
'accounts/%{account_id}/custom_audiences' # @api private
|
31
31
|
RESOURCE = "/#{TwitterAds::API_VERSION}/" \
|
32
|
-
'accounts/%{account_id}/
|
32
|
+
'accounts/%{account_id}/custom_audiences/%{id}' # @api private
|
33
33
|
RESOURCE_USERS = "/#{TwitterAds::API_VERSION}/" \
|
34
|
-
'accounts/%{account_id}/
|
34
|
+
'accounts/%{account_id}/custom_audiences/' \
|
35
35
|
'%{id}/users' # @api private
|
36
36
|
|
37
37
|
LIST_TYPES = %w(
|
@@ -55,17 +55,17 @@ module TwitterAds
|
|
55
55
|
|
56
56
|
class << self
|
57
57
|
|
58
|
-
# Creates a new
|
58
|
+
# Creates a new custom audience.
|
59
59
|
#
|
60
60
|
# @example
|
61
|
-
# audience =
|
61
|
+
# audience = CustomAudience.create(account, 'my list')
|
62
62
|
#
|
63
63
|
# @param account [Account] The account object instance.
|
64
|
-
# @param name [String] The
|
64
|
+
# @param name [String] The custom audience name.
|
65
65
|
#
|
66
66
|
# @since 4.0
|
67
67
|
#
|
68
|
-
# @return [
|
68
|
+
# @return [CustomAudience] The newly created custom audience instance.
|
69
69
|
def create(account, name)
|
70
70
|
audience = new(account)
|
71
71
|
params = { name: name }
|
@@ -76,7 +76,7 @@ module TwitterAds
|
|
76
76
|
|
77
77
|
end
|
78
78
|
|
79
|
-
# Deletes the current
|
79
|
+
# Deletes the current custom audience instance.
|
80
80
|
#
|
81
81
|
# @example
|
82
82
|
# audience.delete!
|
@@ -85,7 +85,7 @@ module TwitterAds
|
|
85
85
|
#
|
86
86
|
# @since 0.3.0
|
87
87
|
#
|
88
|
-
# @return [self] Returns the
|
88
|
+
# @return [self] Returns the custom audience instance refreshed from the API.
|
89
89
|
def delete!
|
90
90
|
resource = RESOURCE % { account_id: account.id, id: id }
|
91
91
|
response = Request.new(account.client, :delete, resource).perform
|
@@ -95,11 +95,11 @@ module TwitterAds
|
|
95
95
|
# This is a private API and requires allowlisting from Twitter.
|
96
96
|
#
|
97
97
|
# This endpoint will allow partners to add, update and remove users from a given
|
98
|
-
#
|
98
|
+
# custom_audience_id.
|
99
99
|
# The endpoint will also accept multiple user identifier types per user as well.
|
100
100
|
#
|
101
101
|
# @example
|
102
|
-
#
|
102
|
+
# custom_audience.users(
|
103
103
|
# account,
|
104
104
|
# [
|
105
105
|
# {
|
@@ -194,7 +194,7 @@ module TwitterAds
|
|
194
194
|
end
|
195
195
|
end
|
196
196
|
|
197
|
-
class
|
197
|
+
class CustomAudiencePermission
|
198
198
|
|
199
199
|
include TwitterAds::DSL
|
200
200
|
include TwitterAds::Resource
|
@@ -207,16 +207,16 @@ module TwitterAds
|
|
207
207
|
property :deleted, type: :bool, read_only: true
|
208
208
|
|
209
209
|
property :id
|
210
|
-
property :
|
210
|
+
property :custom_audience_id
|
211
211
|
property :granted_account_id
|
212
212
|
property :permission_level
|
213
213
|
|
214
214
|
RESOURCE_COLLECTION = "/#{TwitterAds::API_VERSION}/" \
|
215
|
-
'accounts/%{account_id}/
|
216
|
-
'%{
|
215
|
+
'accounts/%{account_id}/custom_audiences/' \
|
216
|
+
'%{custom_audience_id}/permissions' # @api private
|
217
217
|
RESOURCE = "/#{TwitterAds::API_VERSION}/" \
|
218
|
-
'accounts/%{account_id}/
|
219
|
-
'%{
|
218
|
+
'accounts/%{account_id}/custom_audiences/' \
|
219
|
+
'%{custom_audience_id}/permissions/%{id}' # @api private
|
220
220
|
|
221
221
|
def initialize(account)
|
222
222
|
@account = account
|
@@ -226,22 +226,22 @@ module TwitterAds
|
|
226
226
|
class << self
|
227
227
|
|
228
228
|
# Retrieve details for some or
|
229
|
-
# all permissions associated with the specified
|
229
|
+
# all permissions associated with the specified custom audience.
|
230
230
|
#
|
231
231
|
# @exapmle
|
232
|
-
# permissions =
|
232
|
+
# permissions = CustomAudiencePermission.all(account, '36n4f')
|
233
233
|
#
|
234
234
|
# @param account [Account] The account object instance.
|
235
|
-
# @param
|
235
|
+
# @param custom_audience_id [String] The custom audience id.
|
236
236
|
#
|
237
237
|
# @since 5.2.0
|
238
238
|
#
|
239
|
-
# @return [
|
240
|
-
def all(account,
|
239
|
+
# @return [CustomAudiencePermission] The custom audience permission instance.
|
240
|
+
def all(account, custom_audience_id, opts = {})
|
241
241
|
params = {}.merge!(opts)
|
242
242
|
resource = RESOURCE_COLLECTION % {
|
243
243
|
account_id: account.id,
|
244
|
-
|
244
|
+
custom_audience_id: custom_audience_id
|
245
245
|
}
|
246
246
|
request = Request.new(account.client, :get, resource, params: params)
|
247
247
|
Cursor.new(self, request, init_with: [account])
|
@@ -250,7 +250,7 @@ module TwitterAds
|
|
250
250
|
end
|
251
251
|
|
252
252
|
# Saves or updates the current object instance
|
253
|
-
# depending on the presence of `object.
|
253
|
+
# depending on the presence of `object.custom_audience_id`.
|
254
254
|
#
|
255
255
|
# @exapmle
|
256
256
|
# object.save
|
@@ -261,14 +261,14 @@ module TwitterAds
|
|
261
261
|
def save
|
262
262
|
resource = RESOURCE_COLLECTION % {
|
263
263
|
account_id: account.id,
|
264
|
-
|
264
|
+
custom_audience_id: custom_audience_id
|
265
265
|
}
|
266
266
|
params = to_params
|
267
267
|
response = Request.new(account.client, :post, resource, params: params).perform
|
268
268
|
from_response(response.body[:data])
|
269
269
|
end
|
270
270
|
|
271
|
-
# Deletes the current or specified
|
271
|
+
# Deletes the current or specified custom audience permission.
|
272
272
|
#
|
273
273
|
# @example
|
274
274
|
# object.delete!
|
@@ -281,7 +281,7 @@ module TwitterAds
|
|
281
281
|
def delete!
|
282
282
|
resource = RESOURCE % {
|
283
283
|
account_id: account.id,
|
284
|
-
|
284
|
+
custom_audience_id: custom_audience_id,
|
285
285
|
id: @id
|
286
286
|
}
|
287
287
|
response = Request.new(account.client, :delete, resource).perform
|
@@ -18,18 +18,19 @@ module TwitterAds
|
|
18
18
|
|
19
19
|
property :advertiser_domain
|
20
20
|
property :android_app_store_identifier
|
21
|
+
property :audience_expansion
|
21
22
|
property :automatically_select_bid
|
22
23
|
property :bid_amount_local_micro
|
23
|
-
property :
|
24
|
+
property :bid_strategy
|
24
25
|
property :campaign_id
|
25
26
|
property :categories
|
26
|
-
property :charge_by
|
27
27
|
property :end_time, type: :time
|
28
28
|
property :entity_status
|
29
|
+
property :goal
|
29
30
|
property :ios_app_store_identifier
|
30
31
|
property :name
|
31
32
|
property :objective
|
32
|
-
property :
|
33
|
+
property :pay_by
|
33
34
|
property :placements
|
34
35
|
property :primary_web_event_tag
|
35
36
|
property :product_type
|
@@ -38,9 +39,7 @@ module TwitterAds
|
|
38
39
|
|
39
40
|
# beta (not yet generally available)
|
40
41
|
property :advertiser_user_id
|
41
|
-
property :bid_type
|
42
42
|
property :tracking_tags
|
43
|
-
property :audience_expansion
|
44
43
|
|
45
44
|
# sdk only
|
46
45
|
property :to_delete, type: :bool
|
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
|
data/lib/twitter-ads/enum.rb
CHANGED
@@ -59,32 +59,31 @@ module TwitterAds
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
module
|
63
|
-
|
64
|
-
|
65
|
-
ENGAGEMENT
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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'
|
70
73
|
VIEW_3S_100PCT = 'VIEW_3S_100PCT'
|
74
|
+
VIEW_6S = 'VIEW_6S'
|
75
|
+
VIEW_15S = 'VIEW_15S'
|
76
|
+
WEBSITE_CONVERSIONS = 'WEBSITE_CONVERSIONS'
|
71
77
|
end
|
72
78
|
|
73
|
-
module
|
79
|
+
module BidStrategy
|
74
80
|
MAX = 'MAX'
|
75
81
|
AUTO = 'AUTO'
|
76
82
|
TARGET = 'TARGET'
|
77
83
|
end
|
78
84
|
|
79
|
-
module
|
80
|
-
APP_CLICK
|
81
|
-
APP_INSTALL = 'APP_INSTALL'
|
82
|
-
ENGAGEMENT = 'ENGAGEMENT'
|
83
|
-
FOLLOW = 'FOLLOW'
|
84
|
-
LEAD = 'LEAD'
|
85
|
-
LINK_CLICK = 'LINK_CLICK'
|
86
|
-
VIEW = 'VIEW'
|
87
|
-
VIEW_3S_100PCT = 'VIEW_3S_100PCT'
|
85
|
+
module PayBy
|
86
|
+
APP_CLICK = 'APP_CLICK'
|
88
87
|
end
|
89
88
|
|
90
89
|
module MetricGroup
|
@@ -147,14 +146,6 @@ module TwitterAds
|
|
147
146
|
VIDEO = 'VIDEO'
|
148
147
|
end
|
149
148
|
|
150
|
-
module Optimizations
|
151
|
-
APP_CLICKS = 'APP_CLICKS'
|
152
|
-
APP_INSTALLS = 'APP_INSTALLS'
|
153
|
-
DEFAULT = 'DEFAULT'
|
154
|
-
ENGAGEMENTS = 'ENGAGEMENTS'
|
155
|
-
WEBSITE_CONVERSIONS = 'WEBSITE_CONVERSIONS'
|
156
|
-
end
|
157
|
-
|
158
149
|
module Granularity
|
159
150
|
HOUR = 'HOUR'
|
160
151
|
DAY = 'DAY'
|
@@ -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,
|
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
|
@@ -240,22 +240,22 @@ describe TwitterAds::Account do
|
|
240
240
|
|
241
241
|
end
|
242
242
|
|
243
|
-
describe '#
|
243
|
+
describe '#custom_audiences' do
|
244
244
|
|
245
245
|
before(:each) do
|
246
|
-
resource_collection = "#{ADS_API}/accounts/#{account.id}/
|
247
|
-
stub_fixture(:get, :
|
246
|
+
resource_collection = "#{ADS_API}/accounts/#{account.id}/custom_audiences"
|
247
|
+
stub_fixture(:get, :custom_audiences_all, resource_collection)
|
248
248
|
|
249
|
-
resource = "#{ADS_API}/accounts/#{account.id}/
|
250
|
-
stub_fixture(:get, :
|
249
|
+
resource = "#{ADS_API}/accounts/#{account.id}/custom_audiences/abc2"
|
250
|
+
stub_fixture(:get, :custom_audiences_load, /#{resource}\?.*/)
|
251
251
|
end
|
252
252
|
|
253
253
|
context 'with an id specified' do
|
254
254
|
|
255
|
-
it 'successfully loads the specified
|
256
|
-
result = account.
|
255
|
+
it 'successfully loads the specified custom audience' do
|
256
|
+
result = account.custom_audiences('abc2')
|
257
257
|
expect(result).not_to be_nil
|
258
|
-
expect(result.class).to eq(TwitterAds::
|
258
|
+
expect(result.class).to eq(TwitterAds::CustomAudience)
|
259
259
|
expect(result.id).to eq('abc2')
|
260
260
|
end
|
261
261
|
|
@@ -263,11 +263,11 @@ describe TwitterAds::Account do
|
|
263
263
|
|
264
264
|
context 'without an id specified' do
|
265
265
|
|
266
|
-
it 'succesfully returns a cursor with all
|
267
|
-
result = account.
|
266
|
+
it 'succesfully returns a cursor with all custom audiences' do
|
267
|
+
result = account.custom_audiences
|
268
268
|
expect(result.to_a.size).to eq(3)
|
269
269
|
expect(result.class).to eq(TwitterAds::Cursor)
|
270
|
-
expect(result.first.class).to eq(TwitterAds::
|
270
|
+
expect(result.first.class).to eq(TwitterAds::CustomAudience)
|
271
271
|
expect(result.first.id).to eq('abc2')
|
272
272
|
end
|
273
273
|
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Copyright (C) 2019 Twitter, Inc.
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
|
6
|
+
describe TwitterAds::CustomAudience do
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
stub_fixture(:get, :accounts_all, "#{ADS_API}/accounts")
|
10
|
+
stub_fixture(:get, :accounts_load, "#{ADS_API}/accounts/2iqph")
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:client) do
|
14
|
+
Client.new(
|
15
|
+
Faker::Lorem.characters(15),
|
16
|
+
Faker::Lorem.characters(40),
|
17
|
+
"123456-#{Faker::Lorem.characters(40)}",
|
18
|
+
Faker::Lorem.characters(40)
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
let(:account) { client.accounts.first }
|
23
|
+
|
24
|
+
# check model properties
|
25
|
+
subject { described_class.new(account) }
|
26
|
+
|
27
|
+
read = %w(
|
28
|
+
id
|
29
|
+
created_at
|
30
|
+
updated_at
|
31
|
+
deleted
|
32
|
+
audience_size
|
33
|
+
audience_type
|
34
|
+
partner_source
|
35
|
+
reasons_not_targetable
|
36
|
+
targetable
|
37
|
+
targetable_types
|
38
|
+
permission_level
|
39
|
+
owner_account_id
|
40
|
+
)
|
41
|
+
|
42
|
+
write = %w(name list_type)
|
43
|
+
|
44
|
+
include_examples 'object property check', read, write
|
45
|
+
|
46
|
+
end
|
@@ -30,17 +30,21 @@ describe TwitterAds::LineItem do
|
|
30
30
|
name
|
31
31
|
campaign_id
|
32
32
|
advertiser_domain
|
33
|
+
android_app_store_identifier
|
34
|
+
audience_expansion
|
33
35
|
categories
|
34
|
-
|
36
|
+
pay_by
|
35
37
|
objective
|
36
38
|
entity_status
|
37
39
|
primary_web_event_tag
|
38
40
|
product_type
|
39
41
|
placements
|
40
|
-
|
42
|
+
bid_strategy
|
41
43
|
automatically_select_bid
|
42
44
|
bid_amount_local_micro
|
43
45
|
total_budget_amount_local_micro
|
46
|
+
goal
|
47
|
+
ios_app_store_identifier
|
44
48
|
)
|
45
49
|
include_examples 'object property check', read, write
|
46
50
|
|
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:
|
4
|
+
version: 9.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Babich
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date:
|
15
|
+
date: 2021-07-16 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: multi_json
|
@@ -57,7 +57,7 @@ files:
|
|
57
57
|
- bin/twitter-ads
|
58
58
|
- lib/twitter-ads.rb
|
59
59
|
- lib/twitter-ads/account.rb
|
60
|
-
- lib/twitter-ads/audiences/
|
60
|
+
- lib/twitter-ads/audiences/custom_audience.rb
|
61
61
|
- lib/twitter-ads/campaign/advertiser_business_categories.rb
|
62
62
|
- lib/twitter-ads/campaign/app_list.rb
|
63
63
|
- lib/twitter-ads/campaign/campaign.rb
|
@@ -71,6 +71,7 @@ files:
|
|
71
71
|
- lib/twitter-ads/campaign/tweet.rb
|
72
72
|
- lib/twitter-ads/client.rb
|
73
73
|
- lib/twitter-ads/creative/account_media.rb
|
74
|
+
- lib/twitter-ads/creative/cards.rb
|
74
75
|
- lib/twitter-ads/creative/cards_fetch.rb
|
75
76
|
- lib/twitter-ads/creative/draft_tweet.rb
|
76
77
|
- lib/twitter-ads/creative/image_app_download_card.rb
|
@@ -126,6 +127,8 @@ files:
|
|
126
127
|
- spec/fixtures/audience_summary.json
|
127
128
|
- spec/fixtures/campaigns_all.json
|
128
129
|
- spec/fixtures/campaigns_load.json
|
130
|
+
- spec/fixtures/custom_audiences_all.json
|
131
|
+
- spec/fixtures/custom_audiences_load.json
|
129
132
|
- spec/fixtures/funding_instruments_all.json
|
130
133
|
- spec/fixtures/funding_instruments_load.json
|
131
134
|
- spec/fixtures/line_items_all.json
|
@@ -138,7 +141,6 @@ files:
|
|
138
141
|
- spec/fixtures/promoted_tweets_load.json
|
139
142
|
- spec/fixtures/reach_estimate.json
|
140
143
|
- spec/fixtures/tailored_audiences_all.json
|
141
|
-
- spec/fixtures/tailored_audiences_load.json
|
142
144
|
- spec/fixtures/targeted_audiences.json
|
143
145
|
- spec/fixtures/tweet_previews.json
|
144
146
|
- spec/fixtures/videos_all.json
|
@@ -148,7 +150,7 @@ files:
|
|
148
150
|
- spec/spec_helper.rb
|
149
151
|
- spec/support/helpers.rb
|
150
152
|
- spec/twitter-ads/account_spec.rb
|
151
|
-
- spec/twitter-ads/audiences/
|
153
|
+
- spec/twitter-ads/audiences/custom_audience_spec.rb
|
152
154
|
- spec/twitter-ads/campaign/app_list_spec.rb
|
153
155
|
- spec/twitter-ads/campaign/line_item_spec.rb
|
154
156
|
- spec/twitter-ads/campaign/targeting_criteria_spec.rb
|
@@ -184,54 +186,55 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
184
186
|
- !ruby/object:Gem::Version
|
185
187
|
version: 2.6.0
|
186
188
|
requirements: []
|
187
|
-
rubygems_version: 3.
|
189
|
+
rubygems_version: 3.2.22
|
188
190
|
signing_key:
|
189
191
|
specification_version: 4
|
190
192
|
summary: The officially supported Twitter Ads API SDK for Ruby.
|
191
193
|
test_files:
|
192
|
-
- spec/
|
193
|
-
- spec/support/helpers.rb
|
194
|
-
- spec/shared/properties.rb
|
195
|
-
- spec/twitter-ads/audiences/tailored_audience_spec.rb
|
196
|
-
- spec/twitter-ads/creative/promoted_account_spec.rb
|
197
|
-
- spec/twitter-ads/creative/tweet_previews_spec.rb
|
198
|
-
- spec/twitter-ads/creative/media_creative_spec.rb
|
199
|
-
- spec/twitter-ads/creative/promoted_tweet_spec.rb
|
200
|
-
- spec/twitter-ads/rate_limit_spec.rb
|
201
|
-
- spec/twitter-ads/cursor_spec.rb
|
202
|
-
- spec/twitter-ads/placements_spec.rb
|
203
|
-
- spec/twitter-ads/client_spec.rb
|
204
|
-
- spec/twitter-ads/account_spec.rb
|
205
|
-
- spec/twitter-ads/targeting/audience_summary_spec.rb
|
206
|
-
- spec/twitter-ads/retry_count_spec.rb
|
207
|
-
- spec/twitter-ads/utils_spec.rb
|
208
|
-
- spec/twitter-ads/campaign/app_list_spec.rb
|
209
|
-
- spec/twitter-ads/campaign/targeting_criteria_spec.rb
|
210
|
-
- spec/twitter-ads/campaign/tweet_spec.rb
|
211
|
-
- spec/twitter-ads/campaign/line_item_spec.rb
|
212
|
-
- spec/fixtures/promotable_users_load.json
|
213
|
-
- spec/fixtures/promoted_tweets_load.json
|
194
|
+
- spec/fixtures/accounts_all.json
|
214
195
|
- spec/fixtures/accounts_features.json
|
215
|
-
- spec/fixtures/campaigns_all.json
|
216
|
-
- spec/fixtures/line_items_load.json
|
217
|
-
- spec/fixtures/tweet_previews.json
|
218
|
-
- spec/fixtures/targeted_audiences.json
|
219
|
-
- spec/fixtures/videos_all.json
|
220
|
-
- spec/fixtures/tailored_audiences_all.json
|
221
|
-
- spec/fixtures/funding_instruments_load.json
|
222
196
|
- spec/fixtures/accounts_load.json
|
223
|
-
- spec/fixtures/line_items_all.json
|
224
197
|
- spec/fixtures/app_lists_all.json
|
225
|
-
- spec/fixtures/placements.json
|
226
198
|
- spec/fixtures/app_lists_load.json
|
199
|
+
- spec/fixtures/audience_summary.json
|
200
|
+
- spec/fixtures/campaigns_all.json
|
227
201
|
- spec/fixtures/campaigns_load.json
|
228
|
-
- spec/fixtures/
|
202
|
+
- spec/fixtures/custom_audiences_all.json
|
203
|
+
- spec/fixtures/custom_audiences_load.json
|
204
|
+
- spec/fixtures/funding_instruments_all.json
|
205
|
+
- spec/fixtures/funding_instruments_load.json
|
206
|
+
- spec/fixtures/line_items_all.json
|
207
|
+
- spec/fixtures/line_items_load.json
|
208
|
+
- spec/fixtures/no_content.json
|
209
|
+
- spec/fixtures/placements.json
|
229
210
|
- spec/fixtures/promotable_users_all.json
|
230
|
-
- spec/fixtures/
|
211
|
+
- spec/fixtures/promotable_users_load.json
|
231
212
|
- spec/fixtures/promoted_tweets_all.json
|
232
|
-
- spec/fixtures/
|
233
|
-
- spec/fixtures/funding_instruments_all.json
|
213
|
+
- spec/fixtures/promoted_tweets_load.json
|
234
214
|
- spec/fixtures/reach_estimate.json
|
235
|
-
- spec/fixtures/
|
236
|
-
- spec/fixtures/
|
215
|
+
- spec/fixtures/tailored_audiences_all.json
|
216
|
+
- spec/fixtures/targeted_audiences.json
|
217
|
+
- spec/fixtures/tweet_previews.json
|
218
|
+
- spec/fixtures/videos_all.json
|
219
|
+
- spec/fixtures/videos_load.json
|
220
|
+
- spec/quality_spec.rb
|
221
|
+
- spec/shared/properties.rb
|
237
222
|
- spec/spec_helper.rb
|
223
|
+
- spec/support/helpers.rb
|
224
|
+
- spec/twitter-ads/account_spec.rb
|
225
|
+
- spec/twitter-ads/audiences/custom_audience_spec.rb
|
226
|
+
- spec/twitter-ads/campaign/app_list_spec.rb
|
227
|
+
- spec/twitter-ads/campaign/line_item_spec.rb
|
228
|
+
- spec/twitter-ads/campaign/targeting_criteria_spec.rb
|
229
|
+
- spec/twitter-ads/campaign/tweet_spec.rb
|
230
|
+
- spec/twitter-ads/client_spec.rb
|
231
|
+
- spec/twitter-ads/creative/media_creative_spec.rb
|
232
|
+
- spec/twitter-ads/creative/promoted_account_spec.rb
|
233
|
+
- spec/twitter-ads/creative/promoted_tweet_spec.rb
|
234
|
+
- spec/twitter-ads/creative/tweet_previews_spec.rb
|
235
|
+
- spec/twitter-ads/cursor_spec.rb
|
236
|
+
- spec/twitter-ads/placements_spec.rb
|
237
|
+
- spec/twitter-ads/rate_limit_spec.rb
|
238
|
+
- spec/twitter-ads/retry_count_spec.rb
|
239
|
+
- spec/twitter-ads/targeting/audience_summary_spec.rb
|
240
|
+
- spec/twitter-ads/utils_spec.rb
|
@@ -1,68 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
# Copyright (C) 2019 Twitter, Inc.
|
3
|
-
|
4
|
-
require 'spec_helper'
|
5
|
-
|
6
|
-
describe TwitterAds::TailoredAudience do
|
7
|
-
|
8
|
-
before(:each) do
|
9
|
-
stub_fixture(:get, :accounts_all, "#{ADS_API}/accounts")
|
10
|
-
stub_fixture(:get,
|
11
|
-
:tailored_audiences_load,
|
12
|
-
"#{ADS_API}/accounts/2iqph/tailored_audiences/abc2?with_deleted=true")
|
13
|
-
stub_fixture(:get,
|
14
|
-
:targeted_audiences,
|
15
|
-
"#{ADS_API}/accounts/2iqph/tailored_audiences/abc2/targeted")
|
16
|
-
end
|
17
|
-
|
18
|
-
let(:client) do
|
19
|
-
Client.new(
|
20
|
-
Faker::Lorem.characters(15),
|
21
|
-
Faker::Lorem.characters(40),
|
22
|
-
"123456-#{Faker::Lorem.characters(40)}",
|
23
|
-
Faker::Lorem.characters(40)
|
24
|
-
)
|
25
|
-
end
|
26
|
-
|
27
|
-
let(:account) { client.accounts.first }
|
28
|
-
let(:tailored_audience) { described_class.load(account, 'abc2') }
|
29
|
-
# check model properties
|
30
|
-
subject { described_class.new(account) }
|
31
|
-
|
32
|
-
read = %w(
|
33
|
-
id
|
34
|
-
created_at
|
35
|
-
updated_at
|
36
|
-
deleted
|
37
|
-
owner_account_id
|
38
|
-
audience_size
|
39
|
-
audience_type
|
40
|
-
metadata
|
41
|
-
partner_source
|
42
|
-
reasons_not_targetable
|
43
|
-
targetable
|
44
|
-
targetable_types
|
45
|
-
)
|
46
|
-
|
47
|
-
write = %w(name list_type)
|
48
|
-
|
49
|
-
include_examples 'object property check', read, write
|
50
|
-
|
51
|
-
describe '#targeted' do
|
52
|
-
|
53
|
-
let(:cursor) { tailored_audience.targeted }
|
54
|
-
|
55
|
-
it 'has all the correct properties' do
|
56
|
-
result = cursor.first
|
57
|
-
expect(result).to eq(cursor.instance_variable_get('@collection').first)
|
58
|
-
expect(result).to be_instance_of(TwitterAds::TargetedTailoredAudience)
|
59
|
-
expect(cursor).to be_instance_of(Cursor)
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'raises error when TailoredAudience is not loaded' do
|
63
|
-
result = TwitterAds::TailoredAudience.new(account)
|
64
|
-
expect(result).to receive(:validate_loaded).and_call_original
|
65
|
-
expect { result.targeted }.to raise_error(ArgumentError)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|