Walkthrough: Creating a contact and an interaction

Current version: 10.0

This walkthrough is part one of the Extending the xConnect collection model walkthrough series and describes how to create a contact and an interactions.

Before you can complete this walkthrough, you must install the full Sitecore Experience Platform, including xConnect and xDB.

This walkthrough describes how to:

  • Create the Sitecore.Documentation solution and console app

  • Establish contact between the Sitecore.Documentation app and your XConnect instance

  • Create a contact with a known identifier

  • Create an interaction with a single event

Create the Sitecore.Documentation solution and console app

To create the Sitecore.Documentation solution and console app:

  1. In Visual Studio with administrator privileges, create a new solution and console app for .NET Framework project called Sitecore.Documentation:

    The Configure your new project dialogue box in Visual Studio.
  2. In Solution Explorer, right-click References and click Add Reference.

  3. In the Reference Manager window, click Browse and add the following references from your <xConnect instance>\bin\ folder:

    • Sitecore.Framework.Conditions.dll

    • Sitecore.XConnect.Core

    • Sitecore.XConnect.dll

    • Sitecore.XConnect.Client.dll

    • Sitecore.XConnect.Collection.Model.dll

    • Sitecore.XConnect.Search.dll

    • Sitecore.Xdb.Common.Web.dll

  4. In Solution Explorer, right-click References and click Manage NuGet Packages.

  5. In the NuGet window, click Browse and add the following references:

    • Microsoft.AspNet.WebApi.Client - version: 5.2.6

    • Microsoft.Extensions.Configuration.Abstractions - version: 2.1.1

    • System.Interactive.Async.Providers version: 3.1.1

    • Newtonsoft.Json - version: 11.0.2

Establish contact between the Sitecore.Documentation app and your XConnect instance

To establish contact between the Sitecore.Documentation app and your xConnect instance:

  1. In Solution Explorer, double-click the Program.cs file and replace the content with the following code:

    RequestResponse
    using Sitecore.XConnect;
    using Sitecore.XConnect.Client;
    using Sitecore.XConnect.Client.WebApi;
    using Sitecore.XConnect.Collection.Model;
    using Sitecore.XConnect.Schema;
    using Sitecore.Xdb.Common.Web;
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    
    namespace Sitecore.Documentation
    {
        public class Program
        {
            // From <xConnect instance>\App_Config\AppSettings.config
            const string CERTIFICATE_OPTIONS = 
                "StoreName=My;StoreLocation=LocalMachine;FindType=FindByThumbprint;FindValue=???";
    
            // From your installation
            const string XCONNECT_URL = "https://???XConnect.local";
    
            private static void Main(string[] args)
            {
                MainAsync(args).ConfigureAwait(false).GetAwaiter().GetResult();
                System.Console.ForegroundColor = ConsoleColor.DarkGreen;
                System.Console.WriteLine("");
                Console.WriteLine("END OF PROGRAM.");
                Console.ReadKey();
            }
    
            private static async Task MainAsync(string[] args)
            {
                CertificateHttpClientHandlerModifierOptions options = CertificateHttpClientHandlerModifierOptions.Parse(CERTIFICATE_OPTIONS);
    
                var certificateModifier = new CertificateHttpClientHandlerModifier(options);
    
                List<IHttpClientModifier> clientModifiers = new List<IHttpClientModifier>();
                var timeoutClientModifier = new TimeoutHttpClientModifier(new TimeSpan(0, 0, 20));
                clientModifiers.Add(timeoutClientModifier);
    
                var collectionClient = new CollectionWebApiClient(
                    new Uri(XCONNECT_URL + "/odata"),
                    clientModifiers,
                    new[] { certificateModifier }
                );
    
                var searchClient = new SearchWebApiClient(
                    new Uri(XCONNECT_URL + "/odata"),
                    clientModifiers,
                    new[] { certificateModifier }
                );
    
                var configurationClient = new ConfigurationWebApiClient(
                    new Uri(XCONNECT_URL + "/configuration"),
                    clientModifiers,
                    new[] { certificateModifier }
                );
    
                var cfg = new XConnectClientConfiguration(
                    new XdbRuntimeModel(CollectionModel.Model),
                    collectionClient,
                    searchClient,
                    configurationClient
                );
    
                try
                {
                    await cfg.InitializeAsync();
    
                    // Print xConnect if configuration is valid
                    var arr = new[]
                    {
                        @"            ______                                                       __     ",
                        @"           /      \                                                     |  \    ",
                        @" __    __ |  $$$$$$\  ______   _______   _______    ______    _______  _| $$_   ",
                        @"|  \  /  \| $$   \$$ /      \ |       \ |       \  /      \  /       \|   $$ \  ",
                        @"\$$\/  $$| $$      |  $$$$$$\| $$$$$$$\| $$$$$$$\|  $$$$$$\|  $$$$$$$ \$$$$$$   ",
                        @" >$$  $$ | $$   __ | $$  | $$| $$  | $$| $$  | $$| $$    $$| $$        | $$ __  ",
                        @" /  $$$$\ | $$__/  \| $$__/ $$| $$  | $$| $$  | $$| $$$$$$$$| $$_____   | $$|  \",
                        @"|  $$ \$$\ \$$    $$ \$$    $$| $$  | $$| $$  | $$ \$$     \ \$$     \   \$$  $$",
                        @" \$$   \$$  \$$$$$$   \$$$$$$  \$$   \$$ \$$   \$$  \$$$$$$$  \$$$$$$$    \$$$$ "
                    };
                    Console.WindowWidth = 160;
                    foreach (string line in arr)
                        Console.WriteLine(line);
    
                }
                catch (XdbModelConflictException ce)
                {
                    Console.WriteLine("ERROR:" + ce.Message);
                    return;
                }
    
                // Initialize a client using the validated configuration
                using (var client = new XConnectClient(cfg))
                {
                    try
                    {
                        // This is where we add content in later code samples
                    }
                    catch (XdbExecutionException ex)
                    {
                        // Deal with exception
                    }
                }
            }
        }
    }
  2. Edit the CERTIFICATE_THUMBPRINT and the XCONNECT_URL constants.

  3. Save the Program.cs file.

  4. Press F5 to run the app. If the connection is established, the app writes END OF PROGRAM in the terminal:

    A terminal with END OF PROGRAM in the app output.

