Basics of xConnect – Step 6 – Create Interaction

An interaction is the point where contact interacts with the application/organization like Login, Adding item to the Cart or placing order via phone, Payment or just simply browsing the site.

Sitecore.XConnect.Interaction is the class using which, Interaction can be created.

To create interaction, following are the mandatory proeprties you need to pass:

  • Initiator
  • ChannelId
  • UserAgent

Initiator: who initiates the interaction. Either the user/contact or the application

ChannelId: Through which channel contact interact with the application/organization. Channels are represented as items under Sitecore CMS content tree /sitecore/system/Marketing Control Panel/Taxonomies/Channel.

UserAgent: User Agent which every device used to connnect the xConnect web service

For more information on Interaction, have a look at https://doc.sitecore.net/developers/xp/xconnect/xconnect-model/interactions.html

Lets initiate the Interaction now,….

I have already created one goal and channel in the Sitecore Marketing Control Panel.  The variable offlineGoal and channelId in following code are refering to those items.

                //Interaction
                var offlineGoal = Guid.Parse("A9948719-E6E4-46D2-909B-3680E724ECE9");//offline goal - KioskSubmission goal
                var channelId = Guid.Parse("3FC61BB8-0D9F-48C7-9BBD-D739DCBBE032"); // /sitecore/system/Marketing Control Panel/Taxonomies/Channel/Offline/Store/Enter store - offline enter storl channel
                //Create a new interaction for that contact
                Interaction interaction = new Interaction(knownContact, InteractionInitiator.Contact, channelId, "");
                // Add events - all interactions must have at least one event
                var xConnectEvent = new Goal(offlineGoal, DateTime.UtcNow);
                interaction.Events.Add(xConnectEvent);
                //Add interaction to client
                client.AddInteraction(interaction);

After adding this final segment, the method createUpdateContact() would finally look like following:

        public void createUpdateContact()
        {
            //Certificate
            CertificateWebRequestHandlerModifierOptions options =
            CertificateWebRequestHandlerModifierOptions.Parse("StoreName=My;StoreLocation=LocalMachine;FindType=FindByThumbprint;FindValue=587d948806e57cf511b37a447a2453a02dfd3686");
            var certificateModifier = new CertificateWebRequestHandlerModifier(options);

            //Model - xConnect Client Configuration
            List clientModifiers = new List();
            var timeoutClientModifier = new TimeoutHttpClientModifier(new TimeSpan(0, 0, 20));
            clientModifiers.Add(timeoutClientModifier);

            // This overload takes three client end points - collection, search, and configuration
            var collectionClient = new CollectionWebApiClient(new Uri("https://sc9.xconnect/odata"), clientModifiers, new[] { certificateModifier });
            var searchClient = new SearchWebApiClient(new Uri("https://sc9.xconnect/odata"), clientModifiers, new[] { certificateModifier });
            var configurationClient = new ConfigurationWebApiClient(new Uri("https://sc9.xconnect/configuration"), clientModifiers, new[] { certificateModifier });

            var config = new XConnectClientConfiguration(
                new XdbRuntimeModel(CollectionModel.Model), collectionClient, searchClient, configurationClient);
            //initialize the configuration
            config.Initialize();

            //create the xConnect Client
            using (Sitecore.XConnect.Client.XConnectClient client = new XConnectClient(config))
            {
                // Identifier
                var identifier = new ContactIdentifier[]
                {
                    new ContactIdentifier("HIxConnect", "contact.name@demo.com", ContactIdentifierType.Known)
                };

                //Contact & Facets
                // Create a new contact with the identifier
                Contact knownContact = new Contact(identifier);
                client.AddContact(knownContact);

                //Facets
                #region Personal Information Facet
                //Persona information facet
                PersonalInformation personalInfoFacet = new PersonalInformation();
                personalInfoFacet.Title = ddTitle.SelectedValue;
                personalInfoFacet.FirstName = "Alok";
                personalInfoFacet.MiddleName = "S";
                personalInfoFacet.LastName = "KaduDeshmukh";
                personalInfoFacet.PreferredLanguage = "en";
                personalInfoFacet.Gender = "Male";
                personalInfoFacet.JobTitle = "Sitecore Web Developer";
                client.SetFacet(knownContact, PersonalInformation.DefaultFacetKey, personalInfoFacet);
                #endregion
                #region EmailAddress Facet
                EmailAddressList emails = new EmailAddressList(new EmailAddress("alok.kadudeshmukh@gmail.com", true), EmailAddressList.DefaultFacetKey);
                //OR the following code
                //var emails = existingContact.GetFacet(EmailAddressList.DefaultFacetKey);
                //emails.PreferredEmail = new EmailAddress("alok.kadudeshmukh@gmail.com", true);
                client.SetFacet(knownContact, EmailAddressList.DefaultFacetKey, emails);
                #endregion

                //Interaction
                var offlineGoal = Guid.Parse("A9948719-E6E4-46D2-909B-3680E724ECE9");//offline goal - KioskSubmission goal
                var channelId = Guid.Parse("3FC61BB8-0D9F-48C7-9BBD-D739DCBBE032"); // /sitecore/system/Marketing Control Panel/Taxonomies/Channel/Offline/Store/Enter store - offline enter storl channel
                //Create a new interaction for that contact
                Interaction interaction = new Interaction(knownContact, InteractionInitiator.Contact, channelId, "");
                // Add events - all interactions must have at least one event
                var xConnectEvent = new Goal(offlineGoal, DateTime.UtcNow);
                interaction.Events.Add(xConnectEvent);
                //Add interaction to client
                client.AddInteraction(interaction);

                client.Submit();
            }
        }

