Sailthru Specific Functionality

A breakdown of the Sailthru specific functionality in the EngageBySailthru class

If you are a Sailthru customer there are some additional methods you can use to set details about a device or profile. This functionality used to be provided in the main SailthruMobile class but has now been moved out to the EngageBySailthru class as it is only available for this product.

Creating an instance

When creating an instance of the EngageBySailthru class you must ensure that you have already called startEngine or an error will be thrown. If you are not a Sailthru customer this class will also return an error, as this functionality is only available on the Sailthru product.

NSError *error;
EngageBySailthru *engageBySailthru = [[EngageBySailthru alloc] initWithError:&error];
if (error) {
  // Handle error
}
do {
 let engageBySailthru = try EngageBySailthru()
 ...
} catch {
  // Handle error
}
try {
  EngageBySailthru engageBySailthru = new EngageBySailthru();
  ...
} catch(IllegalStateException e) {
  // Called before start engine
} catch(IllegalArgumentException e) {
  // Functionality not available
}
try {
  val engageBySailthru = EngageBySailthru()
  ...
} catch (e: IllegalStateException) {
  // Called before start engine
} catch (e: IllegalArgumentException) {
  // Functionality not available
}

In the wrapper SDKs (React Native and Unity) these errors will be returned when attempting to call methods on the EngageBySailthru class.


The strength of Marigold's targeting and segmentation relies on knowing the correct information about your users. The more information we know about a user, the better you can target them when you send messages.

When a user installs an app, we collect a few attributes automatically. These attributes are helpful for targeting and segmenting your users.

Automatically Tracked Attributes

  • App Version
  • Language
  • Time Zone
  • Badge Number (iOS only)
  • Device ID
  • Device Make & Model
  • Operating System & Version
  • Marigold SDK version
  • Location based on IP Address
  • Notifications Allowed
  • Platform

πŸ“˜

Attributes tracked automatically are refreshed at every app load.

Beyond the automatically tracked attributes, Marigold also lets you store custom information about a user for further segmenting and targeting. This feature is called User Attributes.

Setting a User ID

If your app has a login, you can set a unique User ID with Marigold. This allows you to associate multiple devices to a single user when targeting via the API. You may also want to collect the user's email as well.

// setting a User ID after login
[[EngageBySailthru new] setUserId:@"user_id_1234" withResponse:^(NSError *error) {
    NSLog(@"Error setting user id – %@", error.localizedDescription);
}];

// clearing a User ID after logout
[[EngageBySailthru new] setUserId:nil withResponse:^(NSError *error) {
    
}];
// setting a User ID after login
EngageBySailthru().setUserId("user_id_1234") { error in
    print("setUserID returned with possible error: \(error)")
}

// clearing a User ID after logout
EngageBySailthru().setUserId(nil) { error in
    print("setUserID returned with possible error: \(error)")
}
// setting a User ID after login
new EngageBySailthru().setUserId("user_id_1234", new Marigold.MarigoldHandler<Void> (){

    @Override
    public void onSuccess (Void value){
        //Do Something
    }

    @Override
    public void onFailure (Error error){
        //Do Something
    }
});


// clearing a User ID after logout
new EngageBySailthru().setUserId(null, new Marigold.MarigoldHandler<Void> (){

    @Override
    public void onSuccess (Void value){
        //Do Something
    }

    @Override
    public void onFailure (Error error){
        //Do Something
    }
});
// setting a User ID after login
EngageBySailthru().setUserId("user_id_1234", object : MarigoldHandler<Void?> {
  override fun onSuccess(value: Void?) {
    //Do Something
  }

  override fun onFailure(error: Error?) {
    //Do Something
  }
})

// clearing a User ID after logout
EngageBySailthru().setUserId(null, object : MarigoldHandler<Void?> {
  override fun onSuccess(value: Void?) {
    //Do Something
  }

  override fun onFailure(error: Error?) {
    //Do Something
  }
})
// setting a User ID after login
SailthruMobile.setUserId("user_id_1234");

// clearing a User ID after logout
SailthruMobile.setUserId("");
// setting a User ID after login
new EngageBySailthru().SetUserId("user_id_1234");

// clearing a User ID after logout
new EngageBySailthru().SetUserId(null);

πŸ“˜

Setting a User ID is optional, but it is strongly recommended. It is a prerequisite to use:

Without User ID you will be able to set attributes and events only at the device level.

Setting a User Email

