.NET V3.0.X

Introduction

The following documentation will help you get Flagship running in your .Net environment (server-side or client side) with preconfigured methods to implement the Decision API & Bucketing.

Feel free to contact us if you have any questions regarding this documentation.

SDK features

That SDK version helps you :

Prerequisites

  • This SDK requires .Net with the following target framework versions:
    • net40
    • net45
    • netstandard2.0
    • net5.0 or later

Lern more

  • Your server/device must have an access to the internet.

Good to know

Getting Started

Installation

Follow these steps to install the .Net SDK

Install from nuget

To install from nuget, just run a Install-Package Nuget command to add the SDK to your project

Install-Package Flagship.SDK

Initialization

To initialize and start the SDK, simply call the Start function of the Flagship.Main.Fs class, in the most appropriate location for your application.

// Use the Flagship package
using Flagship.Main;
// ...

Fs.Start("ENV_ID", "API_KEY");

Start static function

That method start the Flagship SDK.

  • static void Start(string envId, string apiKey, [FlagshipConfig config = null])
ParameterTypeDescription
envIdstringEnvironment id provided by Flagship.
apiKeystringApi authentication key provided by Flagship.
configFlagshipConfigCustom flagship configuration. see configuration attribute

Advanced Configuration

Here are all available settings you can set on the SDK.

Those settings can be setup only at the start function.

Here's the full pure example of usage :

// Use the Flagship package
using Flagship.Main;
// ...

Fs.Start("ENV_ID", "API_KEY", new DecisionApiConfig { 
                LogManager = new sentryCustomLog(),
                LogLevel = Flagship.Enums.LogLevel.ALL,
                Timeout = TimeSpan.FromSeconds(2),
            });
// Use the Flagship package
using Flagship.Main;
// ...

Fs.Start("ENV_ID", "API_KEY", new BucketingConfig { 
                LogManager = new sentryCustomLog(),
                LogLevel = Flagship.Enums.LogLevel.ALL,
                Timeout = TimeSpan.FromSeconds(2),
                PollingInterval = TimeSpan.FromSeconds(2)
            });

Below the details of every attribute you can set inside the SDK config object :

AttributeTypeDefaultDescription
TimeoutTimeSpan2sRequired
Specify timeout for api request.
Note: timeout can't be lower than 0 second.
LogLevelFlagship.Enums.LogLevelFlagship.Enums.LogLevel.ALLRequired
Set the maximum log level to display
seeLogLevel
LogManagerFlagship.Logger.IFsLogManagerOjectRequired
Specify a custom implementation of LogManager in order to receive logs from the SDK.
Note: The object must fill Interface IFsLogManager
PollingIntervalTimeSpan2sRequired
Specify delay between two bucketing polling when SDK is running on Bucketing mode.
Note: If 0 is given, it should poll only once at start time.
VisitorCacheImplementationFlagship.Cache.IVisitorCacheImplementationundefinedOptional
Define an object that implement the interface IVisitorCacheImplementation, to handle the visitor cache. see cache-manager
HitCacheImplementationFlagship.Cache.IHitCacheImplementationundefinedOptional
Define an object that implement the interface IHitCacheImplementation, to handle the visitor cache. see cache-manager
DisableCachebooleanfalseRequired
if it's set to true, hit cache and visitor cache will be disabled otherwise will be enabled. see cache-manager
StatusChangedFlagship.Delegate.StatusChangeDelegateundefinedOptional
Define a callable in order to get callback when the SDK status has changed.
see arguments.

Decision Mode

API Mode (by default)

When the SDK is running in API mode, the campaign assignments and targeting validation will be run through our Decision API. In this mode, each time a new Decision is required, it will create an HTTPS request to the API.
This mode is used by default for all our SDK.

Bucketing Mode

When the SDK is running in Bucketing mode, the SDK downloads all the campaigns configurations at once in a single bucketing file so that variation assignment can be computed client-side by the SDK. This bucketing file is stored in cache and will only be downloaded again when campaign configurations are modified in the Flagship interface. Learn more


LogLevel

Flagship.Enums.LogLevel is an enum defined the level of log to receive

KeyValueTypeDescription
NONE0intLogging will be disabled.
EMERGENCY1intOnly emergencies will be logged
ALERT2intOnly alerts and above will be logged.
CRITICAL3intOnly critical and above will be logged.
ERROR4intOnly errors and above will be logged.
WARNING5intOnly warnings and above will be logged.
NOTICE6intOnly notices and above will be logged.
INFO7intOnly info logs and above will be logged.
DEBUG8intOnly debug logs and above will be logged.
ALL9intEverything will be logged.