That’s it. Run the method and you can find the Contact added in the Expereince Profile.

Happy Coding 🙂

 

You can go back to previous step Step 5 – Facets or jump to the Main Page

Advertisements

Basics of xConnect – Step 5 – Create Facets

Facet is properties of the contact or interaction which adds some extra inforamtion about it. Like, name and address of the contact or the location of the interaction.

Facet contains,

  • Facet Model
  • Facet Definition (key)

There are two categories of facets:

  • Value facets
  • Calculated facets

Value facets can be set by using the xConnect Client API  from any client where as the Calculated facet are related to the contact’s interaction history, contact’s average engagement value per visit.

For more information regarding facets, have a look at https://doc.sitecore.net/developers/xp/xconnect/xconnect-model/facets/index.html

 

Let’s Create the Facet

                //Facets
                #region Personal Information Facet
                //Persona information facet
                PersonalInformation personalInfoFacet = new PersonalInformation();
                personalInfoFacet.Title = ddTitle.SelectedValue;
                personalInfoFacet.FirstName = "Alok";
                personalInfoFacet.MiddleName = "S";
                personalInfoFacet.LastName = "KaduDeshmukh";
                personalInfoFacet.PreferredLanguage = "en";
                personalInfoFacet.Gender = "Male";
                personalInfoFacet.JobTitle = "Sitecore Web Developer";
                client.SetFacet<PersonalInformation>(knownContact, PersonalInformation.DefaultFacetKey, personalInfoFacet);
                #endregion
                #region EmailAddress Facet
                EmailAddressList emails = new EmailAddressList(new EmailAddress("alok.kadudeshmukh@gmail.com", true), EmailAddressList.DefaultFacetKey);
                //OR the following code
                //var emails = existingContact.GetFacet<EmailAddressList>(EmailAddressList.DefaultFacetKey);
                //emails.PreferredEmail = new EmailAddress("alok.kadudeshmukh@gmail.com", true);
                client.SetFacet<EmailAddressList>(knownContact, EmailAddressList.DefaultFacetKey, emails);
                #endregion

Facet properties are quite self explanatory.

