app/services/frontend_logger.rb
# frozen_string_literal: true
class FrontendLogger
attr_reader :analytics, :event_map
# @param [Analytics] analytics
# @param [Hash{String=>Symbol,#call}] event_map map of string event names to method names
# on Analytics, or a custom implementation that's callable (like a Proc or Method)
def initialize(analytics:, event_map:)
@analytics = analytics
@event_map = event_map
end
# Logs an event and converts the payload to the correct keyword args
# @param [String] name
# @param [Hash<String,Object>] attributes payload with string keys
def track_event(name, attributes)
analytics_method = event_map[name]
if analytics_method.is_a?(Symbol)
analytics.send(
analytics_method,
**hash_from_kwargs(attributes, AnalyticsEvents.instance_method(analytics_method)),
)
true
elsif analytics_method.respond_to?(:call)
analytics_method.call(**hash_from_kwargs(attributes, analytics_method))
true
else
false
end
end
private
# @param [Hash<String,Object>] hash
# @param [Proc,Method] callable
# @return [Hash<Symbol,Object>]
def hash_from_kwargs(hash, callable)
kwargs(callable).index_with { |key| hash[key.to_s] }
end
# @param [Proc,Method] callable
# @return [Array<Symbol>] the names of the kwargs for the callable (both optional and required)
def kwargs(callable)
callable.
parameters.
map { |type, name| name if [:key, :keyreq].include?(type) }.
compact
end
end