From 93c4154648f8d632fdd5facf1c1abea6340e3c7b Mon Sep 17 00:00:00 2001 From: Seth Call Date: Wed, 14 Jan 2026 08:58:37 -0600 Subject: [PATCH] add capi transmitter and missing event type --- ruby/lib/jam_ruby/lib/capi_transmitter.rb | 75 +++++++++++++++++++++++ ruby/lib/jam_ruby/models/user.rb | 2 + 2 files changed, 77 insertions(+) create mode 100644 ruby/lib/jam_ruby/lib/capi_transmitter.rb diff --git a/ruby/lib/jam_ruby/lib/capi_transmitter.rb b/ruby/lib/jam_ruby/lib/capi_transmitter.rb new file mode 100644 index 000000000..fe64d5a97 --- /dev/null +++ b/ruby/lib/jam_ruby/lib/capi_transmitter.rb @@ -0,0 +1,75 @@ +require 'net/http' +require 'uri' +require 'json' + +class CapiTransmitter + + def self.send_event(event_name, user, custom_data = {}, event_source_url = nil) + begin + pixel_id = APP_CONFIG[:facebook_pixel_id] + access_token = APP_CONFIG[:facebook_access_token] + + if pixel_id.blank? || access_token.blank? + Rails.logger.warn("CapiTransmitter: Missing Facebook Pixel ID or Access Token. Skipping event #{event_name}.") + return + end + + # Construct the User Data object + user_data = { + client_ip_address: user.current_sign_in_ip, + client_user_agent: user.user_agent # Note: User model might not have user_agent stored directly, might need to pass it or rely on what's available + } + + # Enhance user data with hashed PII if available + # Facebook requires SHA256 hashing for PII + # For now, we rely on click_id and browser_id as primary keys if available + user_data[:fbc] = user.facebook_click_id if user.facebook_click_id.present? + user_data[:fbp] = user.facebook_browser_id if user.facebook_browser_id.present? + + # If we have email/phone, we should hash them. But for now, let's stick to the IDs. + # Ideally we should hash email if we have it. + if user.email.present? + user_data[:em] = Digest::SHA256.hexdigest(user.email.downcase) + end + + payload = { + data: [ + { + event_name: event_name, + event_time: Time.now.to_i, + action_source: "website", + user_data: user_data, + custom_data: custom_data, + event_source_url: event_source_url + } + ] + } + + url = URI.parse("https://graph.facebook.com/v19.0/#{pixel_id}/events?access_token=#{access_token}") + + http = Net::HTTP.new(url.host, url.port) + + if APP_CONFIG[:facebook_conversion_api_tls] == false + http.verify_mode = OpenSSL::SSL::VERIFY_NONE + else + http.use_ssl = true + end + + request = Net::HTTP::Post.new(url.request_uri) + request['Content-Type'] = 'application/json' + request.body = payload.to_json + + response = http.request(request) + + if response.code.to_i >= 400 + Rails.logger.error("CapiTransmitter Error: #{response.code} - #{response.body}") + else + Rails.logger.info("CapiTransmitter Success: #{event_name} sent for User #{user.id}") + end + + rescue => e + Rails.logger.error("CapiTransmitter Exception: #{e.message}") + Rails.logger.error(e.backtrace.join("\n")) + end + end +end diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index 5c566e8e2..0b568071b 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -552,6 +552,8 @@ module JamRuby CapiTransmitter.send_event('CompleteGearWizard', self) when 'first_music_session_at' CapiTransmitter.send_event('FirstMusicSession', self) + when 'first_real_music_session_at' + CapiTransmitter.send_event('RealMusicSession', self) end rescue => e Rails.logger.error("Error sending CAPI event: #{e.message}")