Create a contact with a known identifier

To create a contact with a known identifier:

  1. In Visual Studio, in Solution Explorer, double-click the Program.cs file and replace the content with the following code:

    RequestResponse
    using Sitecore.XConnect;
    using Sitecore.XConnect.Client;
    using Sitecore.XConnect.Client.WebApi;
    using Sitecore.XConnect.Collection.Model;
    using Sitecore.XConnect.Schema;
    using Sitecore.Xdb.Common.Web;
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    
    namespace Sitecore.Documentation
    {
        public class Program
        {
            // From <xConnect instance>\App_Config\AppSettings.config
            const string CERTIFICATE_OPTIONS = 
                "StoreName=My;StoreLocation=LocalMachine;FindType=FindByThumbprint;FindValue=???";
    
            // From your installation
            const string XCONNECT_URL = "https://???XConnect.local";
    
            private static void Main(string[] args)
            {
                MainAsync(args).ConfigureAwait(false).GetAwaiter().GetResult();
                System.Console.ForegroundColor = ConsoleColor.DarkGreen;
                System.Console.WriteLine("");
                Console.WriteLine("END OF PROGRAM.");
                Console.ReadKey();
            }
    
            private static async Task MainAsync(string[] args)
            {
                CertificateHttpClientHandlerModifierOptions options = CertificateHttpClientHandlerModifierOptions.Parse(CERTIFICATE_OPTIONS);
    
                var certificateModifier = new CertificateHttpClientHandlerModifier(options);
    
                List<IHttpClientModifier> clientModifiers = new List<IHttpClientModifier>();
                var timeoutClientModifier = new TimeoutHttpClientModifier(new TimeSpan(0, 0, 20));
                clientModifiers.Add(timeoutClientModifier);
    
                var collectionClient = new CollectionWebApiClient(
                    new Uri(XCONNECT_URL + "/odata"),
                    clientModifiers,
                    new[] { certificateModifier }
                );
    
                var searchClient = new SearchWebApiClient(
                    new Uri(XCONNECT_URL + "/odata"),
                    clientModifiers,
                    new[] { certificateModifier }
                );
    
                var configurationClient = new ConfigurationWebApiClient(
                    new Uri(XCONNECT_URL + "/configuration"),
                    clientModifiers,
                    new[] { certificateModifier }
                );
    
                var cfg = new XConnectClientConfiguration(
                    new XdbRuntimeModel(CollectionModel.Model),
                    collectionClient,
                    searchClient,
                    configurationClient
                );
    
                try
                {
                    await cfg.InitializeAsync();
    
                    // Print xConnect if configuration is valid
                    var arr = new[]
                    {
                        @"            ______                                                       __     ",
                        @"           /      \                                                     |  \    ",
                        @" __    __ |  $$$$$$\  ______   _______   _______    ______    _______  _| $$_   ",
                        @"|  \  /  \| $$   \$$ /      \ |       \ |       \  /      \  /       \|   $$ \  ",
                        @"\$$\/  $$| $$      |  $$$$$$\| $$$$$$$\| $$$$$$$\|  $$$$$$\|  $$$$$$$ \$$$$$$   ",
                        @" >$$  $$ | $$   __ | $$  | $$| $$  | $$| $$  | $$| $$    $$| $$        | $$ __  ",
                        @" /  $$$$\ | $$__/  \| $$__/ $$| $$  | $$| $$  | $$| $$$$$$$$| $$_____   | $$|  \",
                        @"|  $$ \$$\ \$$    $$ \$$    $$| $$  | $$| $$  | $$ \$$     \ \$$     \   \$$  $$",
                        @" \$$   \$$  \$$$$$$   \$$$$$$  \$$   \$$ \$$   \$$  \$$$$$$$  \$$$$$$$    \$$$$ "
                    };
                    Console.WindowWidth = 160;
                    foreach (string line in arr)
                        Console.WriteLine(line);
    
                }
                catch (XdbModelConflictException ce)
                {
                    Console.WriteLine("ERROR:" + ce.Message);
                    return;
                }
    
                // Initialize a client using the validated configuration
                using (var client = new XConnectClient(cfg))
                {
                    try
                    {
                        // Identifier for a 'known' contact
                        var identifier = new ContactIdentifier[]
                        {
                            new ContactIdentifier(
                                "twitter",
                                "myrtlesitecore" + Guid.NewGuid().ToString("N"),
                                ContactIdentifierType.Known
                            )
                        };
    
                        // Print out the identifier that is going to be used
                        Console.WriteLine("Contact Identifier: " + identifier[0].Identifier);
    
                        // Create a new contact with the identifier
                        Contact knownContact = new Contact(identifier);
    
                        client.AddContact(knownContact);
    
                        // Submit contact and interaction - a total of two operations
                        await client.SubmitAsync();
    
                        // Get the last batch that was executed
                        var operations = client.LastBatch;
    
                        // Loop through operations and check status
                        foreach (var operation in operations)
                        {
                            Console.WriteLine(
                                operation.OperationType
                                + operation.Target.GetType().ToString()
                                + " Operation: "
                                + operation.Status
                            );
                        }
    
                        Console.ReadLine();
                    }
                    catch (XdbExecutionException ex)
                    {
                        // Deal with exception
                    }
                }
            }
        }
    }
  2. Edit the CERTIFICATE_THUMBPRINT and the XCONNECT_URL constants.

  3. Save the Program.cs file.

  4. Press F5 to run the app. If the connection is established, the app writes the following in the terminal:

    • The contact identifier.

    • That the contact was added.

    A terminal with the contact details in the app output.

