Skip to content

Commit a6f6ba4

Browse files
sakshamg1304rohitesh-wingify
authored andcommitted
feat: support for salting
1 parent fe3d19c commit a6f6ba4

File tree

6 files changed

+68
-16
lines changed

6 files changed

+68
-16
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.5.0] - 2024-03-12
9+
10+
### Added
11+
12+
- Added the support for using salt for bucketing if provided in the rule configuration.
13+
814
## [1.4.0] - 2024-03-04
915

1016
### Added

VWOFmeSdk.NetStandard2.0/VWOFmeSdk.NetStandard2.0.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<AssemblyName>VWOFmeSdk</AssemblyName>
77
<TargetFramework>netstandard2.0</TargetFramework>
88
<PackageId>VWO.FME.Sdk</PackageId>
9-
<Version>1.4.0</Version>
9+
<Version>1.5.0</Version>
1010
<Authors>VWO devs</Authors>
1111
<Company>Wingify</Company>
1212
<Product>VWO</Product>

VWOFmeSdk/Models/Campaign.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public class Campaign
3939
private int endRangeVariation = 0;
4040
private List<Variable> variables;
4141
private double weight;
42+
private string salt;
4243

4344
public int Id
4445
{
@@ -136,6 +137,12 @@ public int EndRangeVariation
136137
set { endRangeVariation = value; }
137138
}
138139

140+
public string Salt
141+
{
142+
get { return salt; }
143+
set { salt = value; }
144+
}
145+
139146
public void SetModelFromDictionary(Campaign model)
140147
{
141148
if (model.Id != 0)
@@ -185,6 +192,10 @@ public void SetModelFromDictionary(Campaign model)
185192

186193
if (model.EndRangeVariation != 0)
187194
endRangeVariation = model.EndRangeVariation;
195+
196+
if(model.Salt != null) {
197+
salt = model.Salt;
198+
}
188199
}
189200
}
190201
}

VWOFmeSdk/Models/Variation.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public class Variation
3434
private Dictionary<string, object> segments = new Dictionary<string, object>();
3535
private string ruleKey;
3636
private string type;
37+
private string salt;
3738

3839
public int Id
3940
{
@@ -95,10 +96,16 @@ public string RuleKey
9596
set { ruleKey = value; }
9697
}
9798

98-
public string Type
99+
public string Type
99100
{
100101
get { return type; }
101102
set { type = value; }
102103
}
104+
105+
public string Salt
106+
{
107+
get { return salt; }
108+
set { salt = value; }
109+
}
103110
}
104111
}

VWOFmeSdk/Services/CampaignDecisionService.cs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
using VWOFmeSdk.Packages.DecisionMaker;
2727
using VWOFmeSdk.Packages.Logger.Enums;
2828
using VWOFmeSdk.Packages.SegmentationEvaluator.Core;
29+
using Newtonsoft.Json;
2930