Now, the method createUpdateContact() would look like following:

        public void createUpdateContact()
        {
            //Certificate
            CertificateWebRequestHandlerModifierOptions options =
            CertificateWebRequestHandlerModifierOptions.Parse("StoreName=My;StoreLocation=LocalMachine;FindType=FindByThumbprint;FindValue=587d948806e57cf511b37a447a2453a02dfd3686");
            var certificateModifier = new CertificateWebRequestHandlerModifier(options);

            //Model - xConnect Client Configuration
            List<IHttpClientModifier> clientModifiers = new List<IHttpClientModifier>();
            var timeoutClientModifier = new TimeoutHttpClientModifier(new TimeSpan(0, 0, 20));
            clientModifiers.Add(timeoutClientModifier);

            // This overload takes three client end points - collection, search, and configuration
            var collectionClient = new CollectionWebApiClient(new Uri("https://sc9.xconnect/odata"), clientModifiers, new[] { certificateModifier });
            var searchClient = new SearchWebApiClient(new Uri("https://sc9.xconnect/odata"), clientModifiers, new[] { certificateModifier });
            var configurationClient = new ConfigurationWebApiClient(new Uri("https://sc9.xconnect/configuration"), clientModifiers, new[] { certificateModifier });

            var config = new XConnectClientConfiguration(
                new XdbRuntimeModel(CollectionModel.Model), collectionClient, searchClient, configurationClient);
            //initialize the configuration
            config.Initialize();

            //create the xConnect Client
            using (Sitecore.XConnect.Client.XConnectClient client = new XConnectClient(config))
            {
                // Identifier
                var identifier = new ContactIdentifier[]
                {
                    new ContactIdentifier("HIxConnect", "contact.name@demo.com", ContactIdentifierType.Known)
                };

                //Contact & Facets
                // Create a new contact with the identifier
                Contact knownContact = new Contact(identifier);
                client.AddContact(knownContact);

                //Facets
                #region Personal Information Facet
                //Persona information facet
                PersonalInformation personalInfoFacet = new PersonalInformation();
                personalInfoFacet.Title = ddTitle.SelectedValue;
                personalInfoFacet.FirstName = "Alok";
                personalInfoFacet.MiddleName = "S";
                personalInfoFacet.LastName = "KaduDeshmukh";
                personalInfoFacet.PreferredLanguage = "en";
                personalInfoFacet.Gender = "Male";
                personalInfoFacet.JobTitle = "Sitecore Web Developer";
                client.SetFacet<PersonalInformation>(knownContact, PersonalInformation.DefaultFacetKey, personalInfoFacet);
                #endregion
                #region EmailAddress Facet
                EmailAddressList emails = new EmailAddressList(new EmailAddress("alok.kadudeshmukh@gmail.com", true), EmailAddressList.DefaultFacetKey);
                //OR the following code
                //var emails = existingContact.GetFacet<EmailAddressList>(EmailAddressList.DefaultFacetKey);
                //emails.PreferredEmail = new EmailAddress("alok.kadudeshmukh@gmail.com", true);
                client.SetFacet<EmailAddressList>(knownContact, EmailAddressList.DefaultFacetKey, emails);
                #endregion

                //Interaction
                client.Submit();
            }
        }

Let’s go to Next Step Step 6- Create Interaction

You can go back to previous step Step 4 – Contacts or jump to the Main Page

Basics of xConnect – Step 4 – Create Contacts

Before directly jumps to create Contact, let’s first understands the Contact.

A end user who interacts with the website/application is a contact.

Contact vs Sitecore User:

A contact and Sitecore user are two completely separate things. Sitecore user is a user who can access the CMS where as Contact is not having rights to use CMS by default. Contact is created in xDB.

Though, there is no implicit relationship between user & contact, developer can define such relationship explicitly. Developer can map the unique properties of both i.e. the username of Sitecore user and the identifier of the Contact.

Sitecore.XConnect.Contact class is used to create Contact object. Whenever this contact is created in xDB, ID has been assigned which is a GuID. Contacts should have atleast one identifier to identify it outside xDB.

Contacts are of Two types:

  • Known Contact – having known identifier
  • Anonymous Contact – having alias identifier.

Ref: https://doc.sitecore.net/developers/xp/xconnect/xconnect-model/contacts/

 

Let’s Create the Known Contact now,


                //Contact & Facets
                // Create a new contact with the identifier
                Contact knownContact = new Contact(identifier);
                client.AddContact(knownContact);

                //Facets

                //Interaction
                client.Submit();

Replace this code with the //Contact & Facets comment in the createUpdateContact() method.

//Contact & Facets

//Facets

//Interaction