IFsLogManager

The aims of Flagship.Logger.IFsLogManager Interface is to define methods that an object must have in order to receive Flagship SDK logs.

interface IFsLogManager
    {
         void Emergency(string message, string tag);
         void Alert(string message, string tag);
         void Critical(string message, string tag);
         void Error(string message, string tag);
         void Warning(string message, string tag);
         void Notice(string message, string tag);
         void Info(string message, string tag);
         void Debug(string message, string tag);
         void Log(LogLevel level, string message, string tag);
    }
ArgumentTypeDescription
messagestringGet a description of the log
tagstringGet the function that triggered the log
levelnumberGet the log level.

Note:only for log method see LogLevel

FlagshipStatus

Flagship.Enums.FlagshipStatus is an enum defining the different status of Flagship SDK

KeyValueTypeDescription
NOT_INITIALIZED0intIt is the default initial status. This status remains until the sdk has been initialized successfully.
STARTING1intFlagship SDK is starting.
POLLING2intFlagship SDK has been started successfully but is still polling campaigns.
READY_PANIC_ON3intFlagship SDK is ready but is running in Panic mode: All features are disabled except the one which refresh this status.
READY4intFlagship SDK is ready to use.

StatusChanged

The Flagship.Delegate.StatusChangeDelegate delegate has one argument

ArgumentTypeDescription
statusFlagship.Enums.FlagshipStatusStatus of the SDK. seeFlagshipStatus

Other Flagship.Main.Fs class methods

Status property

Return current status of Flagship SDK. seeFlagshipStatus

  • static FlagshipStatus Status

Config property

Return the current config used by the SDK. see configuration attribute

  • FlagshipConfig Config

Visitor property

Return the last visitor created and saved or return undefined if no visitor has been saved. see newVisitor.

  • static Visitor Visitor

Create a visitor

The Flagship.FsVisitor.Visitor instance is an object that contains everything related to your visitor, its data but also the Decision of Flagship.

By creating a new visitor, you be able to set all the data relevant for Flagship to take a Decision and know your visitor, this includes :

The visitor context is a dataset (object) that defines your current visitor.
This dataset is sent to Flagship for targeting purposes (use-case assignment) but also to enrich your reporting with Context Filters.
You may have to sync with your team to know what data is useful for them to have in Flagship reporting.

By default, depending on Flagship.Config.FlagshipConfig, this will automatically trigger a Decision of Flagship and will be available through the getFlag method.

Let's take an example:
if you want to enable a specific feature to all your VIPs user,
you'll need to add this data as an attribute into the visitor context (key-value pair) in the visitor context: isVIP: true.
Based on your targeting criteria defined in your use-case (isVIP === true), Flagship will take the Decision and show your feature to visitors that at least contains isVIP in their context and for which isVIP is equal to true.

using Flagship.Main;

//...

var visitor = Fs.NewVisitor("<VISITOR_ID>")
  .IsAuthenticated(true)
  .HasConsented(true)
  .WithContext(new Dictionary<string, object> {
    ["isVIP"] = true,
    ["country"] = "NL",
    ["loginProvider"] = "Google"
    })
  .Build();

NewVisitor static function

Creates and returns a Flagship.FsVisitor.VisitorBuilder or null if the SDK hasn't started successfully.

This method should always be called after the Flagship SDK has started.

  • static VisitorBuilder NewVisitor()

Initialize the builder without visitorID and Return a Flagship.FsVisitor.VisitorBuilder or null if the SDK hasn't started successfully.

  • static VisitorBuilder NewVisitor(string visitorId)

Initialize the builder with visitorId and Return a Flagship.FsVisitor.VisitorBuilder or null if the SDK hasn't started successfully.

ParameterTypeDescription
visitorIdstringUnique visitor identifier
  • static VisitorBuilder NewVisitor(InstanceType instanceType)

Initialize the builder with InstanceType and Return a Flagship.FsVisitor.VisitorBuilder or null if the SDK hasn't started successfully.

ParameterTypeDescription
InstanceTypeFlagship.Enums.InstanceTypeDefined if the SDK will save the newly created visitor instance into the Flagship instance
  • static VisitorBuilder NewVisitor(string visitorId, InstanceType instanceType)

Initialize the builder with visitorId and InstanceType and Return a Flagship.FsVisitor.VisitorBuilder or null if the SDK hasn't started successfully.

