Class: Pinterest::AdvertiserApiClient

Inherits:
BaseService show all
Defined in:
app/services/pinterest/advertiser_api_client.rb

Overview

Service object: advertiser API client.

Constant Summary collapse

PAGE_LIMIT =

Page size for the campaigns list endpoint. Pinterest caps at 250,
well above the realistic active-campaign count for one ad account
(ChatGPT and Google parallels run ~50 campaigns) so we expect a
single page in the common case.

250

Instance Attribute Summary

Attributes inherited from BaseService

#options

Instance Method Summary collapse

Methods inherited from BaseService

#initialize, #log_debug, #log_error, #log_info, #log_warning, #logger, #process, #tagged_logger

Constructor Details

This class inherits a constructor from BaseService

Instance Method Details

#create_audience(ad_account_id:, name:, customer_list_id:, token:) ⇒ Object

Wrap a customer list as a targetable CUSTOMER_LIST audience.



104
105
106
107
108
# File 'app/services/pinterest/advertiser_api_client.rb', line 104

def create_audience(ad_account_id:, name:, customer_list_id:, token:)
  post_audience("ad_accounts/#{}/audiences",
                { name:, rule: { customer_list_id: }, audience_type: 'CUSTOMER_LIST' },
                token, 'create_audience')
end

#create_customer_list(ad_account_id:, name:, records:, token:, list_type: 'EMAIL') ⇒ Object

Create a customer list from a comma-joined record string (ONE identifier
type, hashed). @return [Hash] the created list ({ 'id' =>, 'status' => }).



82
83
84
85
# File 'app/services/pinterest/advertiser_api_client.rb', line 82

def create_customer_list(ad_account_id:, name:, records:, token:, list_type: 'EMAIL')
  post_audience("ad_accounts/#{}/customer_lists",
                { name:, records:, list_type: }, token, 'create_customer_list')
end

#find_audience(ad_account_id:, name:, token:) ⇒ Hash?

Our CUSTOMER_LIST audience with this exact name, or nil.

Returns:

  • (Hash, nil)


98
99
100
101
# File 'app/services/pinterest/advertiser_api_client.rb', line 98

def find_audience(ad_account_id:, name:, token:)
  get_items("ad_accounts/#{}/audiences", token, 'find_audience')
    .find { |audience| audience['name'] == name }
end

#find_customer_list(ad_account_id:, name:, token:) ⇒ Hash?

Our customer list with this exact name, or nil. ponytail: single page
(page_size PAGE_LIMIT); paginate via bookmark if we ever keep more lists.

Returns:

  • (Hash, nil)


75
76
77
78
# File 'app/services/pinterest/advertiser_api_client.rb', line 75

def find_customer_list(ad_account_id:, name:, token:)
  get_items("ad_accounts/#{}/customer_lists", token, 'find_customer_list')
    .find { |list| list['name'] == name }
end

#list_campaigns(ad_account_id:, token:) ⇒ Array<Hash>

List all campaigns on the ad account. Walks the bookmark cursor
pagination until the API stops returning a bookmark and returns
the concatenated list.

Parameters:

  • ad_account_id (String)

    Pinterest ad account ID

  • token (String)

    Pinterest OAuth access token (bearer) with
    ads:read scope.

Returns:

  • (Array<Hash>)

    campaign objects per Pinterest's spec —
    id, name, status ("ACTIVE"|"PAUSED"|"ARCHIVED"),
    objective_type, daily_spend_cap, lifetime_spend_cap,
    created_time/updated_time (Unix timestamps), etc.

Raises:

  • (RuntimeError)

    on non-200 responses (Sidekiq retry surface).



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'app/services/pinterest/advertiser_api_client.rb', line 40

def list_campaigns(ad_account_id:, token:)
  campaigns = []
  bookmark  = nil

  loop do
    response = connection(token).get("ad_accounts/#{}/campaigns") do |req|
      req.params['page_size'] = PAGE_LIMIT
      req.params['bookmark']  = bookmark if bookmark
    end

    unless response.status == 200
      body = safe_parse(response.body)
      msg  = body['message'] || body['error'] || "HTTP #{response.status}"
      raise "Pinterest::AdvertiserApiClient: list_campaigns failed (HTTP #{response.status}): #{msg}"
    end

    body = safe_parse(response.body)
    page = Array(body['items'])
    campaigns.concat(page)

    next_bookmark = body['bookmark']
    break if next_bookmark.blank? || next_bookmark == bookmark # defensive — same cursor twice would loop forever

    bookmark = next_bookmark
  end

  campaigns
end

#update_customer_list(ad_account_id:, customer_list_id:, records:, operation_type:, token:) ⇒ Object

Append or remove records on an existing customer list.

Parameters:

  • operation_type (String)

    'ADD' or 'REMOVE'



90
91
92
93
# File 'app/services/pinterest/advertiser_api_client.rb', line 90

def update_customer_list(ad_account_id:, customer_list_id:, records:, operation_type:, token:)
  post_audience("ad_accounts/#{}/customer_lists/#{customer_list_id}",
                { records:, operation_type: }, token, 'update_customer_list')
end