Module: CampaignUtil

Defined in:
lib/wingify/utils/campaign_util.rb

Class Method Summary collapse

Class Method Details

.assign_range_values(variation, current_allocation) ⇒ Integer

Assigns start and end range values to a variation

Parameters:

  • variation (VariationModel)

    The variation to assign the start and end range values to

  • current_allocation (Integer)

    The current allocation

Returns:

  • (Integer)

    The step factor



52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/wingify/utils/campaign_util.rb', line 52

def self.assign_range_values(variation, current_allocation)
  step_factor = get_variation_bucket_range(variation.get_weight)

  if step_factor > 0
    variation.set_start_range(current_allocation + 1)
    variation.set_end_range(current_allocation + step_factor)
  else
    variation.set_start_range(-1)
    variation.set_end_range(-1)
  end

  step_factor
end

.assign_range_values_meg(data, current_allocation) ⇒ Integer

Assigns range values to a MEG campaign

Parameters:

  • data (VariationModel)

    The variation to assign the start and end range values to

  • current_allocation (Integer)

    The current allocation

Returns:

  • (Integer)

    The step factor



202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/wingify/utils/campaign_util.rb', line 202

def self.assign_range_values_meg(data, current_allocation)
  step_factor = get_variation_bucket_range(data.weight)

  if step_factor > 0
    data.start_range_variation = current_allocation + 1
    data.end_range_variation = current_allocation + step_factor
  else
    data.start_range_variation = -1
    data.end_range_variation = -1
  end

  step_factor
end

.find_groups_feature_part_of(settings, feature_key) ⇒ Array

Finds groups associated with a feature

Parameters:

  • settings (SettingsModel)

    The settings for the VWO instance

  • feature_key (String)

    The key of the feature

Returns:

  • (Array)

    The groups associated with the feature



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/wingify/utils/campaign_util.rb', line 138

def self.find_groups_feature_part_of(settings, feature_key)
  rule_array = []
  settings.get_features.each do |feature|
    if feature.get_key == feature_key
      rule_array.concat(feature.get_rules)
    end
  end

  groups = []
  rule_array.each do |rule|
    group = get_group_details_if_campaign_part_of_it(settings, rule.get_campaign_id, rule.get_type == CampaignTypeEnum::PERSONALIZE ? rule.get_variation_id : nil)
    groups << group unless group.empty? || groups.any? { |g| g[:group_id] == group[:group_id] }
  end

  groups
end

.get_bucketing_seed(user_id, campaign, group_id = nil) ⇒ String

Generates a bucketing seed based on user ID and campaign

Parameters:

  • user_id (String)

    The ID of the user

  • campaign (CampaignModel)

    The campaign to generate the bucketing seed for

  • group_id (String) (defaults to: nil)

    The ID of the group

Returns:

  • (String)

    The bucketing seed



85
86
87
88
89
90
91
92
# File 'lib/wingify/utils/campaign_util.rb', line 85

def self.get_bucketing_seed(user_id, campaign, group_id = nil)
  return "#{group_id}_#{user_id}" if group_id

  is_rollout_or_personalize = [CampaignTypeEnum::ROLLOUT, CampaignTypeEnum::PERSONALIZE].include?(campaign.get_type)
  salt = is_rollout_or_personalize ? campaign.get_variations.first.get_salt : campaign.get_salt

  salt ? "#{salt}_#{user_id}" : "#{campaign.get_id}_#{user_id}"
end

.get_campaign_ids_from_feature_key(settings, feature_key) ⇒ Array

Retrieves campaign IDs from a feature key

Parameters:

  • settings (SettingsModel)

    The settings for the VWO instance

  • feature_key (String)

    The key of the feature

Returns:

  • (Array)

    The campaign IDs associated with the feature



191
192
193
194
195
196
# File 'lib/wingify/utils/campaign_util.rb', line 191

def self.get_campaign_ids_from_feature_key(settings, feature_key)
  settings.get_features.each do |feature|
    return feature.get_rules.map(&:get_campaign_id) if feature.get_key == feature_key
  end
  []
end

.get_campaign_key_from_campaign_id(settings, campaign_id) ⇒ String

Retrieves the campaign key from the campaign ID

Parameters:

  • settings (SettingsModel)

    The settings for the VWO instance

  • campaign_id (Integer)

    The ID of the campaign

Returns:

  • (String)

    The campaign key



