Class: Marketing::Audiences::FacebookAdapter

Inherits:
Object
  • Object
show all
Defined in:
app/services/marketing/audiences/facebook_adapter.rb

Overview

Facebook/Meta Custom Audiences adapter. Snapshot platform: each reconcile
rebuilds the audience's full consented email set and REPLACES the remote
audience's members (Meta's usersreplace session flow), so opt-outs simply
vanish from the next snapshot — hence no #purge_suppressed.

Idempotent by NAME: the remote audience is found (or created) by a
deterministic name derived from the audience key, so there's no local
tracking table and a retry reuses the same remote audience.

Enabled when the Marketing API creds are present — the same
advertiser_access_token + ad_account_id the campaign sync uses (a System
User token with ads_management; Custom Audiences + usersreplace verified
against the live API). 'TBD' counts as absent, mirroring
FacebookCampaignSyncWorker. The daily reconcile is LIVE, but only audiences
flagged facebook in their ad_platforms actually sync.

ponytail: EMAIL-only schema. Meta matches on email well and a single-column
usersreplace avoids per-person email+phone pairing. Add PHONE (per-person
rows, blank where absent) if match rate ever needs it.

Constant Summary collapse

SCHEMA =

Meta usersreplace column schema — EMAIL only (see the class ponytail).

%w[EMAIL].freeze

Instance Method Summary collapse

Constructor Details

#initialize(validate_only: true, client: nil) ⇒ FacebookAdapter

Returns a new instance of FacebookAdapter.

Parameters:

  • validate_only (Boolean) (defaults to: true)

    true (default) dry-runs the reconcile

  • client (Facebook::AdvertiserApiClient) (defaults to: nil)

    injectable for tests



34
35
36
37
# File 'app/services/marketing/audiences/facebook_adapter.rb', line 34

def initialize(validate_only: true, client: nil)
  @validate_only = validate_only
  @client = client
end

Instance Method Details

#enabled?Boolean

Returns true when the Marketing API creds are present.

Returns:

  • (Boolean)

    true when the Marketing API creds are present



43
44
45
# File 'app/services/marketing/audiences/facebook_adapter.rb', line 43

def enabled?
  configured?(config(:ad_account_id)) && configured?(config(:advertiser_access_token))
end

#labelString

Returns platform key, matching ad_platforms values.

Returns:

  • (String)

    platform key, matching ad_platforms values



40
# File 'app/services/marketing/audiences/facebook_adapter.rb', line 40

def label = 'facebook'

#reconcile(audience) ⇒ Hash

Returns a small result summary.

Parameters:

Returns:

  • (Hash)

    a small result summary



49
50
51
52
53
54
55
56
57
# File 'app/services/marketing/audiences/facebook_adapter.rb', line 49

def reconcile(audience)
  rows = email_rows(audience)
  return { audience: audience.key, members: 0, skipped: 'no hashable emails' } if rows.empty?
  return { audience: audience.key, members: rows.size, validate_only: true } if @validate_only

  remote = ensure_audience(audience)
  sent   = client.replace_users(audience_id: remote['id'], schema: SCHEMA, data: rows, token:)
  { audience: audience.key, audience_id: remote['id'], members: sent }
end