Skip to content

Commit c04923e

Browse files
Tom Osowskitushdante
andauthored
Ads API V8 (#235)
* Support TA parameter owner_account_id (#234) * Product renaming for v8 (#233) * Ads API v8 (#241) * bump version * targeted audiences support Co-authored-by: Tushar Bhushan <tushar.bhushan@yahoo.com>
1 parent 3bce052 commit c04923e

10 files changed

Lines changed: 126 additions & 13 deletions

File tree

examples/batch_request.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
line_item_1.name = 'my first ad'
4747
line_item_1.product_type = TwitterAds::Product::PROMOTED_TWEETS
4848
line_item_1.placements = [TwitterAds::Placement::ALL_ON_TWITTER]
49-
line_item_1.objective = TwitterAds::Objective::TWEET_ENGAGEMENTS
49+
line_item_1.objective = TwitterAds::Objective::ENGAGEMENTS
5050
line_item_1.bid_amount_local_micro = 10_000
5151
line_item_1.entity_status = EntityStatus::PAUSED
5252

@@ -55,7 +55,7 @@
5555
line_item_2.name = 'my second ad'
5656
line_item_2.product_type = TwitterAds::Product::PROMOTED_TWEETS
5757
line_item_2.placements = [TwitterAds::Placement::ALL_ON_TWITTER]
58-
line_item_2.objective = TwitterAds::Objective::TWEET_ENGAGEMENTS
58+
line_item_2.objective = TwitterAds::Objective::ENGAGEMENTS
5959
line_item_2.bid_amount_local_micro = 20_000
6060
line_item_2.entity_status = EntityStatus::PAUSED
6161

examples/metric_filtering.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ class Metrics
202202
:video,
203203
:other
204204
],
205-
tweet_engagements: [
205+
engagements: [
206206
:conversion,
207207
:engagement,
208208
:media,

examples/quick_start.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
line_item.name = 'my first ad'
3737
line_item.product_type = Product::PROMOTED_TWEETS
3838
line_item.placements = [Placement::ALL_ON_TWITTER]
39-
line_item.objective = Objective::TWEET_ENGAGEMENTS
39+
line_item.objective = Objective::ENGAGEMENTS
4040
line_item.bid_amount_local_micro = 10_000
4141
line_item.entity_status = EntityStatus::PAUSED
4242
line_item.save

lib/twitter-ads/audiences/tailored_audience.rb

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class TailoredAudience
2020
property :audience_size, read_only: true
2121
property :audience_type, read_only: true
2222
property :metadata, read_only: true
23+
property :owner_account_id, read_only: true
2324
property :partner_source, read_only: true
2425
property :reasons_not_targetable, read_only: true
2526
property :targetable, type: :bool, read_only: true
@@ -91,7 +92,7 @@ def delete!
9192
from_response(response.body[:data])
9293
end
9394

94-
# This is a private API and requires whitelisting from Twitter.
95+
# This is a private API and requires allowlisting from Twitter.
9596
#
9697
# This endpoint will allow partners to add, update and remove users from a given
9798
# tailored_audience_id.
@@ -137,6 +138,60 @@ def users(params)
137138
[success_count, total_count]
138139
end
139140

141+
# Retrieves the entites targeting the current tailored audience instance.
142+
#
143+
# @example
144+
# audience.targeted(with_active=true)
145+
#
146+
# @param with_active [bool] Include active/inactive
147+
#
148+
# @since 8.0.0
149+
#
150+
# @return [self] Returns a Cursor instance of the targeted entities.
151+
def targeted(opts = {})
152+
validate_loaded
153+
params = {}.merge!(opts)
154+
TargetedTailoredAudience.load(account, id, params)
155+
end
156+
157+
def validate_loaded
158+
raise ArgumentError.new(
159+
"Error! #{self.class} object not yet initialized, " \
160+
"call #{self.class}.load first") if id.nil?
161+
end
162+
end
163+
164+
class TargetedTailoredAudience
165+
166+
include TwitterAds::DSL
167+
include TwitterAds::Resource
168+
169+
attr_reader :account
170+
171+
# read-only
172+
property :campaign_id, read_only: true
173+
property :campaign_name, read_only: true
174+
property :line_items, read_only: true
175+
176+
RESOURCE_TARGETED = "/#{TwitterAds::API_VERSION}/" \
177+
'accounts/%{account_id}/tailored_audiences/%{id}/targeted' # @api private
178+
179+
def initialize(account)
180+
@account = account
181+
self
182+
end
183+
184+
class << self
185+
186+
def load(account, tailored_audience_id, params)
187+
resource = RESOURCE_TARGETED % { account_id: account.id, id: tailored_audience_id }
188+
request = TwitterAds::Request.new(account.client,
189+
:get,
190+
resource,
191+
params: params)
192+
Cursor.new(self, request, init_with: [account])
193+
end
194+
end
140195
end
141196

142197
class TailoredAudiencePermission

lib/twitter-ads/client.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
module TwitterAds
55

6-
API_VERSION = '7'
6+
API_VERSION = '8'
77

88
# The Ads API Client class which functions as a
99
# container for basic API consumer information.

lib/twitter-ads/enum.rb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,12 @@ module Enum
99
module Objective
1010
APP_ENGAGEMENTS = 'APP_ENGAGEMENTS'
1111
APP_INSTALLS = 'APP_INSTALLS'
12+
ENGAGEMENTS = 'ENGAGEMENTS'
1213
FOLLOWERS = 'FOLLOWERS'
13-
LEAD_GENERATION = 'LEAD_GENERATION'
14-
TWEET_ENGAGEMENTS = 'TWEET_ENGAGEMENTS'
14+
PREROLL_VIEWS = 'PREROLL_VIEWS'
15+
REACH = 'REACH'
1516
VIDEO_VIEWS = 'VIDEO_VIEWS'
1617
WEBSITE_CLICKS = 'WEBSITE_CLICKS'
17-
WEBSITE_CONVERSIONS = 'WEBSITE_CONVERSIONS'
18-
1918
end
2019

2120
module Product

lib/twitter-ads/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
# Copyright (C) 2019 Twitter, Inc.
33

44
module TwitterAds
5-
VERSION = '7.0.1'
5+
VERSION = '8.0.0'
66
end

spec/fixtures/tailored_audiences_all.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
],
1515
"audience_type": "WEB",
1616
"id": "abc2",
17+
"owner_account_id": "18ce54uhdu0",
1718
"reasons_not_targetable": [
1819
"TOO_SMALL"
1920
],
@@ -33,6 +34,7 @@
3334
],
3435
"audience_type": "CRM",
3536
"id": "abc1",
37+
"owner_account_id": "18ce54uhdu0",
3638
"reasons_not_targetable": [],
3739
"list_type": "DEVICE_ID",
3840
"created_at": "2014-05-22T17:37:12Z",
@@ -50,6 +52,7 @@
5052
],
5153
"audience_type": "CRM",
5254
"id": "abc3",
55+
"owner_account_id": "18ce54uhdu0",
5356
"reasons_not_targetable": [
5457
"TOO_SMALL"
5558
],
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"request": {
3+
"params": {
4+
"account_id": "2iqph",
5+
"tailored_audience_id": "abc2"
6+
}
7+
},
8+
"next_cursor": null,
9+
"data": [
10+
{
11+
"campaign_id": "59hod",
12+
"campaign_name": "test-campaign",
13+
"line_items": [
14+
{
15+
"id": "5gzog",
16+
"name": "test-line-item",
17+
"servable": true
18+
}
19+
]
20+
},
21+
{
22+
"campaign_id": "arja7",
23+
"campaign_name": "Untitled campaign",
24+
"line_items": [
25+
{
26+
"id": "bjw1q",
27+
"name": null,
28+
"servable": true
29+
}
30+
]
31+
}
32+
]
33+
}

spec/twitter-ads/audiences/tailored_audience_spec.rb

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77

88
before(:each) do
99
stub_fixture(:get, :accounts_all, "#{ADS_API}/accounts")
10-
stub_fixture(:get, :accounts_load, "#{ADS_API}/accounts/2iqph")
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")
1116
end
1217

1318
let(:client) do
@@ -20,7 +25,7 @@
2025
end
2126

2227
let(:account) { client.accounts.first }
23-
28+
let(:tailored_audience) { described_class.load(account, 'abc2') }
2429
# check model properties
2530
subject { described_class.new(account) }
2631

@@ -29,6 +34,7 @@
2934
created_at
3035
updated_at
3136
deleted
37+
owner_account_id
3238
audience_size
3339
audience_type
3440
metadata
@@ -42,4 +48,21 @@
4248

4349
include_examples 'object property check', read, write
4450

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
4568
end

0 commit comments

Comments
 (0)