254
255
256
257
258
259
# File 'lib/wingify/utils/campaign_util.rb', line 254

def self.get_campaign_key_from_campaign_id(settings, campaign_id)
  settings.get_campaigns.each do |campaign|
    return campaign.get_key if campaign.get_id == campaign_id
  end
  nil
end

.get_campaign_type_from_campaign_id(settings, campaign_id) ⇒ String

Retrieves the campaign type from the campaign ID

Parameters:

  • settings (SettingsModel)

    The settings for the VWO instance

  • campaign_id (Integer)

    The ID of the campaign

Returns:

  • (String)

    The campaign type



278
279
280
281
282
283
# File 'lib/wingify/utils/campaign_util.rb', line 278

def self.get_campaign_type_from_campaign_id(settings, campaign_id)
  campaign = settings.get_campaigns.find { |c| c.get_id == campaign_id }
  return nil unless campaign

  campaign.get_type
end

.get_campaigns_by_group_id(settings, group_id) ⇒ Array

Retrieves campaigns by group ID

Parameters:

  • settings (SettingsModel)

    The settings for the VWO instance

  • group_id (String)

    The ID of the group

Returns:

  • (Array)

    The campaigns associated with the group



159
160
161
# File 'lib/wingify/utils/campaign_util.rb', line 159

def self.get_campaigns_by_group_id(settings, group_id)
  settings.get_groups[group_id.to_s]&.fetch(:campaigns.to_s, []) || []
end

.get_feature_keys_from_campaign_ids(settings, campaign_ids) ⇒ Array

Retrieves feature keys from campaign IDs

Parameters:

  • settings (SettingsModel)

    The settings for the VWO instance

  • campaign_ids (Array)

    The IDs of the campaigns

Returns:

  • (Array)

    The feature keys associated with the campaigns



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/wingify/utils/campaign_util.rb', line 167

def self.get_feature_keys_from_campaign_ids(settings, campaign_ids)
  feature_keys = []

  campaign_ids.each do |campaign|
    campaign_id, variation_id = campaign.split('_').map(&:to_i)

    settings.get_features.each do |feature|
      next if feature_keys.include?(feature.get_key)

      feature.get_rules.each do |rule|
        if rule.get_campaign_id == campaign_id
          feature_keys << feature.get_key if variation_id.nil? || rule.get_variation_id == variation_id
        end
      end
    end
  end

  feature_keys
end

.get_group_details_if_campaign_part_of_it(settings, campaign_id, variation_id = nil) ⇒ Hash

Retrieves campaign group details if part of a group

Parameters:

  • settings (SettingsModel)

    The settings for the VWO instance

  • campaign_id (Integer)

    The ID of the campaign

  • variation_id (Integer) (defaults to: nil)

    The ID of the variation

Returns:

  • (Hash)

    The group details



123
124
125
126
127
128
129
130
131
132
# File 'lib/wingify/utils/campaign_util.rb', line 123

def self.get_group_details_if_campaign_part_of_it(settings, campaign_id, variation_id = nil)
  campaign_to_check = variation_id ? "#{campaign_id}_#{variation_id}" : campaign_id.to_s

  if settings.get_campaign_groups.key?(campaign_to_check)
    group_id = settings.get_campaign_groups[campaign_to_check]
    { group_id: group_id, group_name: settings.get_groups[group_id.to_s][:name.to_s]}
  else
    {}
  end
end

.get_rule_type_using_campaign_id_from_feature(feature, campaign_id) ⇒ Object

Retrieves the rule type for a given campaign ID from a feature



217
218
219
220
# File 'lib/wingify/utils/campaign_util.rb', line 217

def self.get_rule_type_using_campaign_id_from_feature(feature, campaign_id)
  rule = feature.get_rules.find { |r| r.get_campaign_id == campaign_id }
  rule ? rule.get_type : ''
end

.get_variation_bucket_range(variation_weight) ⇒ Integer

Calculates bucket range for a variation

Parameters:

  • variation_weight (Float)

    The weight of the variation

Returns:

  • (Integer)

    The bucket range



225
226
227
228
229
230
# File 'lib/wingify/utils/campaign_util.rb', line 225

def self.get_variation_bucket_range(variation_weight)
  return 0 unless variation_weight && variation_weight.positive?

  start_range = (variation_weight * 100).ceil
  [start_range, Constants::MAX_TRAFFIC_VALUE].min
end

.get_variation_from_campaign_key(settings, campaign_key, variation_id) ⇒ VariationModel