Create an interaction with a single event

The next step is to create an interaction with a single event such as a goal.

Warning

This code sample pollutes your database, because:

  • All interactions require a channel GUID. You define these in Sitecore, but xConnect lets you pass a random channel GUID.

  • All events require an event GUID. You define these in Sitecore, but xConnect lets you pass a random event GUID.

If you want to keep your database clean, you must manually delete the interaction and the event created here.

To create an interaction with a single event, for example, a goal:

  1. In Visual Studio, in Solution Explorer, double-click the Program.cs file and replace the content with the following code:

    RequestResponse
    using Sitecore.XConnect;
    using Sitecore.XConnect.Client;
    using Sitecore.XConnect.Client.WebApi;
    using Sitecore.XConnect.Collection.Model;
    using Sitecore.XConnect.Schema;
    using Sitecore.Xdb.Common.Web;
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    
    namespace Sitecore.Documentation
    {
        public class Program
        {
            // From <xConnect instance>\App_Config\AppSettings.config
            const string CERTIFICATE_OPTIONS = 
                "StoreName=My;StoreLocation=LocalMachine;FindType=FindByThumbprint;FindValue=???";
    
            // From your installation
            const string XCONNECT_URL = "https://???XConnect.local";
    
            private static void Main(string[] args)
            {
                MainAsync(args).ConfigureAwait(false).GetAwaiter().GetResult();
                System.Console.ForegroundColor = ConsoleColor.DarkGreen;
                System.Console.WriteLine("");
                Console.WriteLine("END OF PROGRAM.");
                Console.ReadKey();
            }
    
            private static async Task MainAsync(string[] args)
            {
                CertificateHttpClientHandlerModifierOptions options = CertificateHttpClientHandlerModifierOptions.Parse(CERTIFICATE_OPTIONS);
    
                var certificateModifier = new CertificateHttpClientHandlerModifier(options);
    
                List<IHttpClientModifier> clientModifiers = new List<IHttpClientModifier>();
                var timeoutClientModifier = new TimeoutHttpClientModifier(new TimeSpan(0, 0, 20));
                clientModifiers.Add(timeoutClientModifier);
    
                var collectionClient = new CollectionWebApiClient(
                    new Uri(XCONNECT_URL + "/odata"),
                    clientModifiers,
                    new[] { certificateModifier }
                );
    
                var searchClient = new SearchWebApiClient(
                    new Uri(XCONNECT_URL + "/odata"),
                    clientModifiers,
                    new[] { certificateModifier }
                );
    
                var configurationClient = new ConfigurationWebApiClient(
                    new Uri(XCONNECT_URL + "/configuration"),
                    clientModifiers,
                    new[] { certificateModifier }
                );
    
                var cfg = new XConnectClientConfiguration(
                    new XdbRuntimeModel(CollectionModel.Model),
                    collectionClient,
                    searchClient,
                    configurationClient
                );
    
                try
                {
                    await cfg.InitializeAsync();
    
                    // Print xConnect if configuration is valid
                    var arr = new[]
                    {
                        @"            ______                                                       __     ",
                        @"           /      \                                                     |  \    ",
                        @" __    __ |  $$$$$$\  ______   _______   _______    ______    _______  _| $$_   ",
                        @"|  \  /  \| $$   \$$ /      \ |       \ |       \  /      \  /       \|   $$ \  ",
                        @"\$$\/  $$| $$      |  $$$$$$\| $$$$$$$\| $$$$$$$\|  $$$$$$\|  $$$$$$$ \$$$$$$   ",
                        @" >$$  $$ | $$   __ | $$  | $$| $$  | $$| $$  | $$| $$    $$| $$        | $$ __  ",
                        @" /  $$$$\ | $$__/  \| $$__/ $$| $$  | $$| $$  | $$| $$$$$$$$| $$_____   | $$|  \",
                        @"|  $$ \$$\ \$$    $$ \$$    $$| $$  | $$| $$  | $$ \$$     \ \$$     \   \$$  $$",
                        @" \$$   \$$  \$$$$$$   \$$$$$$  \$$   \$$ \$$   \$$  \$$$$$$$  \$$$$$$$    \$$$$ "
                    };
                    Console.WindowWidth = 160;
                    foreach (string line in arr)
                        Console.WriteLine(line);
    
                }
                catch (XdbModelConflictException ce)
                {
                    Console.WriteLine("ERROR:" + ce.Message);
                    return;
                }
    
                // Initialize a client using the validated configuration
                using (var client = new XConnectClient(cfg))
                {
                    try
                    {
                        var offlineGoal = Guid.Parse("ad8ab7fe-ab48-4ea9-a976-ae7a268ae2f0"); // "Watched demo" goal
                        var channelId = Guid.Parse("110cbf07-6b1a-4743-a398-6749acfcd7aa"); // "Other event" channel
    
                        // Identifier for a 'known' contact
                        var identifier = new ContactIdentifier[]
                        {
                            new ContactIdentifier(
                                "twitter",
                                "myrtlesitecore" + Guid.NewGuid().ToString("N"),
                                ContactIdentifierType.Known
                            )
                        };
    
                        // Print out the identifier that is going to be used
                        Console.WriteLine("Identifier: " + identifier[0].Identifier);
    
                        // Create a new contact with the identifier
                        Contact knownContact = new Contact(identifier);
    
                        client.AddContact(knownContact);
    
                        // Create a new interaction for that contact
                        Interaction interaction = new Interaction(knownContact, InteractionInitiator.Brand, channelId, "");
    
                        // Add events - all interactions must have at least one event
                        var xConnectEvent = new Goal(offlineGoal, DateTime.UtcNow);
                        interaction.Events.Add(xConnectEvent);
    
                        // Add the contact and interaction
                        client.AddInteraction(interaction);
    
                        // Submit contact and interaction - a total of two operations
                        await client.SubmitAsync();
    
                        // Get the last batch that was executed
                        var operations = client.LastBatch;
    
                        // Loop through operations and check status
                        foreach (var operation in operations)
                        {
                            Console.WriteLine(
                                operation.OperationType
                                + operation.Target.GetType().ToString()
                                + " Operation: "
                                + operation.Status
                            );
                        }
    
                        Console.ReadLine();
                    }
                    catch (XdbExecutionException ex)
                    {
                        // Deal with exception
                    }
    
                }
            }
        }
    }
  2. Edit the CERTIFICATE_THUMBPRINT and the XCONNECT_URL constants.

  3. Save the Program.cs file.

  4. Press F5 to run the app. If the connection is established, the app writes the following in the terminal:

    • The contact identifier.

    • That the contact was added.

    • That the interaction with the event was added.

    A terminal with the contact and interaction event details in the app output.

Go to the next walkthrough to learn how to set contact and interaction facets.

Do you have some feedback for us?

If you have suggestions for improving this article,