Setting a user email allows to link a device to an identifier user profile in Marigold, matching the email you provide with an existing Email ID. This is a required step to leverage omnichannel personalization using interests and other data points from the Marigold user profile.

We recommend to collect both User ID and email.

// setting a User Email after login
[[EngageBySailthru new] setUserEmail:@"[email protected]" withResponse:^(NSError *error) {
    NSLog(@"Error setting user email – %@", error.localizedDescription);
}];

// clearing a User Email after logout
[[EngageBySailthru new] setUserEmail:nil withResponse:^(NSError *error) {
    NSLog(@"Error setting user email – %@", error.localizedDescription);
}];
// setting a User Email after login
EngageBySailthru().setUserEmail("[email protected]") { error in
    print("setUserEmail returned with possible error: \(error)")
}

// clearing a User Email after logout
EngageBySailthru().setUserEmail(nil) { error in
    print("setUserEmail returned with possible error: \(error)")
}
// setting a User Email after login
new EngageBySailthru().setUserEmail("[email protected]", new Marigold.MarigoldHandler<Void> (){

    @Override
    public void onSuccess (Void value){
        //Do Something
    }

    @Override
    public void onFailure (Error error){
        //Do Something
    }
});


// clearing a User Email after logout
new EngageBySailthru().setUserEmail(null, new Marigold.MarigoldHandler<Void> (){

    @Override
    public void onSuccess (Void value){
        //Do Something
    }

    @Override
    public void onFailure (Error error){
        //Do Something
    }
});
// setting a User Email after login
EngageBySailthru().setUserEmail("[email protected]", object : MarigoldHandler<Void?> {
  override fun onSuccess(value: Void?) {
    //Do Something
  }

  override fun onFailure(error: Error?) {
    //Do Something
  }
})


// clearing a User Email after logout
EngageBySailthru().setUserEmail(null, object : MarigoldHandler<Void?> {
  override fun onSuccess(value: Void?) {
    //Do Something
  }

  override fun onFailure(error: Error?) {
    //Do Something
  }
})
// setting a User Email after login
SailthruMobile.setUserEmail("[email protected]");

// clearing a User Email after logout
SailthruMobile.setUserEmail("");
// setting a User Email after login
new EngageBySailthru().SetUserEmail("[email protected]");

// clearing a User Email after logout
new EngageBySailthru().SetUserEmail(null);

User Attributes (deprecated - use Profile Vars instead)

User Attributes provide a powerful & flexible way for developers to store extra metadata for the purposes of grouping, segmenting and targeting users at a later stage.

Each User/Device can have multiple attributes. User Attributes are unique to a device and app, and persist between app opens. They are set on the SDK side and saved back to the Marigold platform with the appropriate SDK methods.

Each User Attribute has a name, a type and a value.

For example;

  • first_name (String)
  • lifetime_value (Float)
  • number_of_items_purchased (Integer)
  • is_premium_subscriber (Boolean)

The following attribute datatypes are supported;

  • Integer (32 bit)
  • Float
  • Date
  • String
  • Boolean
  • Array (of Integer, Floats, Dates and Strings)

To set some User attributes from the SDK

// Construct the object
MARAttributes *attributes  = [[MARAttributes alloc] init];

// Set one or more attributes
[attributes setString:@"Handbags" forKey:@"last_visited_category"];
[attributes setStrings:@[@"world", @"sports"] forKey:@"subscriptions"];
[attributes setFloat:104.87 forKey:@"customer_ltv"];
[attributes setInteger:3 forKey:@"products_in_cart"];
[attributes setFloats:@[@(36.99), @(42.3)] forKey:@"cart_items_unit_price"];
[attributes setIntegers:@[@(2), @(1)] forKey:@"cart_item_quantities"];
[attributes setBool:YES forKey:@"user_did_use_facebook_login"];
[attributes setDates:@[[NSDate date]] forKey:@"checkout_started"];

// Optional: choose if you want to add new attributes to the existing (update), or if you want to overwrite the current attributes with the new payload (replace). By default, we update.
[attributes setAttributesMergeRule:MARAttributesMergeRuleUpdate];

EngageBySailthru *engageBySailthru = [EngageBySailthru new];

// Send to Sailthru Mobile
[engageBySailthru setAttributes:attributes withResponse:^(NSError * _Nullable error) {
  if (error) {
    NSLog(@"Error - %@", [error debugDescription]);
  }
}];