ParameterTypeDescription
visitorIdstringUnique visitor identifier.
InstanceTypeFlagship.Enums.InstanceTypeDefined if the SDK will save the newly created visitor instance into the Flagship instance

VisitorBuilder

Flagship.FsVisitor.VisitorBuilder is a fluent interface builder api managing Visitor creation.

  • VisitorBuilder IsAuthenticated(bool isAuthenticated)

    Specify if the Visitor is authenticated or anonymous.

ParameterTypeDescription
isAuthenticatedbooltrue for an authenticated visitor, false for an anonymous visitor.
  • VisitorBuilder HasConsented(bool hasConsented)

    Specify if the Visitor has consented for personal data usage. When false some features will be deactivated, cache will be deactivated and cleared.

ParameterTypeDescription
hasConsentedboolSet to true when the visitor has consented, false otherwise.
  • VisitorBuilder WithContext(IDictionary<string, object> context)

    Specify Visitor initial context key / values used for targeting.

ParameterTypeDescription
withContextIDictionary<string, object>|visitor initial context.

🚧

  • User context keys must have a type of string
  • User context values must have a type of string, bool, numeric
  • User context keys and values are case sensitive
  • Visitor Build()

    Complete the Visitor Creation process and return an instance of \Flagship\Visitor\Visitor

🚧

  • If visitorId is not given, the SDK will generat one by default
  • If IsAuthenticated is not set, the SDK will set false by default
  • If HasConsented is not set, the SDK will set true by default

Updating the visitor context

The user context is a property dataset that defines the current user of your app. This dataset is sent and used as targeting criteria for campaign assignment.

The following method from the Flagship.FsVisitor.Visitor instance allows you to set new context values matching the given keys.

using Flagship.Main;

//...

var visitor = Fs.NewVisitor("<VISITOR_ID>")
  .IsAuthenticated(true)
  .HasConsented(true)
  .WithContext(new Dictionary<string, object> {
    ["isVIP"] = true,
    ["country"] = "NL",
    ["loginProvider"] = "Google"
    })
  .Build();

visitor.UpdateContext("lastPurchaseDate", DateTime.Now.ToShortDateString());

updateContext function

Update the visitor context values, matching the given keys, used for targeting.

A new context value associated with this key will be created if there is no previous matching value.

  • void UpdateContext(IDictionary<string, object> context)

It has one argument :

ArgumentTypeDescription
contextIDictionary<string, object>A Set of keys, values.
  • void UpdateContext(string key, string value)

Update the visitor context values, matching the given key or created one if there is no previous matching value

ParameterTypeDescription
keystringContext key.
valuestringContext value.
  • void UpdateContext(string key, double value)

Update the visitor context values, matching the given key or created one if there is no previous matching value

ParameterTypeDescription
keystringContext key.
valuedoubleContext value.
  • void UpdateContext(string key, bool value)

Update the visitor context values, matching the given key or created one if there is no previous matching value

ParameterTypeDescription
keystringContext key.
valueboolContext value.

Context property