So, now method should look like following:

        public void createUpdateContact()
        {
            //Certificate
            CertificateWebRequestHandlerModifierOptions options =
            CertificateWebRequestHandlerModifierOptions.Parse("StoreName=My;StoreLocation=LocalMachine;FindType=FindByThumbprint;FindValue=587d948806e57cf511b37a447a2453a02dfd3686");
            var certificateModifier = new CertificateWebRequestHandlerModifier(options);

            //Model - xConnect Client Configuration
            List clientModifiers = new List();
            var timeoutClientModifier = new TimeoutHttpClientModifier(new TimeSpan(0, 0, 20));
            clientModifiers.Add(timeoutClientModifier);

            // This overload takes three client end points - collection, search, and configuration
            var collectionClient = new CollectionWebApiClient(new Uri("https://sc9.xconnect/odata"), clientModifiers, new[] { certificateModifier });
            var searchClient = new SearchWebApiClient(new Uri("https://sc9.xconnect/odata"), clientModifiers, new[] { certificateModifier });
            var configurationClient = new ConfigurationWebApiClient(new Uri("https://sc9.xconnect/configuration"), clientModifiers, new[] { certificateModifier });

            var config = new XConnectClientConfiguration(
                new XdbRuntimeModel(CollectionModel.Model), collectionClient, searchClient, configurationClient);
            //initialize the configuration
            config.Initialize();

            //create the xConnect Client
            using (Sitecore.XConnect.Client.XConnectClient client = new XConnectClient(config))
            {
                // Identifier
                var identifier = new ContactIdentifier[]
                {
                    new ContactIdentifier("HIxConnect", "contact.name@demo.com", ContactIdentifierType.Known)
                };

                //Contact & Facets
                // Create a new contact with the identifier
                Contact knownContact = new Contact(identifier);
                client.AddContact(knownContact);

                //Facets

                //Interaction
                client.Submit();
            }
        }

Let’s go to Next Step Step 5- Create Facets

You can go back to previous step Step 3 – Identifier or jump to the Main Page

Basics of xConnect – Step 3 – Create Identifier

ID can be used to identify the contact inside the xDB. But to identify the contact outside the xDB, you have to assign a identifier. Examples of valid identifiers include the website which the user is comming from, website logins, social media handles, referrals, etc.

Sitecore.XConnect.ContactIdentifier class can be used to initialize the Identifier.

Each Identifier consist of following:

An identifier Source, which describes where the identifier comes from – such as ‘twitter’ or might be the domain name of the website

An Identifier, such as a username or email id

An identifier ContactIdentifierType – either ContactIdentifierType.Anonymous  or ContactIdentifierType.Known

You can identify if the Contact is known or anonymous by using IsKnown property.

Contacts are uniquely identified by a combination of Identifier and Source. This requirement supports the following scenarios:

  1. A contact using the same username across multiple systems – for example, using myrtlesitecore on Twitter as well as Instagram
  2. Two different contacts using the same username – for example, contact 1 using sitecore on Instagram and contact 2 using sitecore on Twitter.

Let’s create identifier,

// Identifier
var identifier = new ContactIdentifier[]
{
    new ContactIdentifier("HIxConnect", "alok.kadudeshmukh@gmail.com", ContactIdentifierType.Known)
};

Paste this code in place of // Identifier &amp;amp;amp;amp; Contact

You can notice that it is an array ContactIdentifier[]. This is because a single contact can have multiple identifiers. A contact’s identifiers are represented by the Identifiers property on the Contact class.

The first parameter of the ContactIdentifier() is the Source – here I have kept it hardcoded domain name – “HIxConnect” (hardcoded domain name is not best practice. I have done it just because of demo purpose).

2nd parameter is the unique identifier string. Here I have used an email id.

3rd parameter is the type. Either ContactIdentifierType.Known or ContactIdentifierType.Anonymous.

 

So, now your method should look like following:

        public void createUpdateContact()
        {
            //Certificate
            CertificateWebRequestHandlerModifierOptions options =
            CertificateWebRequestHandlerModifierOptions.Parse("StoreName=My;StoreLocation=LocalMachine;FindType=FindByThumbprint;FindValue=587d948806e57cf511b37a447a2453a02dfd3686");
            var certificateModifier = new CertificateWebRequestHandlerModifier(options);

            //Model - xConnect Client Configuration
            List clientModifiers = new List();
            var timeoutClientModifier = new TimeoutHttpClientModifier(new TimeSpan(0, 0, 20));
            clientModifiers.Add(timeoutClientModifier);

            // This overload takes three client end points - collection, search, and configuration
            var collectionClient = new CollectionWebApiClient(new Uri("https://sc9.xconnect/odata"), clientModifiers, new[] { certificateModifier });
            var searchClient = new SearchWebApiClient(new Uri("https://sc9.xconnect/odata"), clientModifiers, new[] { certificateModifier });
            var configurationClient = new ConfigurationWebApiClient(new Uri("https://sc9.xconnect/configuration"), clientModifiers, new[] { certificateModifier });

            var config = new XConnectClientConfiguration(
                new XdbRuntimeModel(CollectionModel.Model), collectionClient, searchClient, configurationClient);
            //initialize the configuration
            config.Initialize();

            //create the xConnect Client
            using (Sitecore.XConnect.Client.XConnectClient client = new XConnectClient(config))
            {
                // Identifier
                var identifier = new ContactIdentifier[]
                {
                    new ContactIdentifier("HIxConnect", "contact.name@demo.com", ContactIdentifierType.Known)
                };

                //Contact & Facets

                // Interaction
            }

        }