// Remove an attribute
[engageBySailthru removeAttributeWithKey:@"products_in_cart" withResponse:nil];

// Remove all attributes
[engageBySailthru clearAttributesWithResponse:^(NSError * _Nullable error) {
  if (error) {
    NSLog(@"Error - %@", [error debugDescription]);
  }
}];
// Construct the object
let attributes = MARAttributes()

// Set one or more attributes
attributes.setString("Handbags", forKey: "last_visited_category")
attributes.setStrings(["world", "sports"], forKey: "subscriptions")
attributes.setFloat(104.87, forKey: "customer_ltv")
attributes.setInteger(3, forKey: "products_in_cart")
attributes.setFloats([36.99, 42.3], forKey: "cart_items_unit_price")
attributes.setIntegers([2, 1], forKey: "cart_item_quantities")
attributes.setBool(true, forKey: "user_did_use_facebook_login")
attributes.setDates(NSDate(), forKey: "checkout_started")

// Optional: choose if you want to add new attributes to the existing (update), or if you want to overwrite the current attributes with the new payload (replace). By default, we update.
attributes.setAttributesMergeRule(.Update)

let engageBySailthru = EngageBySailthru()

// Send to Sailthru Mobile
engageBySailthru.setAttributes(attributes) { error in
  print("setAttributes returned with possible error: \(error)")
}

// Remove an attribute
engageBySailthru.removeAttributeWithKey("products_in_cart", nil)

// Remove all attributes
engageBySailthru.clearAttributes() { error in
  print("clearAttributes returned with possible error: \(error)")
}
// Construct the object
AttributeMap attributes = new AttributeMap();

// Set one or more attributes
attributes.putString("last_visited_category", "Handbags");

ArrayList<String> subscriptions = new ArrayList<>(Arrays.asList("world", "sports"));
attributes.putStringArray("subscriptions", subscriptions);

attributes.putFloat("customer_ltv", 104.87f);

ArrayList<Float> cartItemsUnitPrice = new ArrayList<>(Arrays.asList(36.99f, 42.3f));
attributes.putFloatArray("cart_items_unit_price", cartItemsUnitPrice);

attributes.putInt("products_in_cart", 3);

ArrayList<Integer> cartItemQuantities = new ArrayList<>(Arrays.asList(2, 1));
attributes.putIntArray("cart_item_quantities", cartItemQuantities);

attributes.putBoolean("user_did_user_facebook_login", true);
attributes.putDate("checkout_started", new Date());

// Optional: choose if you want to add new attributes to the existing (update), or if you want to overwrite the current attributes with the new payload (replace). By default, we update.
attributes.setMergeRules(AttributeMap.RULE_UPDATE);

EngageBySailthru engageBySailthru = new EngageBySailthru();

// Send to Marigold
engageBySailthru.setAttributes(attributes, new EngageBySailthru.AttributesHandler() {
  @Override
  public void onSuccess() {
    // Handle success here
  }

  @Override
  public void onFailure(Error error) {
    // Handle failure here
    Log.d("YOUR_LOG_TAG", "setAttributes returned with possible error: " + error.getLocalizedMessage());
  }
});

// Remove an attribute
engageBySailthru.removeAttribute("products_in_cart");

// Remove all attributes
engageBySailthru.clearAttributes(new Marigold.MarigoldHandler<>() {
  @Override
  public void onSuccess(Void value) {
		// Handle success here
  }

  @Override
  public void onFailure(@NonNull Error error) {
    // Handle failure here
		Log.d("YOUR_LOG_TAG", "clearAttributes returned with possible error: " + error.getLocalizedMessage());
  }
});
// Construct the object
val attributes = AttributeMap()

// Set one or more attributes
attributes.putString("last_visited_category", "Handbags")

val subscriptions: ArrayList<String> = ArrayList(Arrays.asList("world", "sports"))
attributes.putStringArray("subscriptions", subscriptions)

attributes.putFloat("customer_ltv", 104.87f)

val cartItemsUnitPrice: ArrayList<Float> = ArrayList(Arrays.asList(36.99f, 42.3f))
attributes.putFloatArray("cart_items_unit_price", cartItemsUnitPrice)

attributes.putInt("products_in_cart", 3)

val cartItemQuantities: ArrayList<Int> = ArrayList(Arrays.asList(2, 1))
attributes.putIntArray("cart_item_quantities", cartItemQuantities)

