Skip to main content
1 of 3
Mark Lowe
  • 1.1k
  • 6
  • 14

Tracker.Current.Session.IdentifyAs() will only merge contacts, if the current contact is not a known contact yet: Contact.IdentificationLevel != ContactIdentificationLevel.Known

If the current contact already is known, IdentifyAs() will not merge it with an existing contact that already has the identifier.

So what we ended up doing was this:

public bool IdentifyAs(string source, string identifier)
{
    if (Tracker.Current == null)
    {
        return false;
    }

    // Contact already has the identifier
    if (Tracker.Current.Session.Contact.Identifiers.Any(x => x.Source == source && x.Identifier == identifier))
    {
        return true;
    }

    var manager = Sitecore.Configuration.Factory.CreateObject("tracking/contactManager", true) as Sitecore.Analytics.Tracking.ContactManager;

    if (manager == null)
    {
        Log.Error("XConnectContactRepository: Unable to instantiate ContactManager", this);
        return false;
    }

    // Use default identifyAs for unknown contacts
    if (Tracker.Current.Contact.IdentificationLevel != ContactIdentificationLevel.Known)
    {
        Tracker.Current.Session.IdentifyAs(source, identifier);

        var contactId = Tracker.Current.Contact.ContactId;
        manager.RemoveFromSession(contactId);
        Tracker.Current.Session.Contact = manager.LoadContact(contactId);
        return true;
    }

    var existingContact = manager.LoadContact(source, identifier);

    // No other contact has this identifier yet: just set it
    if (existingContact == null)
    {
        var contactId = Tracker.Current.Session.Contact.ContactId;

        Log.Info($"Add identifier for contact '{contactId}'. {source} > {identifier}", this);

        manager.AddIdentifier(contactId, new ContactIdentifier(source, identifier, ContactIdentificationLevel.Known));
        manager.RemoveFromSession(contactId);
        Tracker.Current.Session.Contact = manager.LoadContact(contactId);

        return true;
    }

    // Other contact with identifier exists: Merge explicitly
    var currentContact = Tracker.Current.Session.Contact;
    var hasBehaviourProfiles = currentContact.BehaviorProfiles.Count != 0;

    Log.Info($"Merge contacts '{currentContact.ContactId}' into {existingContact.ContactId}. reason: {source} > {identifier}", this);

    Tracker.Current.Session.Contact = manager.MergeContacts(existingContact, currentContact);

    manager.RemoveFromSession(Tracker.Current.Contact.ContactId);

    Tracker.Current.Session.Interaction.ContactId = Tracker.Current.Session.Contact.ContactId;
    Tracker.Current.Session.Interaction.ContactVisitIndex = Tracker.Current.Session.Contact.System.VisitCount;
    
    if (hasBehaviourProfiles || Tracker.Current.Interaction.Profiles.GetProfileNames().Length == 0)
    {
        InitializeInteractionProfilePipeline.Run(new InitializeInteractionProfileArgs(Tracker.Current.Session));
    }

    return true;
}

We can now safely set multiple identifiers through our IdentifyAs():

IdentifyAs("USERID_SOURCE", "U1542658"); 
IdentifyAs("EMAIL_SOURCE", "[email protected]");
Mark Lowe
  • 1.1k
  • 6
  • 14