Let’s go to Next Step Step 4- Create Contact

You can go back to previous step Step 2 – Model or jump to the Main Page

Basics of xConnect – Step 2 – Understanding Model

The xConnect model is a representation of the structure and type of data that is collected by xConnect.

The xConnect model defines,

  • Contact and interaction facets, such as PersonalInformation, Email Address and IPInfo
  • Event types, such as Goal and Outcome
  • All CLR types, such as System.String or

Want to know how json format of this model looks like? Open the xConnect website root folder. The \App_data\Models folder must contain a JSON representation of all models. You can find Sitecore.XConnect.Collection.Model, 9.0.json and Sitecore.XConnect.ContentTesting.Model, 1.0.json files. Open the Collection.Model.9.0.json file, and you can see different Facets like Email Address, PersonalInformation in that file.

When a new model is created, it must be deployed to xConnect before it can be used. The xConnect version of the model is considered to be the authoritative version. All client-side models are validated against the xConnect version when the xConnect Client API is initialized.

The following properties of the client’s model must match the xConnect model:

  • Model Name,
  • Model Version,
  • Facets-events-types

For more information on models, have a look at https://doc.sitecore.net/developers/xp/xconnect/xconnect-model/index.html

Let’s create a model and require client configuration.


//Model - xConnect Client Configuration
List clientModifiers = new List();
var timeoutClientModifier = new TimeoutHttpClientModifier(new TimeSpan(0, 0, 20));
clientModifiers.Add(timeoutClientModifier);

// This overload takes three client end points - collection, search, and configuration
var collectionClient = new CollectionWebApiClient(new Uri("https://sc9.xconnect/odata"), clientModifiers, new[] { certificateModifier });
var searchClient = new SearchWebApiClient(new Uri("https://sc9.xconnect/odata"), clientModifiers, new[] { certificateModifier });
var configurationClient = new ConfigurationWebApiClient(new Uri("https://sc9.xconnect/configuration"), clientModifiers, new[] { certificateModifier });

var config = new XConnectClientConfiguration(
new XdbRuntimeModel(CollectionModel.Model), collectionClient, searchClient, configurationClient);
//initialize the configuration
config.Initialize();
//create the xConnect Client
using (Sitecore.XConnect.Client.XConnectClient client = new XConnectClient(config))
{

}

Move the Identifier, Contact & Facets and Interaction comment lines into the using() braces.

In the code, one thing to notice is that we have initialized collection client, search client and configuration client. Make sure you replace the sc9.xconnect domain name in the url with your xconnect website domain name.

At the end of this our createUpdateContact method looks like following:


public void createUpdateContact()
{
//Certificate
CertificateWebRequestHandlerModifierOptions options =
CertificateWebRequestHandlerModifierOptions.Parse("StoreName=My;StoreLocation=LocalMachine;FindType=FindByThumbprint;FindValue=587d948806e57cf511b37a447a2453a02dfd3686");
var certificateModifier = new CertificateWebRequestHandlerModifier(options);

//Model - xConnect Client Configuration
List clientModifiers = new List();
var timeoutClientModifier = new TimeoutHttpClientModifier(new TimeSpan(0, 0, 20));
clientModifiers.Add(timeoutClientModifier);

// This overload takes three client end points - collection, search, and configuration
var collectionClient = new CollectionWebApiClient(new Uri("https://sc9.xconnect/odata"), clientModifiers, new[] { certificateModifier });
var searchClient = new SearchWebApiClient(new Uri("https://sc9.xconnect/odata"), clientModifiers, new[] { certificateModifier });
var configurationClient = new ConfigurationWebApiClient(new Uri("https://sc9.xconnect/configuration"), clientModifiers, new[] { certificateModifier });
var config = new XConnectClientConfiguration(
new XdbRuntimeModel(CollectionModel.Model), collectionClient, searchClient, configurationClient);
//initialize the configuration
config.Initialize();

//create the xConnect Client
using (Sitecore.XConnect.Client.XConnectClient client = new XConnectClient(config))
{
// Identifier

//Contact & Facets

// Interaction
}
}