This property returns all the visitor's current context as an object

  • `IDictionary<string, object> Context

ClearContext function

Clear the actual visitor context

  • void ClearContext()

🚧

  • User context keys must have a type of string
  • User context values must have a type of string, bool, numeric
  • User context keys and values are case sensitive

update context with predefined keys of context

using Flagship.Main;

//...

var visitor = Fs.NewVisitor("<VISITOR_ID>")
  .IsAuthenticated(true)
  .HasConsented(true)
  .WithContext(new Dictionary<string, object> {
    ["isVIP"] = true,
    ["country"] = "NL",
    ["loginProvider"] = "Google"
    })
  .Build();

visitor.UpdateContext(Flagship.Enums.PredefinedContext.OS_NAME, "linux");
visitor.UpdateContext(Flagship.Enums.PredefinedContext.IP, "127.0.0.1");

Learn more about predefined keys of context

Managing visitor campaigns

Fetching Flags

The FetchFlags() method of the Visitor instance, according to Decision Mode, will either automatically call the Flagship Decision API to run campaign assignments according to the current user context and retrieve applicable flags,
or check bucketing file, validate campaigns targeting the visitor, assign a variation and retrieve applicable flags

These flags are then stored in the SDK and updated asynchronously when FetchFlags() is called.

using Flagship.Main;

//...

var visitor = Fs.NewVisitor("<VISITOR_ID>")
  .IsAuthenticated(true)
  .HasConsented(true)
  .WithContext(new Dictionary<string, object> {
    ["isVIP"] = true,
    ["country"] = "NL",
    ["loginProvider"] = "Google"
    })
  .Build();
  
  await visitor.FetchFlags();

//ready to use all features from the SDK

FetchFlags function

In DecisionApi Mode this function calls the Flagship Decision API to run campaign assignments according to the current user context and retrieve applicable flags.

In bucketing Mode, it checks bucketing file, validates campaigns targeting the visitor, assigns a variation, and retrieves applicable flags

  • Task FetchFlags()

Getting flags

Once the campaign has been assigned and fetched, all the flags are stored in the SDK. You can retrieve them using the following functions from the Visitor instance:

using Flagship.Main;

//...

var visitor = Fs.NewVisitor("<VISITOR_ID>")
  .IsAuthenticated(true)
  .HasConsented(true)
  .WithContext(new Dictionary<string, object> {
    ["isVIP"] = true,
    ["country"] = "NL",
    ["loginProvider"] = "Google"
    })
  .Build();
  
  await visitor.FetchFlags();

var flag = visitor.GetFlag("displayVipFeature", false);

GetFlag function

Return a Flag object by its key. If no flag match the given key an empty flag will be returned. Call Exists to check if the flag has been found.

  • IFlag<T> GetFlag(string key, T defaultValue)
ArgumentTypeDescription
keystringkey associated to the flag.
defaultValueTflag default value.

🚧

  • Default value must be one of the following type : string, number, boolean, Newtonsoft.Json.Linq.JArray, Newtonsoft.Json.Linq.JObject.

Getting flags current values

GetValue function

To retrieve flag current value, simply call GetValue() method of the Flag object.

using Flagship.Main;

//...

var visitor = Fs.NewVisitor("<VISITOR_ID>")
  .IsAuthenticated(true)
  .HasConsented(true)
  .WithContext(new Dictionary<string, object> {
    ["isVIP"] = true,
    ["country"] = "NL",
    ["loginProvider"] = "Google"
    })
  .Build();
  
  await visitor.FetchFlags();

var flag = visitor.GetFlag("displayVipFeature", false);

var flagValue = flag.GetValue();
  • T GetValue([bool userExposed=true]) function

Returns the value from the assigned campaign variation or the Flag default value if the Flag does not exist, or if types are different.

ParameterTypeDefault ValueDescription
userExposedBooleantrueTells Flagship the user have been exposed and have seen this flag. This will increment the visits for the current variation on your campaign reporting.
If needed it is possible to set this param to false and call UserExposed() afterward when the user sees it.

Getting flags campaigns metadata

Metadata property

You may need to send campaign IDs or variation IDs to a third party for reporting and/or analytics purposes. It is possible to retrieve campaigns metadata for a specific Flag.

using Flagship.Main;

//...

var visitor = Fs.NewVisitor("<VISITOR_ID>")
  .IsAuthenticated(true)
  .HasConsented(true)
  .WithContext(new Dictionary<string, object> {
    ["isVIP"] = true,
    ["country"] = "NL",
    ["loginProvider"] = "Google"
    })
  .Build();
  
  await visitor.FetchFlags();

var flag = visitor.GetFlag("displayVipFeature", false);

var campaignMetadata = flag.Metadata;
  • IFlagMetadata Metadata { get; }

Return the campaign information metadata or an empty object if the Flag doesn't exist or if the default value type does not correspond to the Flag type in Flagship.

interface IFlagMetadata 
{
  string CampaignId { get; }
  string CampaignName { get; }
  string VariationGroupId { get; }
  string VariationGroupName { get; }
  string VariationId { get; }
  string VariationName { get; }
  bool IsReference { get; }
  string CampaignType { get; }
  string Slug { get; }
  string ToJson();
}
Key\PropertyTypeDescription
CampaignIdstringCampaign name
CampaignNamestringCampaign name
VariationGroupIdstringVariation group ID
VariationGroupNamestringVariation group name
VariationIdstringThe variation ID assigned to the user
VariationNamestringVariation name
IsReferencebooleanSpecify if its the reference variation
CampaignTypestringcampaign type
Slugstringcampaign slug
ToJsonfunctionReturn a Json of current metada

Report a Flag exposition

UserExposed function

By default when the method GetValue() is called, The SDK considers that the user have seen the effets of your Flag, unless you pass false to GetValue(). In this case you will have to call UserExposed().

There are two ways for exposing a user to a flag:

  1. Pass an UserExposed=true parameter to the GetValue() method.
  2. Use the following UserExposed() method from the Flag instance.
using Flagship.Main;

//...

var visitor = Fs.NewVisitor("<VISITOR_ID>")
  .IsAuthenticated(true)
  .HasConsented(true)
  .WithContext(new Dictionary<string, object> {
    ["isVIP"] = true,
    ["country"] = "NL",
    ["loginProvider"] = "Google"
    })
  .Build();
  
  await visitor.FetchFlags();

//Get flag displayVipFeature
var flag = visitor.GetFlag("displayVipFeature", false);

var flagValue = flag.GetValue(false);

//Report a flag exposition
await flag.UserExposed();
  • Task UserExposed()

Tells Flagship the user have been exposed and have seen this flag. This will increment the visits for the current variation on your campaign reporting. No user exposition will be sent if the Flag doesn't exist or if the default value type do not correspond to the Flag type in Flagship.

Check if a Flag exists

Exists property

This method will return true if a Flag exists in Flagship

  • bool Exists { get; }
using Flagship.Main;

//...

var visitor = Fs.NewVisitor("<VISITOR_ID>")
  .IsAuthenticated(true)
  .HasConsented(true)
  .WithContext(new Dictionary<string, object> {
    ["isVIP"] = true,
    ["country"] = "NL",
    ["loginProvider"] = "Google"
    })
  .Build();
  
  await visitor.FetchFlags();

//Get flag displayVipFeature
var flag = visitor.GetFlag("displayVipFeature", false);

var isDisplayVipFeature = flag.Exists();

Managing visitor consent

The Visitor class provides a method to let you manage visitor consent for data privacy usage. When False, campaign activation and hits will be disabled.

There are 2 ways to set visitor consent :

  1. Set HasConsented to true when creating a new visitor
  2. Use SetConsent method of visitor instance
using Flagship.Main;

//...

var visitor = Fs.NewVisitor("<VISITOR_ID>")
  .IsAuthenticated(true)
  .HasConsented(true) // set hasConsented to true
  .WithContext(new Dictionary<string, object> {
    ["isVIP"] = true,
    ["country"] = "NL",
    ["loginProvider"] = "Google"
    })
  .Build();

// or use setConsent method
visitor.SetConsent(true);

SetConsent function

Set if visitor has consented for protected data usage.

  • void SetConsent(bool hasConsented)
ArgumentTypeDefaultDescription
hasConsentedbooleanrequiredSet visitor consent for private data usage. When false some features will be deactivated.

hasConsented property

Return True if the visitor has consented for private data usage, otherwise return False.

  • bool HasConsented { get; }

Experience Continuity

Dealing with anonymous and logged-in users, Experience continuity allows you to maintain consistency between sessions and devices.

🚧

Make sure that the experience continuity option is enabled on the flagship platform before using those methods.

Authenticate

There are 2 ways to authenticate a visitor:

  1. Set IsAuthenticated to true when creating a new visitor
  2. Use Authenticate of method of Visitor instance

Authenticate anonymous visitor

  • void Authenticate(string visitorId)
ArgumentTypeDefaultDescription
visitorIdstringrequiredid of the new authenticated visitor.

🚧

Because we have changed the visitor data, we have to call the fetchFlags method after calling this one to update the decision from Flagship.

The targeting / Flags could be different for the visitor.

Unauthenticate

This function change authenticated Visitor to anonymous visitor

  • void Unauthenticate()

🚧

Because we have changed the visitor datas, we have to call the fetchFlags method after calling this one to update the decision from Flagship.

The targeting / Flags could be different for the visitor.

Code example

Let's assume basic scenario to understand how things work:

1. Your visitor arrives on your app for the first time

We need to initialize the visitor but as we don't known anything about this visitor, we'll create a random visitor id or let the SDK do it for us. You can also specify some visitor context if necessary.

using Flagship.Main;

//...

var visitor = Fs.NewVisitor()
  .WithContext(new Dictionary<string, object> {
    ["key"] = "value"
    })
  .Build();

visitor.fetchFlags()

Here we don't set visitorId property so the SDK has auto-created an id for our visitor.

Regardless of how it has been set, the actual visitor id will be what we call the anonymous id.

2. Your visitor is signing in.

To tell the SDK about this status modification, you'll have to call the authenticate function which takes the required visitor id as argument.

// Example 
// You fetch the visitor_id from your DB
// let visitorId = db.getUserId();

visitor.Authenticate("VISITOR_ID_ALREADY_KNOWN_BY_FLAGSHIP");

// Since your visitor has changed (is now logged-in)
// You have to check if the proper targeting and flags are set

visitor.fetchFlags()

The visitor is updated as authenticated, keeping the previous variations from campaigns that are still matched and thus gives you same flags as before being logged in.

📘

Keep in mind that if the visitor also has its context changed, you might still have changes on flags as your visitor might target new campaigns.

3. Your visitor decide to sign out.

If you want to keep the same visitor experience, then you should do:

visitor.Unauthenticate();

// Since your visitor has changed (is now logged-out)
// You have to check if the proper targeting and flags are set

visitor.fetchFlags();

Hit Tracking

This section helps you track your users in your application and learn how to build hits in order to feed your reports. For more information about our measurement protocol, read our Universal Collect documentation.

There are five different types of Hits available:

ClassDescription
PageUser has seen a URL.
ScreenUser has seen a screen.
TransactionUser has made a transaction.
ItemItem bought in a transaction.
EventUser has made a specific action.

They must all be built and sent with the following function from the Visitor instance:

await visitor.SendHit(new Screen("abtastylab"));

sendHit function

Send Hit to Flagship servers for reporting.

  • Task SendHit(HitAbstract hit)
ParameterTypeDefaultDescription
hitHitAbstractrequiredHit to send. see Hit

Hit common optional parameters

await visitor.SendHit(new Screen("abtastylab")
{
  UserIp = "127.0.0.1",
  ScreenResolution=  "800X600",
  Locale = "fr",
  SessionNumber = "1234"
  });
ParameterTypeDescription
UserIpstring(Optional) User IP
ScreenResolutionstring(Optional) Screen resolution.
Localestring(Optional) User language
SessionNumberstring(Optional) Session number

Page

This hit should be sent each time a visitor arrives on a new page.

await visitor.SendHit(new Page("https://www.my_domain_com/my_page"));
  • Constructor
ParamsTypeDescription
documentLocationstringValid url.
  • A hit of type Page has this following structure:
PropertyTypeDescription
DocumentLocationstringValid url.

Screen

This hit should be sent each time a visitor arrives on an interface on client side.

await visitor.SendHit(new Screen("home_screen"));
  • Constructor
ParamsTypeDescription
documentLocationstringScreen name.
  • A hit of type Screen has this following structure:
PropertyTypeDescription
DocumentLocationstringScreen name.

Transaction

This hit should be sent when a user complete a Transaction.

await visitor.SendHit(new Transaction("#12345", "affiliation")
{
  Taxes = 19.99,
  Currency = "USD",
  CouponCode = "code",
  ItemCount = 1,
  ShippingMethod = "road",
  ShippingCosts = 5,
  PaymentMethod = "credit_card",
  TotalRevenue = 199.99
  });
  • Constructor
ParamsTypeDescription
transactionIdstringUnique identifier for your transaction.
affiliationstringThe name of the KPI that you will have inside your reporting. Learn more
  • A hit of type Transaction has this following structure:
PropertyTypeDescription
TransactionIdstringUnique identifier for your transaction.
AffiliationstringThe name of the KPI that you will have inside your reporting. Learn more
TotalRevenuedoubleSpecifies the total revenue associated with the transaction. This value should include any shipping and/or tax amounts.
ShippingCostsdoubleThe total shipping cost of your transaction.
ShippingMethodstringThe shipping method for your transaction.
TaxesdoubleSpecifies the total amount of taxes in your transaction.
CurrencystringSpecifies the currency of your transaction. NOTE: This value should be a valid ISO 4217 currency code.
PaymentMethodstringSpecifies the payment method used for your transaction.
ItemCountintSpecifies the number of items in your transaction.
CouponCodestringSpecifies the coupon code used by the customer in your transaction.

Item

This hit is used to link an item with a transaction. It must be sent after the corresponding transaction hit.

await visitor.SendHit(new Item("#12345", "product", "sku123")
{
  Price = 199.99,
  Quantity = 1,
  Category = "test"
 });
  • Constructor
ParamsTypeDescription
transactionIdstringUnique identifier for your transaction.
namestringName of your item.
codestringSpecifies the SKU or item code.
  • A hit of type Item has this following structure:
PropertyTypeDescription
TransactionIdstringUnique identifier for your transaction.
NamestringName of your item.
CodestringSpecifies the SKU or item code.
CategorystringSpecifies the category that the item belongs to.
PricedoubleSpecifies the price for a single item/unit.
QuantityintSpecifies the number of items purchased.

Event

This hit can be used for any event (e.g. Add To Cart click, newsletter subscription).

await visitor.SendHit(new Event(EventCategory.ACTION_TRACKING, "click")
{
  Label = "label",
  Value = 100,
});
  • Constructor
ParamsTypeDescription
CategoryFlagship.Hit.EventCategorySpecifies the category of your event.
ActionstringEvent name that will also serve as the KPI that you will have inside your reporting. Learn more
  • A hit of type Event has this following structure:
PropertyTypeDescription
CategoryFlagship.Hit.EventCategorySpecifies the category of your event.
ActionstringEvent name that will also serve as the KPI that you will have inside your reporting. Learn more
LabelstringAdditional description of your event.
Valueuint(optional) Can be used to evaluate user interactions with individual site objects or content items.
NOTE: this value must be non-negative.

Managing visitor cache

The aims of the cache management is the response to the following problematic:

  • Re-allocation in bucketing mode :

In bucketing mode, the SDK will always keep visitor in variation where he was allocated first, in case of the customer or the dynamic allocation has changed the traffic allocation. Indeed in bucketing mode the assignation is made on local device so changing campaign allocation in the platform would make the visitors see different campaigns.

  • Handle offline mode on client side :

With the cache enabled, the SDK will try to retrieve the latest visitor data (campaign assignations) from the cache, also will save all the failed hits and UserExposed in order to resend them later.

To use the cache manager the intefaces IVisitorCacheImplementation and IHitCacheImplementation must be implemented through visitorCacheImplementation and hitCacheImplementation properties of configuration.

Visitor Cache

The visitor cache is used to store the visitor data in a database through the Flagship.Cache.IVisitorCacheImplementation interface.

interface IVisitorCacheImplementation
{
  TimeSpan? LookupTimeout { get; set; }
  Task CacheVisitor(string visitorId, JObject data);
  Task<JObject> LookupVisitor(string visitorId);
  Task FlushVisitor(string visitorId);
}

CacheVisitor function

This method is called when the SDK needs to cache visitor information in your database.

  • Task CacheVisitor(string visitorId, JObject data)

It has 2 arguments :

ArgumentTypeDescription
visitorIdstringvisitor ID
DataNewtonsoft.Json.Linq.JObjectvisitor data. The JSON object has the follows shape see.

LookupVisitor function

This method is called when the SDK needs to get the visitor information corresponding to visitor ID from your database.

It has to return an JSON object which follows this shape see.

  • Task<JObject> LookupVisitor(string visitorId)

It has one argument :

ArgumentTypeDescription
visitorIdstringvisitor ID

FlushVisitor function

This method is called when the SDK needs to erase the visitor information corresponding to visitor ID in your database.

It will be called every time setConsent get false.

  • Task FlushVisitor(string visitorId)

It has one argument :

ArgumentTypeDescription
visitorIdstringvisitor ID

📘

  • FlushVisitor method will be called every time SetConsent get false.
Visitor Cache format
{
  "Version": 1,
  "Data": {
      "VisitorId": "visitor_1",
      "AnonymousId": null,
      "Consent": true,
      "Context": {
        "qa_getflag": true,
        "fs_client": ".NET",
        "fs_version": "V3"
      },
    "AssignmentsHistory": {
      "xxxxxxxxxxxxxxxxxxxx": "xxxxxxxxxxxxxxxxxxxx",
      "yyyyyyyyyyyyyyyyyyyy": "yyyyyyyyyyyyyyyyyyyy"
    },
    "Campaigns": [
      {
        "CampaignId": "xxxxxxxxxxxxxxxxxxxx",
        "VariationGroupId": "xxxxxxxxxxxxxxxxxxxx",
        "VariationId": "xxxxxxxxxxxxxxxxxxxx",
        "IsReference": false,
        "Type": 2,
        "Activated": false,
        "Slug": xxxxxxxxxxxxxxx,
        "Flags": {
          "key": "value"
        }
      },
      {
        "CampaignId": "xxxxxxxxxxxxxxxxxxxx",
        "VariationGroupId": "xxxxxxxxxxxxxxxxxxxx",
        "VariationId": "xxxxxxxxxxxxxxxxxxxx",
        "IsReference": false,
        "Type": "",
        "Activated": false,
        "Slug": xxxxxxxxxxxxxxx,
        "Flags": {
          "myAwesomeFeature": 20
        }
      }
    ]
  }
}

Hit Cache

The hit cache is used to store the failed hits and UserExposed in your database through the Flagship.Cache.IHitCacheImplementation interface to handle it.

interface IHitCacheImplementation
{
  TimeSpan? LookupTimeout { get; set; }
  Task CacheHit(string visitorId, JObject data);
  Task<JArray> LookupHits(string visitorId);
  Task FlushHits(string visitorId);
}

CacheHit function

This method will be called to cache visitor hits when a hit has failed to be sent if there is no internet, there has been a timeout or if the request responded with something > 2XX.

  • Task CacheHit(string visitorId, JObject data)

It has 2 arguments :

ArgumentTypeDescription
visitorIdstringvisitor ID
dataNewtonsoft.Json.Linq.JObjecthit data. The JSON object has the follows shape see.

LookupHits function

This method will be called to load hits corresponding to visitor ID from your database and will try to send them again in the background.

It has to return an JSON array which follows this shape see.

  • Task<JArray> LookupHits(string visitorId)

It has one argument :

ArgumentTypeDescription
visitorIdstringvisitor ID

FlushHits function

This method will be called to erase the visitor hits cache corresponding to visitor ID from your database.

NOTE: It will be called every time SetConsent get false.

  • Task FlushHits(string visitorId)

It has one argument :

ArgumentTypeDescription
visitorIdstringvisitor ID
Hit Cache format
[
  {
      "Version": 1,
      "Data": {
        "VisitorId": "visitor_1",
        "AnonymousId": null,
        "Type": 4,
        "Time": "2022-03-21T13:51:48.4696354+01:00",
        "Content": {
          "Category": 1,
          "Action": "Event 2",
          "Label": null,
          "Value": null,
          "VisitorId": "visitor_1",
          "Type": 4,
          "DS": "APP",
          "AnonymousId": null,
          "UserIp": null,
          "ScreenResolution": null,
          "Locale": null,
          "SessionNumber": null
        }
      }
]

📘

  • FlushHits method will be called every time SetConsent get false.
  • After LookupHits has returned the visitor hits information corresponding to visitor ID, this data must be deleted from persistent storage.
  • Hits older than 4H will be ignored during the resending process.

API reference

Fs class

Visitor class

Flag class

Appendix

Predefined user context keys :

The Flagship SDK contains predefined user context keys.

The keys marked as Yes in the Auto-set by SDK column will be automatically set, while the ones marked as No need to be set by customer.

You can overwrite these keys at any time. The keys-value pairs will be sent to the server in the user context and can be edited in the Persona section of the Flagship platform.

Note: All predefined contexts can be found as static property in Flagship.Enums.PredefinedContext class

SDK constant NameDescriptionContext variable nameTypeAuto-set by SDKExample
DEVICE_LOCALELanguage of the devicesdk_deviceLanguageStringNofra
DEVICE_TYPEType of the devicesdk_deviceTypeDeviceTypeNoMobile
DEVICE_MODELModel of the devicesdk_deviceModelStringNosamsung E1200
LOCATION_CITYCity geolocationsdk_cityStringNotoulouse
LOCATION_REGIONRegion geolocationsdk_regionStringNooccitanie
LOCATION_COUNTRYCountry geolocationsdk_countryStringNoFrance
LOCATION_LATCurrent Latitudesdk_latDoubleNo43.623647
LOCATION_LONGCurrent Longitudesdk_longDoubleNo1.445397
IPIP of the devicesdk_ipStringNo127.0.0.1
OS_NAMEName of the OSsdk_osNameStringYESubuntu / centos
OS_VERSION_NAMEVersion name of the OSsdk_osVersionNameStringNo9.0.0
OS_VERSION_CODEVersion code of the OSsdk_osVersionCodeNumberNo24
CARRIER_NAMEName of the carrier or mobile virtual network operatorsdk_carrierNameStringNofree
INTERNET_CONNECTIONWhat is the internet connectionsdk_internetConnectionStringNo5g
APP_VERSION_NAMEVersion name of the appsdk_versionNameStringNo1.1.2-beta
APP_VERSION_CODEVersion code of the appsdk_versionCodeNumberNo40
INTERFACE_NAMEName of the interfacesdk_interfaceNameStringNoProductPage
FLAGSHIP_CLIENTFlagship SDK client (Reserved)fs_clientStringYesTS
FLAGSHIP_VERSIONVersion of the Flagship SDK (Reserved)fs_versionStringYes2.0.0
FLAGSHIP_VISITORCurrent visitor id (Reserved)fs_usersStringYesvisitor_id

📘

To overwrite the keys, use the updateContext method