Retrieves variation from campaign key

Parameters:

  • settings (SettingsModel)

    The settings for the VWO instance

  • campaign_key (String)

    The key of the campaign

  • variation_id (Integer)

    The ID of the variation

Returns:



99
100
101
102
103
104
105
# File 'lib/wingify/utils/campaign_util.rb', line 99

def self.get_variation_from_campaign_key(settings, campaign_key, variation_id)
  campaign = settings.get_campaigns.find { |c| c.get_key == campaign_key }
  return nil unless campaign

  variation = campaign.get_variations.find { |v| v.get_id == variation_id }
  variation ? VariationModel.new.model_from_dictionary(variation) : nil
end

.get_variation_name_from_campaign_id_and_variation_id(settings, campaign_id, variation_id) ⇒ String

Retrieves the variation name from the campaign ID and variation ID

Parameters:

  • settings (SettingsModel)

    The settings for the VWO instance

  • campaign_id (Integer)

    The ID of the campaign

  • variation_id (Integer)

    The ID of the variation

Returns:

  • (String)

    The variation name



266
267
268
269
270
271
272
# File 'lib/wingify/utils/campaign_util.rb', line 266

def self.get_variation_name_from_campaign_id_and_variation_id(settings, campaign_id, variation_id)
  campaign = settings.get_campaigns.find { |c| c.get_id == campaign_id }
  return nil unless campaign

  variation = campaign.get_variations.find { |v| v.get_id == variation_id }
  variation ? variation.get_key : nil
end

.handle_rollout_campaign(campaign) ⇒ Object

Handles rollout campaign logic

Parameters:

  • campaign (CampaignModel)

    The campaign to handle the rollout logic for



234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/wingify/utils/campaign_util.rb', line 234

def self.handle_rollout_campaign(campaign)
  campaign.get_variations.each do |variation|
    end_range = variation.get_weight * 100
    variation.set_start_range(1)
    variation.set_end_range(end_range)

    LoggerService.log(LogLevelEnum::INFO, "VARIATION_RANGE_ALLOCATION", {
      variationKey: variation.get_key,
      campaignKey: campaign.get_key,
      variationWeight: variation.get_weight,
      startRange: 1,
      endRange: end_range
    })
  end
end

.scale_variation_weights(variations) ⇒ Array<VariationModel>

Scales variation weights to sum up to 100%

Parameters:

  • variations (Array<VariationModel>)

    The variations to scale the weights of

Returns:



69
70
71
72
73
74
75
76
77
78
# File 'lib/wingify/utils/campaign_util.rb', line 69

def self.scale_variation_weights(variations)
  total_weight = variations.sum(&:weight)

  if total_weight.zero?
    equal_weight = 100.0 / variations.length
    variations.each { |variation| variation.weight = equal_weight }
  else
    variations.each { |variation| variation.weight = (variation.weight / total_weight) * 100 }
  end
end

.set_campaign_allocation(campaigns) ⇒ Object

Sets campaign allocation ranges

Parameters:

  • campaigns (Array<CampaignModel>)

    The campaigns to set the allocation ranges for



109
110
111
112
113
114
115
116
# File 'lib/wingify/utils/campaign_util.rb', line 109

def self.set_campaign_allocation(campaigns)
  current_allocation = 0

  campaigns.each do |campaign|
    step_factor = assign_range_values_meg(campaign, current_allocation)
    current_allocation += step_factor
  end
end

.set_variation_allocation(campaign) ⇒ Object

Sets the variation allocation for a campaign

Parameters:

  • campaign (CampaignModel)

    The campaign to set the variation allocation for



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/wingify/utils/campaign_util.rb', line 28

def self.set_variation_allocation(campaign)
  if [CampaignTypeEnum::ROLLOUT, CampaignTypeEnum::PERSONALIZE].include?(campaign.get_type)
    handle_rollout_campaign(campaign)
  else
    current_allocation = 0
    campaign.get_variations.each do |variation|
      step_factor = assign_range_values(variation, current_allocation)
      current_allocation += step_factor

      LoggerService.log(LogLevelEnum::INFO, "VARIATION_RANGE_ALLOCATION", {
        variationKey: variation.get_key,
        campaignKey: campaign.get_key,
        variationWeight: variation.get_weight,
        startRange: variation.get_start_range_variation,
        endRange: variation.get_end_range_variation
      })
    end
  end
end