attributes.putBoolean("user_did_user_facebook_login", true)
attributes.putDate("checkout_started", Date())

// Optional: choose if you want to add new attributes to the existing (update), or if you want to overwrite the current attributes with the new payload (replace). By default, we update.
attributes.setMergeRules(AttributeMap.RULE_UPDATE)

val engageBySailthru = EngageBySailthru()

// Send to Marigold
engageBySailthru.setAttributes(attributes, object : EngageBySailthru.AttributesHandler {
  override fun onSuccess() {
    // Handle success here
  }

  override fun onFailure(error: Error?) {
    // Handle failure here
    Log.d("YOUR_LOG_TAG", "setAttributes returned with possible error: " + error!!.localizedMessage)
  }
})

// Remove an attribute
engageBySailthru.removeAttribute("products_in_cart")

// Remove all attributes
engageBySailthru.clearAttributes(object : Marigold.MarigoldHandler<Void?> {
  override fun onSuccess(value: Void?) {
    // Handle success here
  }

  override fun onFailure(error: Error) {
    // Handle failure here
    Log.d("YOUR_LOG_TAG", "clearAttributes returned with possible error: " + error.localizedMessage)
  }
})
// Construct the object
var attrMap = new SailthruMobile.AttributeMap();

// Set one or more attributes
attrMap.setString("string_key", "This is the string value");
attrMap.setStringArray("strings_key", ["This is first value", "This is the second value"]);
attrMap.setDate("date_key", new Date());
attrMap.setDateArray("dates_key", [new Date(), new Date(), new Date()]);
attrMap.setFloat("float_key", 3.141);
attrMap.setFloatArray("floats_key", [1.1, 2.2, 3.3, 4.4]);
attrMap.setInteger("integer_key", 3);
attrMap.setIntegerArray("integers_key", [1, 2, 3, 4]);
attrMap.setBoolean("boolean_key", true);

// Optional: choose if you want to add new attributes to the existing (update), or if you want to overwrite the current attributes with the new payload (replace). By default, we update.
attrMap.setMergeRule(attrMap.MergeRules.Update);

// Send to Sailthru Mobile
SailthruMobile.setAttributes(attrMap).catch(e => {
	// Handle error
});

Custom Attribute Limits

There are limits in place on the maximum number of custom attributes allowed as well as the length (size) of strings and arrays.

  • A maximum of 50 custom attributes is allowed per device. If you exceed this amount any new attributes being set will be discarded.
  • String values that have more than 255 characters will be truncated.
  • Arrays with more than 50 elements will be truncated.

Key name restrictions

  • Only letters, numbers, underscore and dashes are valid characters.
  • Leading spaces will be removed.
  • Invalid characters other than spaces and dots will be removed.
  • Spaces and dots will be replaced for underscores.
  • Keys will be truncated to a maximum of 255 characters.
  • Invalid keys will simply be discarded and no error will be returned.

πŸ“˜

Custom attributes are refreshed in real time.

Profile Vars

Profile Vars can be set and retrieved through the SDK. This makes maintaining state between your email/on-site campaigns and your mobile marketing easy. Note that the use of this feature requires that your app be linked to Sailthru Email/On-Site.

Vars should be set in a JSON object format:

// Setup profile vars object
NSDictionary *profileVars = @{
    @"string_key" : @"string_value",
    @"object_key" : @{},
    @"boolean_key" : @YES
};
    
// Set profile vars
[[EngageBySailthru new] setProfileVars:profileVars withResponse:^(NSError * _Nullable error) {
    // Check if error is non-nil for result
}];
// Setup profile vars object
let profileVars : [String : Any] = [ 
  	"string_key" : "string_value",
		"object_key" : [],
		"boolean_key" : true 
]

// Set profile vars
EngageBySailthru().setProfileVars(profileVars) { (error : Error?) in
		// Check if error is non-nil for result
}
// Setup profile vars object
JSONObject profileVars = new JSONObject();
profileVars.put("string_key", "string_value");
profileVars.put("object_key", new JSONObject());
profileVars.put("boolean_key", true);

// Set profile vars
new EngageBySailthru().setProfileVars(profileVars, new Marigold.MarigoldHandler<Void>() {
    @Override
    public void onSuccess(Void value) {
        // Handle success
    }

    @Override
    public void onFailure(Error error) {
        // Handle error
    }
});
// Setup profile vars object
val profileVars = JSONObject()
profileVars.put("string_key", "string_value")
profileVars.put("object_key", JSONObject())
profileVars.put("boolean_key", true)

