Class: Marketing::AdSpend::OpenaiAdapter
- Inherits:
-
Object
- Object
- Marketing::AdSpend::OpenaiAdapter
- Defined in:
- app/services/marketing/ad_spend/openai_adapter.rb
Overview
Daily campaign spend from OpenAI (ChatGPT) Ads.
Insights are per-campaign and the endpoint ignores date params, so this
fans out over the campaigns and filters to the requested day client-side —
see OpenaiAds::AdvertiserApiClient#campaign_insights for the API's traps.
Volume is tiny (single-digit campaigns), so the per-campaign fan-out costs
nothing; revisit if the account grows into the hundreds.
Constant Summary collapse
- PROVIDER =
Provider key recorded on ad spend rows produced by this adapter.
'openai_ads'
Class Method Summary collapse
-
.call(date) ⇒ Array<Hash>
{ external_id:, spend:, clicks:, impressions:, conversions: }empty when no API key is configured.
Class Method Details
.call(date) ⇒ Array<Hash>
Returns { external_id:, spend:, clicks:, impressions:, conversions: }
empty when no API key is configured. conversions is always nil — the
Ads API exposes no conversions field.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'app/services/marketing/ad_spend/openai_adapter.rb', line 18 def self.call(date) token = Heatwave::Configuration.fetch(:openai_ads, :advertiser_api_key) return [] if token.blank? client = OpenaiAds::AdvertiserApiClient.new wanted = date.to_s client.list_campaigns(token: token).flat_map do |campaign| client.campaign_insights(token: token, campaign_id: campaign['id']) .select { |row| row['readable_time'] == wanted } .map do |row| { external_id: row['campaign_id'].to_s, spend: row['spend'].to_f, # already dollars, not micros clicks: row['clicks'].to_i, impressions: row['impressions'].to_i, conversions: nil } end end end |