Now let’s go to Next Step Step 3- Create Idenitifer

You can go back to previous step Step 1 – Valid Certificate or Go back to the Main Page

Basics of xConnect – Step 1 – Valid Certificate

Please note, xConnect is the service layer that sits in between the xDB and any trusted client. Any application that accesses the xDB through xConnect must have valid certificate.

If you already have the ssl certificate for your application then you can copy the thumbprint of the certificate and pass it in the code.

If not, Let’s create the secure certificate,

Make sure you have folder named certificates created under C: drive or else just update the path of C:\certificates in below script.


#generate certificate
$thumbprint = (New-SelfSignedCertificate `
-Subject "CN=xConnectDemoCert" `
-Type SSLServerAuthentication `
-FriendlyName "xConnectDemoCertificate").Thumbprint
#export certificate with password
$certificateFilePath = "C:\certificates\$thumbprint.pfx"
Export-PfxCertificate `
-cert cert:\LocalMachine\MY\$thumbprint `
-FilePath "$certificateFilePath" `
-Password (Read-Host -Prompt "Enter password that would protect the certificate" -AsSecureString)
#convert it to base64 string (blob)
$fileContentBytes = get-content $certificateFilePath -Encoding Byte
[System.Convert]::ToBase64String($fileContentBytes) | Out-File "C:\certificates\$thumbprint.txt"
Write-Host "Your secure certificate blob is located at C:\certificates\$thumbprint.txt" 

Open Powershell and run the script. You will be asked to enter the password for the certificate.

Once the certificate has been created, Go to the IIS server and add binding for your site. Make sure it is secured and having port 443 and select the newly created certificate “xConnectDemoCertificate” under SSL certificate option.

BasicsofxConnectCertificateIIS

 

Once we are done with the certificate, we need its thumbprint to connect to xConnect. Now let’s create the code and get the certificate.


//Certificate
 CertificateWebRequestHandlerModifierOptions options =
 CertificateWebRequestHandlerModifierOptions.Parse("StoreName=My;StoreLocation=LocalMachine;FindType=FindByThumbprint;FindValue=587d948806e57cf511b37a447a2453a02dfd3686");
 var certificateModifier = new CertificateWebRequestHandlerModifier(options);

You can notice, we need the StoreName, StoreLocation and the Thumbprint of the certificate as parameters to pass. Value
“587d948806e57cf511b37a447a2453a02dfd3686” is the certificate thumbprint value.

Replace the above code at //Certificate comment location in the createUpdateContact() method. The final method output will look like following:


public void createUpdateContact()
{
//Certificate
CertificateWebRequestHandlerModifierOptions options =
CertificateWebRequestHandlerModifierOptions.Parse("StoreName=My;StoreLocation=LocalMachine;FindType=FindByThumbprint;FindValue=587d948806e57cf511b37a447a2453a02dfd3686");
var certificateModifier = new CertificateWebRequestHandlerModifier(options);

//Model - xConnect Client Configuration

// Identifier

//Contact & Facets

// Interaction

}

Let’s now understand the Model and Client Configuration Step2

or Go back to the Main Page

Basics of xConnect

SITECORE XCONNECT.png

Hello Sitecoreans,

After getting a huge response on the Trending topic – xConnect at Sitecore User Group Conference India 2018 (#sugcon2018), I am sharing a step by step guide to create Contacts through .net application and xConnect which helps a new bee to  understands the xConnect quickly.

Let’s create a simple asp.net  application having Contact Us page which connects to xConnect and create the Experience Profile on submission. The click event of the form submission will call CreateContact method and this method looks like following.


public void createUpdateContact()
{
//Certificate

//Model - xConnect Client Configuration

// Identifier

//Contact

//Facets

// Interaction

}

Here are the few steps to start with