// Set profile vars
EngageBySailthru().setProfileVars(profileVars, object : MarigoldHandler<Void?> {
  override fun onSuccess(value: Void?) {
    // Handle success
  }

  override fun onFailure(error: Error?) {
    // Handle error
  }
})
// Setup profile vars object
var profileVars = {
	"string_key" : "string_value",
	"object_key" : {},
	"boolean_key": true
};

// Set profile vars
SailthruMobile.setProfileVars(profileVars).then(result => {
  // Handle success
}).catch(e => {
  // Handle error
});
JSONClass jsonObject = new JSONClass();
jsonObject["string_key"] = "string_value";
jsonObject["object_key"] = new JSONClass();
jsonObject["array_key"] = new JSONArray();
jsonObject["int_key"].AsInt = 1234;
jsonObject["bool_key"].AsBool = false;

new EngageBySailthru().SetProfileVars(jsonObject);

When retrieving vars they will be returned in the same JSON object format:

[[EngageBySailthru new] getProfileVarsWithResponse:^(NSDictionary<NSString *,id> * _Nullable profileVars, NSError * _Nullable error) {
    // Handle profileVars object or error
}];
EngageBySailthru().getProfileVars { (profileVars : [String : Any]?, error : Error?) in
		// Handle profileVars object or error
}
new EngageBySailthru.getProfileVars(new Marigold.MarigoldHandler<JSONObject>() {
    @Override
    public void onSuccess(JSONObject profileVars) {
				// Handle profileVars object
    }

    @Override
    public void onFailure(Error error) {
        // Handle error
    }
});
EngageBySailthru().getProfileVars(object : MarigoldHandler<JSONObject?> {
  override fun onSuccess(profileVars: JSONObject?) {
    // Handle profileVars object
  }

  override fun onFailure(error: Error?) {
    // Handle error
  }
})
SailthruMobile.getProfileVars().then(profileVars => {
	// Handle profileVars object
}).catch(e => {
	// Handle error
});
EngageBySailthru.OnProfileVarsReceivedEvent += (object sender, ProfileVarsReceivedEventArgs args) => {
	// Handle profileVars object
};

new EngageBySailthru().GetProfileVars();

Variable names

  • Are case sensitive. For example, if you create a variable named β€œSurvey_Score” it will not be accessible using all lowercase letters.
  • May not start with a number or be only numbers. For example, don’t upload phone numbers using var name β€œ#”.
  • May not contain special characters (such as %, -, or $). These characters will be scrubbed from variable names upon import.
  • May not contain spaces. If the variable name is submitted with a space, it will be converted to an underscore.

Date and Time Formats

  • In order to maintain strict JSON compatibility, Marigold vars do not support a native date or time type. Instead, if you use specific naming and formatting conventions, Marigold will treat these values as dates and times throughout our system, for example, when performing queries in Audience Builder.

For more information on Vars, see the User Variables docs

Custom Events

Custom Events provide a simple event tracking solution for measuring actions in your app. Events can be logged to track actions that users take, such as screen views, or social network shares. Unlike user attributes, events occur over time and graphs of the events can be seen within the analytics section of the Marigold dashboard.

A record is kept of the count and the last occurrence of an event for each user, so you can target and segment based on;

  • Whether a user has performed this event or not
  • When they last performed this event
  • How often they have performed this event

These events are also passed through to the Lifecycle Optimiser where they can be used to build powerful workflows for both mobile and email.

To log a Custom Event

EngageBySailthru *engageBySailthru = [EngageBySailthru new];
[engageBySailthru logEvent:@"Checkout started"];
[engageBySailthru logEvent:@"Article shared"];

// with Vars
NSDictionary* eventVars = @{ @"itemCount" : @3 };
[engageBySailthru logEvent:@"Checkout started" withVars:eventVars];
let engageBySailthru = EngageBySailthru()
engageBySailthru.logEvent("Checkout started")
engageBySailthru.logEvent("Article shared")

// with Vars
let eventVars = [ "itemCount" : 3 ]
engageBySailthru.logEvent("Checkout started", withVars: eventVars)
EngageBySailthru engageBySailthru = new EngageBySailthru();
engageBySailthru.logEvent("Checkout started");
engageBySailthru.logEvent("Article shared");

