Class: Marketing::CustomerMatch::Client

Inherits:
DataManager::Client
  • Object
show all
Defined in:
app/services/marketing/customer_match/client.rb

Overview

Data Manager API client specialized for Customer Match audiences: create /
find CONTACT_INFO user lists and ingest hashed audience members. The OAuth
transport, destination building, and request-status polling are inherited
from DataManager::Client.

Constant Summary collapse

MAX_MEMBERS_PER_REQUEST =

Google's cap: 10,000 audience members per ingest request.

10_000

Instance Method Summary collapse

Instance Method Details

#create_user_list(display_name:, description: nil, membership_days: 540) ⇒ String

Create a CONTACT_INFO Customer Match user list.

Parameters:

  • display_name (String)

    unique per account

  • description (String, nil) (defaults to: nil)
  • membership_days (Integer) (defaults to: 540)

    0–540

Returns:

  • (String)

    the new user list's numeric id (use as productDestinationId)



20
21
22
23
24
25
26
27
28
29
30
31
# File 'app/services/marketing/customer_match/client.rb', line 20

def create_user_list(display_name:, description: nil, membership_days: 540)
  body = {
    displayName: display_name,
    description: description,
    membershipDuration: "#{membership_days * 86_400}s",
    ingestedUserListInfo: {
      uploadKeyTypes: ['CONTACT_ID'],
      contactIdInfo: { dataSourceType: 'DATA_SOURCE_TYPE_FIRST_PARTY' }
    }
  }.compact
  post("#{}/userLists", body).fetch('id').to_s
end

#find_user_list(display_name:) ⇒ String?

Returns id of an existing user list with that display name.

Parameters:

  • display_name (String)

Returns:

  • (String, nil)

    id of an existing user list with that display name



35
36
37
38
# File 'app/services/marketing/customer_match/client.rb', line 35

def find_user_list(display_name:)
  lists = Array(get("#{}/userLists")['userLists'])
  lists.find { |list| list['displayName'] == display_name }&.dig('id')&.to_s
end

#ingest(user_list_id:, members:, validate_only: true) ⇒ String

Ingest audience members into a user list.

Parameters:

  • user_list_id (String)

    productDestinationId

  • members (Array<Hash>)

    AudienceMember payloads (see MemberBuilder)

  • validate_only (Boolean) (defaults to: true)

    dry-run without committing

Returns:

  • (String)

    the requestId



45
46
47
48
49
50
51
52
53
54
55
# File 'app/services/marketing/customer_match/client.rb', line 45

def ingest(user_list_id:, members:, validate_only: true)
  body = {
    destinations: [destination(user_list_id)],
    audienceMembers: members,
    consent: { adUserData: 'CONSENT_GRANTED', adPersonalization: 'CONSENT_GRANTED' },
    encoding: 'HEX',
    termsOfService: { customerMatchTermsOfServiceStatus: 'ACCEPTED' },
    validateOnly: validate_only
  }
  post('/v1/audienceMembers:ingest', body).fetch('requestId').to_s
end

#remove(user_list_id:, members:, validate_only: true) ⇒ String

Remove audience members from a user list — opt-outs, closed/bankrupt
accounts, or any member no longer eligible. Mirrors #ingest; a removal
carries no consent / terms-of-service.

Parameters:

  • user_list_id (String)

    productDestinationId

  • members (Array<Hash>)

    AudienceMember payloads (see MemberBuilder)

  • validate_only (Boolean) (defaults to: true)

    dry-run without committing

Returns:

  • (String)

    the requestId



64
65
66
67
68
69
70
71
72
# File 'app/services/marketing/customer_match/client.rb', line 64

def remove(user_list_id:, members:, validate_only: true)
  body = {
    destinations: [destination(user_list_id)],
    audienceMembers: members,
    encoding: 'HEX',
    validateOnly: validate_only
  }
  post('/v1/audienceMembers:remove', body).fetch('requestId').to_s
end