lib/vwo.rb
# This API method: Marks the conversion of the campaign
# for a particular goal
# 1. validates the arguments being passed
# 2. Checks if user is eligible to get bucketed into the campaign,
# 3. Gets the assigned deterministic variation to the
#     user(based on user_d), if user becomes part of campaign
# 4. Sends an impression call to VWO server to track goal data
#
# @param[String]                      :campaign_key     Unique campaign key
# @param[String]                      :user_id          ID assigned to a user
# @param[String]                      :goal_identifier  Unique campaign's goal identifier
# @param[Hash]                        :options             Contains revenue value and custom variables
# @param[Numeric|String]              :revenue_value    It is the revenue generated on triggering the goal
#
This API method: Marks the conversion of the campaign
for a particular goal
1. validates the arguments being passed
2. Checks if user is eligible to get bucketed into the campaign,
3. Gets the assigned deterministic variation to the
user(based on user_d), if user becomes part of campaign
4. Sends an impression call to VWO server to track goal data
This API method : Marks the conversion of the campaign for a particular goal 1 . validates the arguments being passed 2 . Checks if user is eligible to get bucketed into the campaign 3 . Gets the assigned deterministic variation to the user ( based on user_d ) if user becomes part of campaign 4 . Sends an impression call to VWO server to track goal data
def track(campaign_key, user_id, goal_identifier, options = {})
    if is_opted_out(ApiMethods::TRACK)
      return false
    end
    unless @is_instance_valid
      @logger.log(
        LogLevelEnum::ERROR,
        format(
          LogMessageEnum::ErrorMessages::API_CONFIG_CORRUPTED,
          file: FILE,
          api_name: ApiMethods::TRACK
        )
      )
      return false
    end
    options = convert_to_symbol_hash(options)
    revenue_value = options[:revenue_value]
    custom_variables = options[:custom_variables]
    variation_targeting_variables = options[:variation_targeting_variables]
    goal_type_to_track = get_goal_type_to_track(options)
    unless (valid_string?(campaign_key) || campaign_key.is_a?(Array) || campaign_key.nil?) && valid_string?(user_id) && valid_string?(goal_identifier) && (custom_variables.nil? || valid_hash?(custom_variables)) &&
      (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables)) && (GOAL_TYPES.key? (goal_type_to_track))
      @logger.log(
        LogLevelEnum::ERROR,
        format(
          LogMessageEnum::ErrorMessages::TRACK_API_INVALID_PARAMS,
          file: FILE,
          api_name: ApiMethods::TRACK
        )
      )
      return false
    end
    campaigns = get_campaigns(@settings_file, campaign_key, goal_identifier, goal_type_to_track)
    if campaigns.nil?
      return nil
    end
    metric_map = {}
    revenue_props = []
    result = {}
    campaigns.each do |campaign|
      begin
        campaign_type = campaign['type']
        if campaign_type == CampaignTypes::FEATURE_ROLLOUT
          @logger.log(
            LogLevelEnum::ERROR,
            format(
              LogMessageEnum::ErrorMessages::INVALID_API,
              file: FILE,
              api_name: ApiMethods::TRACK,
              user_id: user_id,
              campaign_key: campaign['key'],
              campaign_type: campaign_type
            )
          )
          result[campaign['key']] = false
          next
        end
        variation = @variation_decider.get_variation(user_id, campaign, ApiMethods::TRACK, campaign['key'], custom_variables, variation_targeting_variables, goal_identifier)
        if variation
          goal = get_campaign_goal(campaign, goal_identifier)
          if goal.nil? || !goal["id"]
            @logger.log(
              LogLevelEnum::ERROR,
              format(
                LogMessageEnum::ErrorMessages::TRACK_API_GOAL_NOT_FOUND,
                file: FILE,
                goal_identifier: goal_identifier,
                user_id: user_id,
                campaign_key: campaign['key'],
                api_name: ApiMethods::TRACK
              )
            )
            result[campaign['key']] = false
            next
          elsif goal['type'] == GoalTypes::REVENUE && !valid_value?(revenue_value)
            @logger.log(
              LogLevelEnum::ERROR,
              format(
                LogMessageEnum::ErrorMessages::TRACK_API_REVENUE_NOT_PASSED_FOR_REVENUE_GOAL,
                file: FILE,
                user_id: user_id,
                goal_identifier: goal_identifier,
                campaign_key: campaign['key'],
                api_name: ApiMethods::TRACK
              )
            )
            result[campaign['key']] = false
            next
          elsif goal['type'] == GoalTypes::CUSTOM
            revenue_value = nil
          end
          if variation['goal_identifier']
            identifiers = variation['goal_identifier'].split(VWO_DELIMITER)
          else
            variation['goal_identifier'] = ''
            identifiers = []
          end
          if !identifiers.include? goal_identifier
            updated_goal_identifier = variation['goal_identifier']
            updated_goal_identifier += VWO_DELIMITER + goal_identifier
            @variation_decider.save_user_storage(user_id, campaign['key'], campaign['name'], variation['name'], updated_goal_identifier) if variation['name']
          else
            @logger.log(
              LogLevelEnum::INFO,
              format(
                LogMessageEnum::InfoMessages::GOAL_ALREADY_TRACKED,
                file: FILE,
                user_id: user_id,
                campaign_key: campaign['key'],
                goal_identifier: goal_identifier,
                api_name: ApiMethods::TRACK
              )
            )
            result[campaign['key']] = false
            next
          end
          if defined?(@batch_events)
            impression = create_bulk_event_impression(
              @settings_file,
              campaign['id'],
              variation['id'],
              user_id,
              goal['id'],
              revenue_value
            )
            @batch_events_queue.enqueue(impression)
          elsif  is_event_arch_enabled
            metric_map[campaign['id']] = goal['id']
            if goal['type'] == GoalTypes::REVENUE && !(revenue_props.include? goal['revenueProp'])
              revenue_props << goal['revenueProp']
            end
          else
            impression = create_impression(
              @settings_file,
              campaign['id'],
              variation['id'],
              user_id,
              @sdk_key,
              goal['id'],
              revenue_value
            )
            if @event_dispatcher.dispatch(impression)
              @logger.log(
                LogLevelEnum::INFO,
                format(
                  LogMessageEnum::InfoMessages::IMPRESSION_SUCCESS,
                  file: FILE,
                  account_id: @account_id,
                  campaign_id: campaign['id'],
                  variation_id: variation['id'],
                  end_point: EVENTS::TRACK_GOAL
                )
              )
              @logger.log(
                LogLevelEnum::INFO,
                format(
                  LogMessageEnum::InfoMessages::MAIN_KEYS_FOR_IMPRESSION,
                  file: FILE,
                  campaign_id: impression[:experiment_id],
                  account_id: impression[:account_id],
                  variation_id: impression[:combination]
                )
              )
            end
          end
          result[campaign['key']] = true
          next
        end
        result[campaign['key']] = false
      rescue StandardError => e
        @logger.log(
          LogLevelEnum::ERROR,
          format(
            e.message,
            file: FILE,
            exception: e
          )
        )
      end
    end
    if is_event_arch_enabled
      properties = get_events_base_properties(@settings_file, goal_identifier)
      payload = get_track_goal_payload_data(@settings_file, user_id, goal_identifier, revenue_value, metric_map, revenue_props)
      @event_dispatcher.dispatch_event_arch_post(properties, payload)
    end
    if result.length() == 0
      return nil
    end
    result
  rescue StandardError => e
    @logger.log(
      LogLevelEnum::ERROR,
      format(
        LogMessageEnum::ErrorMessages::API_NOT_WORKING,
        file: FILE,
        api_name: ApiMethods::TRACK,
        exception: e
      )
    )
    false
  end