// with Vars
JSONObject eventVars = new JSONObject().put("itemCount", 3);
engageBySailthru.logEvent("Checkout started", eventVars);
val engageBySailthru = EngageBySailthru()
engageBySailthru.logEvent("Checkout started")
engageBySailthru.logEvent("Article shared")

// with Vars
val eventVars = JSONObject().put("itemCount", 3)
engageBySailthru.logEvent("Checkout started", eventVars)
SailthruMobile.logEvent("Checkout started");
SailthruMobile.logEvent("Article shared");

// with Vars
var eventVars = {
  "itemCount" : 3
};
SailthruMobile.logEvent("Checkout started", eventVars);
EngageBySailthru engageBySailthru = new EngageBySailthru();
engageBySailthru.LogEvent("Checkout started");
engageBySailthru.LogEvent("Article shared");

// with Vars
JSONClass eventVars = new JSONClass()
eventVars["itemCount"].AsInt = 3;
engageBySailthru.LogEvent("Checkout started", eventVars);

πŸ“˜

NOTE

The maximum amount of unique events which can be registered per device is limited to 50. Events are updated in batch, close to real-time, every few seconds.

Auto-Analytics Tracking

On iOS

The Marigold iOS SDK automatically integrates with other analytics providers to capture some analytics. At the moment we capture only event data. This means that if you use the frameworks below to log events, they'll also be logged to Marigold as an event also.

The providers we integrate with are:

  • Google Analytics
  • Mixpanel
  • Adobe Analytics (Formerly Omniture)
  • Localytics
  • Amplitutde
  • Flurry

Auto-Analytics is opt-in. To enable Auto-Analytics, use the enableAutoAnalytics method.

//Call as early as possible, perhaps straight after startEngine

[[EngageBySailthru new] enableAutoAnalytics:@[MARAutoAnalyticsSourceGoogleAnalytics, MARAutoAnalyticsSourceAdobe, MARAutoAnalyticsSourceMixpanel, MARAutoAnalyticsSourceLocalytics]];
//Call as early as possible, perhaps straight after startEngine

EngageBySailthru().enableAutoAnalytics([MARAutoAnalyticsSourceGoogleAnalytics, MARAutoAnalyticsSourceAdobe, MARAutoAnalyticsSourceMixpanel, MARAutoAnalyticsSourceLocalytics])

Methods captured

Google Analytics
  • + (id)createEventWithCategory:(NSString *)category action:(NSString *)action label:(NSString *)label value:(NSString *)value

We discard category, label and value, and log a Marigold event with the action as the name.

Adobe Analytics
  • + (void)trackAction:(NSString *)action data:(id)data
    We discard data and log a Marigold event with the action as the name.
Mixpanel
  • - (void)track:(NSString *)event properties:(NSString *)properties
    We discard properties and log a Marigold event with the event as the name.
Localytics
  • - (void)tagEvent:(NSString *)eventName attributes:(NSDictionary *)attributes customerValueIncrease:(NSNumber *)customerValueIncrease;

We discard attributes and customerValueIncrease, and log a Marigold event with the eventName as the name.

Flurry
  • + (NSInteger)logEvent:(NSString *)eventName withParameters:(NSDictionary *)parameters timed:(BOOL)timed
  • + (NSInteger)logEvent:(NSString *)eventName timed:(BOOL)timed

We discard eventName, parameters and timed, and log a Marigold event with the eventName as the name.

Amplitude
  • - (void)logEvent:(NSString *)eventType withEventProperties:(NSDictionary *)eventProperties withApiProperties:(NSDictionary *)apiProperties withUserProperties:(NSDictionary *)userProperties withGroups:(NSDictionary *)groups withTimestamp:(NSNumber *)timestamp outOfSession:(BOOL)outOfSession (Other event methods call this method)

We discard most parameters, and log a Marigold event with the eventType as the name.

On Android

For Auto-Analytics Tracking on Android, the logEvent() call now takes a source parameter for when forwarding events from other analytics frameworks to Marigold. This allows you to target based on events you already track.

new EngageBySailthru().logEvent("source", "myEvent");

A selection of pre-written integrations have been provided, allowing you to just include one file, replace your event logging calls and then turn on or off the frameworks you want to use by commenting them out in the source file provided.

πŸ“˜

User Attributes or Custom Events?

User Attributes don't record events that happen over time, and don't appear in graphs in the platform. They are simply metadata for a user. For recording events that happen over time, so you can target users by behavior, you should use our custom events feature.