3031
namespace VWOFmeSdk.Services
3132
{
@@ -38,22 +39,24 @@ public class CampaignDecisionService
3839
/// <param name="campaign"></param>
3940
public bool IsUserPartOfCampaign(string userId, Campaign campaign)
4041
{
41-
if (campaign == null || userId == null)
42+
if (campaign == null || string.IsNullOrEmpty(userId))
4243
{
4344
return false;
4445
}
4546

46-
double trafficAllocation;
47-
if (campaign.Type == CampaignTypeEnum.ROLLOUT.GetValue() || campaign.Type == CampaignTypeEnum.PERSONALIZE.GetValue())
48-
{
49-
trafficAllocation = campaign.Variations[0].Weight;
50-
}
51-
else
52-
{
53-
trafficAllocation = campaign.PercentTraffic;
54-
}
47+
// Determine if the campaign is of type ROLLOUT or PERSONALIZE
48+
bool isRolloutOrPersonalize = campaign.Type == CampaignTypeEnum.ROLLOUT.GetValue() || campaign.Type == CampaignTypeEnum.PERSONALIZE.GetValue();
5549

56-
int valueAssignedToUser = new DecisionMaker().GetBucketValueForUser(campaign.Id + "_" + userId);
50+
// Get the salt based on the campaign type
51+
string salt = isRolloutOrPersonalize ? campaign.Variations[0].Salt : campaign.Salt;
52+
53+
// Get the traffic allocation based on the campaign type
54+
double trafficAllocation = isRolloutOrPersonalize ? campaign.Variations[0].Weight : campaign.PercentTraffic;
55+
56+
// Build the bucket key
57+
string bucketKey = !string.IsNullOrEmpty(salt) ? $"{salt}_{userId}" : $"{campaign.Id}_{userId}";
58+
59+
int valueAssignedToUser = new DecisionMaker().GetBucketValueForUser(bucketKey);
5760
bool isUserPart = valueAssignedToUser != 0 && valueAssignedToUser <= trafficAllocation;
5861

5962
LoggerService.Log(LogLevelEnum.INFO, "USER_PART_OF_CAMPAIGN", new Dictionary<string, string>
@@ -109,14 +112,22 @@ public Variation CheckInRange(Variation variation, int bucketValue)
109112
/// <param name="campaign"></param>
110113
public Variation BucketUserToVariation(string userId, string accountId, Campaign campaign)
111114
{
112-
if (campaign == null || userId == null)
115+
if (campaign == null || string.IsNullOrEmpty(userId))
113116
{
114117
return null;
115118
}
116119

117120
int multiplier = campaign.PercentTraffic != 0 ? 1 : 0;
118121
int percentTraffic = campaign.PercentTraffic;
119-
long hashValue = new DecisionMaker().GenerateHashValue(campaign.Id + "_" + accountId + "_" + userId);
122+
123+
// Get salt
124+
string salt = campaign.Salt;
125+
126+
// Get bucket key
127+
string bucketKey = !string.IsNullOrEmpty(salt) ? $"{salt}_{accountId}_{userId}" : $"{campaign.Id}_{accountId}_{userId}";
128+
129+
// Generate hash value
130+
long hashValue = new DecisionMaker().GenerateHashValue(bucketKey);
120131
int bucketValue = new DecisionMaker().GenerateBucketValue(hashValue, ConstantsNamespace.Constants.MAX_TRAFFIC_VALUE, multiplier);
121132

122133
LoggerService.Log(LogLevelEnum.DEBUG, "USER_BUCKET_TO_VARIATION", new Dictionary<string, string>

VWOFmeSdk/Utils/CampaignUtil.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,24 @@ public static void ScaleVariationWeights(List<Variation> variations)
116116
/// <returns>The bucketing seed.</returns>
117117
public static string GetBucketingSeed(string userId, Campaign campaign, int? groupId)
118118
{
119-
return groupId.HasValue ? $"{groupId}_{userId}" : $"{campaign.Id}_{userId}";
119+
//return groupId.HasValue ? $"{groupId}_{userId}" : $"{campaign.Id}_{userId}";
120+
if(groupId.HasValue) {
121+
return $"{groupId}_{userId}";
122+
}
123+
124+
// Determine if the campaign is of type ROLLOUT or PERSONALIZE
125+
bool isRolloutOrPersonalize = campaign.Type == CampaignTypeEnum.ROLLOUT.GetValue() || campaign.Type == CampaignTypeEnum.PERSONALIZE.GetValue();
126+
127+
// Get the salt based on the campaign type
128+
string salt = isRolloutOrPersonalize ? campaign.Variations[0].Salt : campaign.Salt;
129+
130+
if (!string.IsNullOrEmpty(salt))
131+
{
132+
return $"{salt}_{userId}";
133+
} else {
134+
return $"{campaign.Id}_{userId}";
135+
}
136+
120137
}
121138

122139
/// <summary>

0 commit comments

Comments
 (0)