def track ( campaign_key , user_id , goal_identifier , options = { } ) if is_opted_out ( ApiMethods :: TRACK ) return false end unless @is_instance_valid @logger . log ( LogLevelEnum :: ERROR , format ( LogMessageEnum :: ErrorMessages :: API_CONFIG_CORRUPTED , file : FILE , api_name : ApiMethods :: TRACK ) ) return false end options = convert_to_symbol_hash ( options ) revenue_value = options [ :revenue_value ] custom_variables = options [ :custom_variables ] variation_targeting_variables = options [ :variation_targeting_variables ] goal_type_to_track = get_goal_type_to_track ( options ) unless ( valid_string? ( campaign_key ) || campaign_key . is_a? ( Array ) || campaign_key . nil? ) && valid_string? ( user_id ) && valid_string? ( goal_identifier ) && ( custom_variables . nil? || valid_hash? ( custom_variables ) ) && ( variation_targeting_variables . nil? || valid_hash? ( variation_targeting_variables ) ) && ( GOAL_TYPES . key? ( goal_type_to_track ) ) @logger . log ( LogLevelEnum :: ERROR , format ( LogMessageEnum :: ErrorMessages :: TRACK_API_INVALID_PARAMS , file : FILE , api_name : ApiMethods :: TRACK ) ) return false end campaigns = get_campaigns ( @settings_file , campaign_key , goal_identifier , goal_type_to_track ) if campaigns . nil? return nil end metric_map = { } revenue_props = [ ] result = { } campaigns . each do | campaign | begin campaign_type = campaign [ 'type' ] if campaign_type == CampaignTypes :: FEATURE_ROLLOUT @logger . log ( LogLevelEnum :: ERROR , format ( LogMessageEnum :: ErrorMessages :: INVALID_API , file : FILE , api_name : ApiMethods :: TRACK , user_id : user_id , campaign_key : campaign [ 'key' ] , campaign_type : campaign_type ) ) result [ campaign [ 'key' ] ] = false next end variation = @variation_decider . get_variation ( user_id , campaign , ApiMethods :: TRACK , campaign [ 'key' ] , custom_variables , variation_targeting_variables , goal_identifier ) if variation goal = get_campaign_goal ( campaign , goal_identifier ) if goal . nil? || ! goal [ "id" ] @logger . log ( LogLevelEnum :: ERROR , format ( LogMessageEnum :: ErrorMessages :: TRACK_API_GOAL_NOT_FOUND , file : FILE , goal_identifier : goal_identifier , user_id : user_id , campaign_key : campaign [ 'key' ] , api_name : ApiMethods :: TRACK ) ) result [ campaign [ 'key' ] ] = false next elsif goal [ 'type' ] == GoalTypes :: REVENUE && ! valid_value? ( revenue_value ) @logger . log ( LogLevelEnum :: ERROR , format ( LogMessageEnum :: ErrorMessages :: TRACK_API_REVENUE_NOT_PASSED_FOR_REVENUE_GOAL , file : FILE , user_id : user_id , goal_identifier : goal_identifier , campaign_key : campaign [ 'key' ] , api_name : ApiMethods :: TRACK ) ) result [ campaign [ 'key' ] ] = false next elsif goal [ 'type' ] == GoalTypes :: CUSTOM revenue_value = nil end if variation [ 'goal_identifier' ] identifiers = variation [ 'goal_identifier' ] . split ( VWO_DELIMITER ) else variation [ 'goal_identifier' ] = '' identifiers = [ ] end if ! identifiers . include? goal_identifier updated_goal_identifier = variation [ 'goal_identifier' ] updated_goal_identifier += VWO_DELIMITER + goal_identifier @variation_decider . save_user_storage ( user_id , campaign [ 'key' ] , campaign [ 'name' ] , variation [ 'name' ] , updated_goal_identifier ) if variation [ 'name' ] else @logger . log ( LogLevelEnum :: INFO , format ( LogMessageEnum :: InfoMessages :: GOAL_ALREADY_TRACKED , file : FILE , user_id : user_id , campaign_key : campaign [ 'key' ] , goal_identifier : goal_identifier , api_name : ApiMethods :: TRACK ) ) result [ campaign [ 'key' ] ] = false next end if defined? ( @batch_events ) impression = create_bulk_event_impression ( @settings_file , campaign [ 'id' ] , variation [ 'id' ] , user_id , goal [ 'id' ] , revenue_value ) @batch_events_queue . enqueue ( impression ) elsif is_event_arch_enabled metric_map [ campaign [ 'id' ] ] = goal [ 'id' ] if goal [ 'type' ] == GoalTypes :: REVENUE && ! ( revenue_props . include? goal [ 'revenueProp' ] ) revenue_props << goal [ 'revenueProp' ] end else impression = create_impression ( @settings_file , campaign [ 'id' ] , variation [ 'id' ] , user_id , @sdk_key , goal [ 'id' ] , revenue_value ) if @event_dispatcher . dispatch ( impression ) @logger . log ( LogLevelEnum :: INFO , format ( LogMessageEnum :: InfoMessages :: IMPRESSION_SUCCESS , file : FILE , account_id : @account_id , campaign_id : campaign [ 'id' ] , variation_id : variation [ 'id' ] , end_point : EVENTS :: TRACK_GOAL ) ) @logger . log ( LogLevelEnum :: INFO , format ( LogMessageEnum :: InfoMessages :: MAIN_KEYS_FOR_IMPRESSION , file : FILE , campaign_id : impression [ :experiment_id ] , account_id : impression [ :account_id ] , variation_id : impression [ :combination ] ) ) end end result [ campaign [ 'key' ] ] = true next end result [ campaign [ 'key' ] ] = false rescue StandardError => e @logger . log ( LogLevelEnum :: ERROR , format ( e . message , file : FILE , exception : e ) ) end end if is_event_arch_enabled properties = get_events_base_properties ( @settings_file , goal_identifier ) payload = get_track_goal_payload_data ( @settings_file , user_id , goal_identifier , revenue_value , metric_map , revenue_props ) @event_dispatcher . dispatch_event_arch_post ( properties , payload ) end if result . length ( ) == 0 return nil end result rescue StandardError => e @logger . log ( LogLevelEnum :: ERROR , format ( LogMessageEnum :: ErrorMessages :: API_NOT_WORKING , file : FILE , api_name : ApiMethods :: TRACK , exception : e ) ) false end
This API method: Marks the conversion of the campaign
for a particular goal
1. validates the arguments being passed
2.
This API method : Marks the conversion of the campaign for a particular goal 1 . validates the arguments being passed 2 .
# Check for valid args # log invalid params # Get campaigns settings # Validate campaign # set variation at user storage
campaign_key
<not_specific>
user_id
<not_specific>
goal_identifier
<not_specific>
options
<not_specific>
param[String]
:campaign_key Unique campaign key
: campaign_key Unique campaign key
param[String]
:user_id ID assigned to a user
: user_id ID assigned to a user
param[String]
:goal_identifier Unique campaign's goal identifier
: goal_identifier Unique campaign ' s goal identifier
param[Hash]
:options Contains revenue value and custom variables
: options Contains revenue value and custom variables
param[Numeric|String]
:revenue_value It is the revenue generated on triggering the goal
: revenue_value It is the revenue generated on triggering the goal