Blog

Aceik & Sitecore’s Whisky Tasting & CX Roundtable

Last week, Aceik and Sitecore brought together 18 digital experts from around Australia to discuss customer experience – the trends, challenges and risks facing a new project in 2021. And it wouldn’t be a robust discussion without a little whisky tasting – kindly delivered by Melbourne’s The Elysian Whisky Bar.

Our moderator introduced two topics then guests were divided into groups of 6 to discuss. Upon return to the main track, guests then shared their unique discussion. And today, we wanted to share the key highlights.

Question 1

Thinking of your ultimate goal for your customer experience: Where does personalisation and marketing automation fit in, and what has been the most significant step you’ve taken towards that goal in the last 12 months?

  • Need to answer the question – what is the goal of website? why do we have a website? Many competing internal stakeholders (e.g. buyers v sellers)
  • xConnect implementation issues – holding back use of marketing features
  • Constrained internally (resources, budget)
  • Lots and lots of content – how to deliver the right content to the right people
  • Targeting an audience to help them through a specific journey
  • A lot of marketing automation – Facebook and Google advertising – open rates response rates – deliverability of email – personalised to get better open rate – lots of experimentation – gain more information – and helping them through the marketing funnel
  • Xdb – issues – business priorities – can’t start the journey.
  • Quick wins – show/prove value

Question 2

Thinking of that ideal CX, what steps will you take for the next 12 months?

  • Quick wins are the focus all round – esp. marketing
  • Maintainability – JSS, SXA
  • Content, content, content – and how to manage
  • How to upsell better online – parts, service; portal for owners – service history, finance offers.
  • Ease of access to information, engagement on the website, simple discoverable info
  • Learn more about the primary personas/segments
  • Alignment of brand and service
  • More content for SEO and drive more traffic to website
  • Automate the creation of pages with data have
  • Cost effective ways of producing rich content
  • Complete digital sign up
  • Transform the experience in engaging with the brand for the first time
  • Brand awareness, show expertise, show thought leadership
  • Pattern matching to industries
  • CRM integration

It was a fantastic event and we really appreciate the open sharing amongst the group!

People of Aceik: Lila Tournier, Delivery and Operations Manager

Continuing on with our People of Aceik series, where we introduce you to our talented team mates, this month, we sat down with our Delivery and Operations Manager, Lila Tournier (note – it’s pronounced Lee-la, like from Futurama).

If you missed the last one with Praveen Manchana, you can catch up here.

Lila, tell us a bit about yourself

Lila: In terms of my career background, I started in advertising agencies, working through the line – so anything from TV, press and radio ads, brochures, point of sales, emails, online advertising… anything! 

I then moved internally to a digital focus role as it felt that this was the future and I loved the fact that there is always something to learn. 

From big ad land agencies in Sydney, I moved to Melbourne to digital agencies, from small to large consulting ones, and I’m now here at Aceik.

Tell us about why you decided to join Aceik

Lila: It happened rather randomly actually. Tim O’Neill, the former CEO of Reactive and current friend of Aceik put me onto the job. In the same week that Tim got in touch, I heard from 2 ex-colleagues that they were joining Aceik and I thought hang on, there is something to explore here. 

I wasn’t looking for a role, but Aceik seemed so attractive in terms of where it was at: a small agency with a blank canvas to work with and the opportunity to help shape and grow the business. Being part of that growth journey was something that was so exciting, so it was a quick and easy decision. 

What are you working on at the moment?

Lila: I’m lucky to work on a mixture of projects – there are just too many to explain! But it keeps the days diverse.

Tell us about yourself outside of Aceik hours

Lila: Outside of work, I’m also a farmer 🙂 I know that sounds weird but we have a small farm, mainly managing sheep but do also have a few rescues, so a bit like Noah’s Ark. 

This makes things very interesting and very busy when also coupled with our two young children! 

If someone wants to follow a career in your steps, what would you recommend?

Lila: Try anything and learn as much as you can early on. 

Sitecore Email Experience Manager (EXM), Importing Contacts and Custom Facets – Part 4

In Sitecore Email Experience Manager (EXM), Importing Contacts and Custom Facets – Part 1, I showed you how you can import contacts from a CSV file into a list in Sitecore. In Sitecore Email Experience Manager (EXM), Importing Contacts and Custom Facets – Part 2, I showed you how you can add to the list of out of the box supported fields when importing contacts into Sitecore. In Sitecore Email Experience Manager (EXM), Importing Contacts and Custom Facets – Part 3, I showed you how you can create your own custom facets and populate them for your contacts as you import them. If you haven’t already read them, head over and read them first.

In Sitecore Email Experience Manager (EXM), Importing Contacts and Custom Facets – Part 4, I’m now going to demonstrate how you can update the Experience Profile for a Contact by Add a new Tab into the User Interface and displaying your Custom Facet information.

Experience Profile Express Tab

Instead of developing all of this code from scratch, we’re going to use a package available in NuGet specifically written for this purpose. No point reinventing the wheel when someone else has already done all the hard work for you.

Experience Profile Express Tab is a package developed to streamline the creation of new tabs in the Experience Profile.

The first step we’ll take is to add the EPExpressTab to our project using NuGet. This will install two packages. EPExpressTab.Core and EXExpressTab. At the time of writing, version 2.0.2 was the latest released version.

To use EP Express Tab, we need to do the following:

  • Create a custom ViewModel that will represent the custom data we wish to display in the Experience Profile Tab
  • Create a custom EPExpressViewModel that will act as a Controller of sorts that will be called by EPExpressTab to populate our custom View Model and pass it to our view
  • Create a View to render the content for out custom tab in Experience Profile

First, let’s create our custom view model. In this example, this will contain just the new Employee fields the same as out custom Facet. Nothing special here. It’s just a standard class to hold our view model.

using System;

namespace Aceik.Feature.EXM.Models
{
    public class EmployeeViewModel
    {
        public string EmployeeId { get; set; }
        public string Department { get; set; }
        public DateTime? StartDate { get; set; }
        public string EmployeeType { get; set; }
    }
}

Next we need to create our EPExpressTab “Controller” class. This class is called by EPExpressTab and is used to generate the instance of our view model and pass it to the view.

using EPExpressTab.Data;
using EPExpressTab.Repositories;
using System;

namespace Aceik.Feature.EXM.Models
{
    public class EPCustomModel : EpExpressViewModel
    {
        public override string TabLabel => "Employee";
        public override string Heading => "Employee Details";

        public override object GetModel(Guid contactId)
        {
            Sitecore.XConnect.Contact model = EPRepository.GetContact(contactId, new string[] { EmployeeInfo.DefaultFacetKey });

            var employeeInfo = model.GetFacet<EmployeeInfo>();

            return new EmployeeViewModel
            {
                EmployeeId = employeeInfo?.EmployeeId,
                Department = employeeInfo?.Department,
                StartDate = employeeInfo?.StartDate,
                EmployeeType = employeeInfo?.EmployeeType
            };
        }

        public override string GetFullViewPath(object model)
        {
            return "/views/Aceik/Feature/EXM/Employee.cshtml";
        }
    }
}

The GetModel method is the action that is called to create the view model instance that will be passed to the view.

The GetFullViewPath method is as described. The method to get the path to the view.

The view itself it pretty straight forward with some inline styles defined, and the html tags etc to render the required custom data.

@model Aceik.Feature.EXM.Models.EmployeeViewModel
<style>
    .employee-border {
        padding-top: 10px !important;
        float: left;
        width: 100%;
    }

    .employee-text {
        display: block;
        float: left;
        width: 150px;
        color: #707070;
        clear: both;
    }

    .employee-value {
        clear: unset;
        padding-left: 95px;
        width: calc(100% - 150px);
        color: #121212;
    }
</style>
<div class="row">
    <div class="col-md-6">
        <span class="sc-text sc-text-value">Employee</span>
        <div class="sc-border employee-border">
            <span class="sc-text employee-text">Employee Id</span>
            <span class="sc-text employee-text employee-value">@Model.EmployeeId</span>
        </div>
        <div class="sc-border employee-border">
            <span class="sc-text employee-text">Department</span>
            <span class="sc-text employee-text employee-value">@Model.Department</span>
        </div>
        <div class="sc-border employee-border">
            <span class="sc-text employee-text">Start Date</span>
            <span class="sc-text employee-text employee-value">
                @if (Model.StartDate.HasValue)
                {
                    @Model.StartDate.Value.ToLocalTime().ToString("dd/MM/yyyy")
                }
            </span>
        </div>
        <div class="sc-border employee-border">
            <span class="sc-text employee-text">Employee Type</span>
            <span class="sc-text employee-text employee-value">@Model.EmployeeType</span>
        </div>
    </div>
</div>

Once this is deployed, along with the added EpExpressTab.config file that is added to the project with the inclusion of the NuGet package, you can now view the “Employee” tab in the Experience Profile that now shows the custom EmployeeInfo Facet data.

So you can examine the solution for yourself, please see below a link to the zip file containing the full Visual Studio solution, CSV files and a Sitecore package for the Import Map configuration items.

AceikEXM.zip

Sitecore Email Experience Manager (EXM), Importing Contacts and Custom Facets – Part 3

In Sitecore Email Experience Manager (EXM), Importing Contacts and Custom Facets – Part 1, I showed you how you can import contacts from a CSV file into a list in Sitecore. In Sitecore Email Experience Manager (EXM), Importing Contacts and Custom Facets – Part 2, I demonstrated how you can add to the list of out of the box supported fields when importing contacts into Sitecore. If you haven’t read these as yet, best to start with them first.

In Sitecore Email Experience Manager (EXM), Importing Contacts and Custom Facets – Part 3, I’m going to share with you how you can create your own custom facets and populate them for your contacts as you import them.

To do this, you are going to need to complete the following tasks:

  • Create a custom facet that will describe the additional data you wish to store for your contacts
  • Build a model for your custom facet that will be used by Xdb to store your custom facet data
  • Serialize your custom model and publish it so that Xdb will recognise your model
  • Create a custom Import mapper class that will be used by the Import process to read your custom fields from the import data and write it to your custom facet
  • Update the Import map configuration so that you can map the fields of your CSV file on import
  • Create the required Sitecore configuration settings for your facet and facet import mapper
  • Deploy the updated/new files to Sitecore and XConnect

Create a custom facet

We are going to store Employee information for each of our contacts. To support that, the first thing we are going to need to do is to create our own custom Facet.

Using Sitecore Helix principles and guidelines, I’ve created a new Feature project in Visual Studio that will contain all the custom code to support our custom EXM requirements. In this project, I’ve started with adding a new Facet class called EmployeeInfo:

using System;
using Sitecore.XConnect;

namespace Aceik.Feature.EXM.Models
{
    public class EmployeeInfo : Facet
    {
        public const string DefaultFacetKey = "EmployeeInfo";
        public string EmployeeId { get; set; }
        public string Department { get; set; }
        public DateTime? StartDate { get; set; }
        public string EmployeeType { get; set; }
    }
}

My EmployeeInfo facet, contains 4 properties that I want to be able to populate for my contacts:

  • EmployeeId
  • Department
  • StartDate
  • EmployeeType

Build a model for your custom Facet

The next thing I need to do is to create an XdbModel for my custom Facet. This is required to be deployed into our XConnect instance and will allow XConnect to know about our custom Facet and be able to store the Facet details for each contact.

using Sitecore.XConnect;
using Sitecore.XConnect.Schema;

namespace Aceik.Feature.EXM.Models
{
    public class EmployeeModel
    {
        public static XdbModel Model { get; } = EmployeeModel.BuildModel();

        private static XdbModel BuildModel()
        {
            XdbModelBuilder modelBuilder = new XdbModelBuilder("EmployeeModel", new XdbModelVersion(1, 0));

            modelBuilder.ReferenceModel(Sitecore.XConnect.Collection.Model.CollectionModel.Model);
            modelBuilder.DefineFacet<Contact, EmployeeInfo>(EmployeeInfo.DefaultFacetKey);

            return modelBuilder.BuildModel();
        }
    }
}

Note: Pay attention to the XdbModelBuilder parameters. This instructs the model with our custom Facet details.

We now need to run a build on our new project in Visual Studio so that the assembly can be generated with our classes.

Serlialize your custom model

XConnect requires a JSON representation of your XdbModel. We will now create a console application that can be used to generated the required JSON file.

First, Add a new project to your solution in Visual Studio, selecting to use the Console App template.

You will need to add a reference to your Feature project into the Console application as well as Nuget reference to the Sitecore.XConnect package.

Update the program.cs file to look like below:

using Sitecore.XConnect.Serialization;
using System.IO;

namespace Aceik.Feature.EXM.Serialize
{
    class Program
    {
        static void Main(string[] args)
        {
            // File name will be "Aceik.Feature.Mail.Models.EmployeeModel, 1.0.json
            var json = XdbModelWriter.Serialize(Models.EmployeeModel.Model);
            File.WriteAllText("Aceik.Feature.EXM.Models." + Models.EmployeeModel.Model.FullName + ".json", json);
        }
    }
}

Build and execute the console application.

As per the code comments, this will generate a file called “Aceik.Feature.Mail.Models.EmployeeModel, 1.0.json”. This will vary based on your custom model name and versioning you assigned in your XdbModel.

Note: If after deploying your model to XConnect, you need to update it, you will need to update the XdbModel version and deploy the updated JSON file before XConnect will recognise the new properties of your custom facet.

Create a custom import mapper

When a contact is imported via CSV, various ImportMapper classes are executed to process the contact and to populate the various Facets with the data from the CSV.

To populate our custom Facet, we need to create our own custom ImportMapper class to do this.

To process the contacts employee fields, I created my custom import mapper class called EmployeeInfoFacetMapper.

using System;
using System.Globalization;
using Sitecore.Diagnostics;
using Sitecore.ListManagement.Import;
using Sitecore.ListManagement.XConnect.Web.Import;
using Sitecore.XConnect;
using Aceik.Feature.EXM.Models;

namespace Aceik.Feature.EXM.Import
{
    public class EmployeeInfoFacetMapper : IFacetMapper
    {
        public EmployeeInfoFacetMapper() : this(EmployeeInfo.DefaultFacetKey)
        {
        }

        public EmployeeInfoFacetMapper(string facetName)
        {
            Assert.ArgumentNotNull(facetName, nameof(facetName));
            this.FacetName = facetName;
        }

        public string FacetName { get; }

        public MappingResult Map(
          string facetKey,
          Facet source,
          ContactMappingInfo mappings,
          string[] data)
        {
            if (facetKey != this.FacetName)
                return new NoMatch(facetKey);

            var facet = source as EmployeeInfo ?? new EmployeeInfo();

            // EmployeeInfo Properties
            facet.EmployeeId = SetTextField(FacetName, mappings, data, "EmployeeId");
            facet.Department = SetTextField(FacetName, mappings, data, "Department");
            facet.StartDate = SetDateTimeField(FacetName, mappings, data, "StartDate", "dd/MM/yyyy");
            facet.EmployeeType = SetTextField(FacetName, mappings, data, "EmployeeType");

            return new FacetMapped(facetKey, facet);
        }

        private string SetTextField(string facetName, ContactMappingInfo mappings, string[] data, string fieldName) => mappings.GetValue($"{facetName}_{fieldName}", data);

        private DateTime? SetDateTimeField(string facetName, ContactMappingInfo mappings, string[] data, string fieldName, string dateFormat)
        {
            DateTime? fieldValue = null;
            var fieldText = mappings.GetValue($"{facetName}_{fieldName}", data);
            DateTime fieldDate;

            if (DateTime.TryParseExact(fieldText, dateFormat, new CultureInfo("en-AU"), DateTimeStyles.None, out fieldDate))
                fieldValue = fieldDate.ToUniversalTime();

            return fieldValue;
        }
    }
}

This class is instantiated for each contact. First, it verifies that the data being passed to it is for the EmployeeInfo facet. Once that is confirmed, it populates the EmployeeInfo facet properties from the CSV data that is passed into it.

As you can see, I’ve used a couple of private methods to extract and set the string and DateTime values passed in.

Notice that when extracting the values from the mappings data passed in, it uses a pattern to extract the data for the correct field: “{facetName}_{fieldName}”. This pattern matches the Import mappings that we will setup in the next step.

Import Mapping Fields

As per Part 2, we need to configure the custom Import Mapping fields. Once again, switch to the Core database in Sitecore and navigate to this path: “/sitecore/client/Applications/List Manager/Dialogs/ImportWizardDialog/PageSettings/TabControl Parameters/Map/ImportModel”.

Select one of the existing mapping fields and duplicate it giving it a name of “Employee Info – Employee Id”. Populate the FieldName and DataField fields as per below. Note that the DataField value is the value used in the Import Mapper classes to identify the field so these need to be carefully assigned to match your custom Import Mapper class.

Do the same 3 more times to create the custom import mapping fields for:

  • Employee Info – Department
  • Employee Info – Start Date
  • Employee Info – Employee Type

Create the Sitecore configuration

In your project, you will need to create configuration files for the following purposes:

  • Patch the ListManagement.Import.FacetsToMap setting so that it includes your custom Facet name
  • Add your custom FacetMapper to the list of Import Facet Mappers defined in Sitecore
  • Add your schema to the list of schemas defined for XConnect
  • Add your projects path to the Layer configuration so that your configuration files are recognized

In my EXM Helix project, I’ve added the following configuration files:

  • ListManagement.config
  • sc.Aceik.Feature.EXM.Models.EmployeeModel.xml
  • Layers.config
ListManagement.config
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/">
  <sitecore>
    <settings>
      <setting name="ListManagement.Import.FacetsToMap" set:value="Emails|Personal|Addresses|EmployeeInfo" />
    </settings>

    <import>
      <facetMapper type="Sitecore.ListManagement.XConnect.Web.Import.CompositeFacetMapperCollection, Sitecore.ListManagement.XConnect.Web">
        <param resolve="true" type="Sitecore.Abstractions.BaseLog, Sitecore.Kernel"/>
        <facetMappers hint="list:Add">
          <facetMapper type="Aceik.Feature.EXM.Import.EmployeeInfoFacetMapper, Aceik.Feature.EXM" />
        </facetMappers>
      </facetMapper>
    </import>

    <xconnect>
      <runtime type="Sitecore.XConnect.Client.Configuration.RuntimeModelConfiguration,Sitecore.XConnect.Client.Configuration">
        <schemas hint="list:AddModelConfiguration">
          <!-- value of 'name' property must be unique -->
          <schema name="employeemodel" type="Sitecore.XConnect.Client.Configuration.StaticModelConfiguration,Sitecore.XConnect.Client.Configuration" patch:after="schema[@name='collectionmodel']">
            <param desc="modeltype">Aceik.Feature.EXM.Models.EmployeeModel, Aceik.Feature.EXM</param>
          </schema>
        </schemas>
      </runtime>
    </xconnect>

  </sitecore>
</configuration>
sc.Aceik.Feature.EXM.Models.EmployeeModel.xml
<?xml version="1.0" encoding="utf-8"?>
<Settings>
  <Sitecore>
    <XConnect>
      <Services>
        <XConnect.Client.Configuration>
          <Options>
            <Models>
              <EmployeeModel>
                <TypeName>Aceik.Feature.EXM.Models.EmployeeModel, Aceik.Feature.EXM</TypeName>
                <PropertyName>Model</PropertyName>
              </EmployeeModel>
            </Models>
          </Options>
        </XConnect.Client.Configuration>
      </Services>
    </XConnect>
  </Sitecore>
</Settings>
Layers.config
<?xml version="1.0" encoding="utf-8"?>
<layers>
  <layer name="Sitecore" includeFolder="/App_Config/Sitecore/">
    <loadOrder>
      <add path="ContentSearch.Azure" type="Folder" />
      <add path="Reporting" type="Folder" />
      <add path="Marketing.Xdb.Sql.Common" type="Folder" />
      <add path="CMS.Core" type="Folder" />
      <add path="AntiCSRFModule" type="Folder" />
      <add path="Contact.Enrichment.Services.Client" type="Folder" />
      <add path="ContentSearch" type="Folder" />
      <add path="Buckets" type="Folder" />
      <add path="DeviceDetection.Client" type="Folder" />
      <add path="DetectionServices.Location" type="Folder" />
      <add path="ItemWebApi" type="Folder" />
      <add path="Owin.Authentication" type="Folder" />
      <add path="Owin.Authentication.IdentityServer" type="Folder" />
      <add path="TransientFaultHandling" type="Folder" />
      <add path="Messaging" type="Folder" />
      <add path="Processing.Tasks.Messaging.Xmgmt" type="Folder" />
      <add path="Update" type="Folder" />
      <add path="XConnect.Client.Configuration" type="Folder" />
      <add path="Marketing.Xdb.MarketingAutomation.Operations" type="Folder" />
      <add path="Marketing.Xdb.MarketingAutomation.Reporting" type="Folder" />
      <add path="Marketing.Xdb.ReferenceData.Core" type="Folder" />
      <add path="Marketing.Xdb.ReferenceData.Client" type="Folder" />
      <add path="Marketing.Operations.xMgmt" type="Folder" />
      <add path="Marketing.Segmentation.xMgmt" type="Folder" />
      <add path="Marketing.Xdb.MarketingAutomation.Locators" type="Folder" />
      <add path="Marketing.Xdb.ReferenceData.Service" type="Folder" />
      <add path="Marketing.Xdb.ReferenceData.SqlServer" type="Folder" />
      <add path="Marketing.Operations.Xdb.ReferenceData" type="Folder" />
      <add path="Marketing.xDB" type="Folder" />
      <add path="Mvc" type="Folder" />
      <add path="Services.Client" type="Folder" />
      <add path="ExperienceContentManagement.Administration" type="Folder" />
      <add path="Speak.Integration" type="Folder" />
      <add path="Marketing.Tracking" type="Folder" />
      <add path="Tracking.Web.MVC" type="Folder" />
      <add path="Tracking.Web.RobotDetection" type="Folder" />
      <add path="Marketing.Assets" type="Folder" />
      <add path="Marketing.Xdb.MarketingAutomation.Tracking" type="Folder" />
      <add path="SPEAK" type="Folder" />
      <add path="Speak.Applications" type="Folder" />
      <add path="LaunchPad" type="Folder" />
      <add path="Experience Editor" type="Folder" />
      <add path="ContentTagging" type="Folder" />
      <add path="ListManagement" type="Folder" />
      <add path="Marketing.Client" type="Folder" />
      <add path="MVC.ExperienceEditor" type="Folder" />
      <add path="MVC.DeviceSimulator" type="Folder" />
      <add path="Personalization" type="Folder" />
      <add path="ContentTesting" type="Folder" />
      <add path="ExperienceProfile" type="Folder" />
      <add path="ExperienceExplorer" type="Folder" />
      <add path="SPEAK.Components" type="Folder" />
      <add path="ExperienceAnalytics" type="Folder" />
      <add path="CampaignCreator" type="Folder" />
      <add path="ExperienceForms" type="Folder" />
      <add path="ExperienceForms" type="Folder" />
      <add path="FederatedExperienceManager" type="Folder" />
      <add path="Marketing.Automation.Client" type="Folder" />
      <add path="Marketing.Automation.ActivityDescriptors.Client" type="Folder" />
      <add path="EmailExperience" type="Folder" />
      <add path="PathAnalyzer" type="Folder" />
      <add path="UpdateCenter" type="Folder" />
    </loadOrder>
  </layer>
  <layer name="Modules" includeFolder="/App_Config/Modules/" />
  <layer name="Custom" includeFolder="/App_Config/Include/">
    <loadOrder>
      <add path="Foundation" type="Folder" />
      <add path="Feature" type="Folder" />
      <add path="Project" type="Folder" />
    </loadOrder>
  </layer>

  <layer name="Aceik" includeFolder="/App_Config/Aceik/">
    <loadOrder>
      <add path="Foundation" type="Folder" />
      <add path="Feature" type="Folder" />
      <add path="Project" type="Folder" />
    </loadOrder>
  </layer>

  <layer name="Environment" includeFolder="/App_Config/Environment/" />
</layers>

Deploy to Sitecore and XConnect

Deploy the EXM helix project to Sitecore using your usual method. In my case, I used the publish option in Visual Studio and deployed the files to the website folder for my Sitecore instance.

To deploy the files to XConnect, this was not so simple. I manually deployed the following files to these locations in my XConnect instance:

  • sc.Aceik.Feature.EXM.Models.EmployeeModel.xml => \App_Data\jobs\continuous\AutomationEngine\App_Data\Config\sitecore
  • Aceik.Feature.EXM.dll => \App_Data\jobs\continuous\AutomationEngine
  • Aceik.Feature.EXM.Models.EmployeeModel, 1.0.json => \App_Data\Models

After deploying the files to XConnect, you will need to go and restart the XConnect services:

  • Marketing Automation Service
  • Processing Engine Service
  • Index Worker

Test the Import

Now that you have deployed the code and configuration changes to both Sitecore and XConnect, applied the Import Mapper configuration changes, you can now import your “Employees” from a CSV file. I have amended the CSV used in the Part 2 adding in the additional Employee specific columns:

email, firstname, middlename, lastname, gender, jobtitle, address1, address2, city, postcode, state, country,Employee ID,Department,Start Date,Employee Type
alberte@gmail.com,Albert,Basil,Einstein,Male,Scientist,Level 12,100 New York Lane, New York,25438, NY, US,FT0195,Science,23/01/1869,Fulltime
blaise@gmail.com,Blaise,Patricia,Pascal,Male,Mathematician,125 The Pond,,Paris,7321AE,PA, FR,CA0125,Mathematics,08/10/1915,Casual
cherschel@yahoo.com,Caroline,Jenny,Herschel,Female,Astronomer,34 The Strait,,Hanover,123BCF,Lower Saxony, DE,PT4567,Astronomy,05/05/1979,Permament Part-time
dorothyhodgkin@live.com,Dorothy,Anne,Hodgkin,Female,Chemist,87 Downing Street,,Westminister,SW1A,London,UK,FT0099,Science,13/08/1940,Fulltime
edmond145@facebook.com,Edmond,William,Halley,Male,Astronomer,114 ChittingHam Way,,Greenwich,SW1A,Kent,UK,CA0087,Astronomy,01/10/1985,Casual

I then imported these “Employees” using the same process as previously, with the only difference being that I now mapped the additional Employee fields.

Import from CSV file
Imported Employees

As you can see the Employees imported in the same manner as previously. Now, when I open the details of one of the Employees, I see no difference to before.

Contact Details

In the last and final part of this series, I’ll show you how to update the Experience Profile with a new Tab that you can use to display your custom Facet details. Click here for Part 4.

Sitecore Email Experience Manager (EXM), Importing Contacts and Custom Facets – Part 2

In Sitecore Email Experience Manager (EXM), Importing Contacts and Custom Facets – Part 1, I showed you how you can import contacts from a CSV file into a list in Sitecore EXM. Head over to Part 1 if you haven’t read that one as yet.

The properties of a contact that we are able to populate out-of-the-box are configured to the following fields:

  • Email
  • First name
  • Last name

Sitecore can be configured to support importing additional properties. In this article, I will show you how to update the configuration to support importing additional contact properties such as:

  • Middle name
  • Gender
  • Job Title
  • Address

Configure the Import Model

We need to first update the configuration of the import model. The import model is used to define the list of mapping fields that are displayed in the Contact Import dialog.

Start by launching the Sitecore Desktop from the Sitecore Launchpad. From there click on the master database in the lower right hand corner and select “core”. This switches the context to the core database. You can now launch the Content Editor by clicking on the Sitecore start button and selecting “Content Editor”.

Launch Sitecore Desktop
Switch to the Core database
Launch the Content Editor

In the Content Editor, navigate to the following path:

/sitecore/client/Applications/List Manager/Dialogs/ImportWizardDialog/PageSettings/TabControl Parameters/Map/ImportModel

Here you will see the list of configured field mappings. Will we now add to the list of field mappings by using the predefined available list of additional fields. Rich-Click on the “Import Model” node and using the Insert submenu, choose to add the following additional fields:

  • Personal – Middle name
  • Personal – Gender
  • Personal – Job title
  • Preferred Address – Address Line 1
  • Preferred Address – Address Line 2
  • Preferred Address – City
  • Preferred Address – Postal code
  • Preferred Address – State or Province
  • Preferred Address – Country code

The ordering of the fields is not mandatory but it’s worth putting into a logical order as this will be the order they are displayed in, in the contact import dialog.

Updated Import Model configuration

Now, go through the same process to create a new list and import the contacts from a CSV file. This time, when you reach the step of mapping the fields, you will notice there is additional fields to map. They are the new fields we just added to the Import Model is the previous step. Complete the mapping and the import as you did in the previous article.

Updated list of mapping fields
Updated list of mapping fields
Updated list of mapping fields

Now, when you open one of the imported contacts in Experience Profile, you will see the additional properties that have been imported:

Newly populated fields from the updated Import Model

In the Sitecore Email Experience Manager (EXM), Importing Contacts and Custom Facets – Part 3, I will show you how to add custom properties to a Contact and have those properties populated via the Contact Import process.

Sitecore Email Experience Manager (EXM), Importing Contacts and Custom Facets – Part 1

Are you a Sitecore developer looking to import contacts into Sitecore? Do you need to store properties for your contacts that are not supported out of the box by Sitecore?

In this multi-part series of posts, I will show you how you can import your contacts from a text file. I’ll show you how you can update the out of the box configuration to include importing other standard properties for your contacts. I’ll also show you how you can add your own custom properties for your contacts. And lastly, I’ll show you how you can update the Experience Profile UI so that your custom properties can be displayed for your contacts.

Contacts and Lists

Sitecore EXM supports the concept of both Contacts and Lists.

A contact itself is pretty self-explanatory and contains all the properties for the contact. Here are some of examples of the properties stored for a contact:

  • Email addresses
  • First, middle and last names
  • Gender
  • Birthday
  • Addresses
  • Job title

A list is simply a collection of contacts. A contact can be a member or a subscriber to multiple lists. Lists can be either static (a contact has been added to the list) or a list can be dynamic. Dynamic lists are populated based on a set of rules that uses the contact properties to determine if they should be a member of the list.

Importing Contacts

Out-of-the-box, Sitecore supports importing contacts from a CSV file. Your list of contacts to be imported need to have a minimum of the following fields:

  • Email address
  • First name
  • Last name

Sample CSV file

email, firstname, lastname
alberte@gmail.com,Albert,Einstein
blaise@gmail.com,Blaise,Pascal
cherschel@yahoo.com,Caroline,Herschel
dorothyhodgkin@live.com,Dorothy,Hodgkin
edmond145@facebook.com,Edmond,Halley

To import the contacts, go to the Sitecore Launchpad and click List Manager.

Once you are in the List Manager, follow these steps to import your contact list:

  • Click on the “Create” button
  • Select “Create list from file”
  • Click on the “Browse for a CSV file” button and select your csv file containing your contacts. Note: Make sure your file is named with a .csv extension
  • Enter a name for your list
  • Click on the “Upload file” button
Create a new list
Create the new list from a CSV file
Give your new list a name and upload the CSV file

Once the file has been uploaded, the process will prompt you to choose the mappings between the predefined Contact properties and the columns in your CSV file. If your CSV file contains columns you would like to use for the contact identifier and/or the identifier source, you can optionally check those and then be able to select the column mappings for those Contact properties.

Click “Next” to being the import process.

Nominate the field mappings

Once the import process has been completed, you will be shown a summary of what has been imported. When you click on the finish button, you will then be taken to your list that you have just imported. Here you can see the contacts that have been added to your new list.

Import Summary
Newly created list

You can also view the contact details by navigating back to the Sitecore Launchpad and launching the Experience Profile. There you can see the entire list of contacts. You can click into any of the contacts to see the details of the contact.

Experience Profile showing all your contacts
Contact details

There are additional properties that are shown in the experience profile that we can also populate via the CSV import process. To do that, we will need to customise the list of available properties that the importer allows to be mapped to.

In Sitecore Email Experience Manager (EXM), Importing Contacts and Custom Facets – Part 2, I will show you how you can customise that list of fields and import additional standard properties for each contact.

Aceik & Sitecore’s Digital Wine-Down

Last week, Aceik and Sitecore brought together 16 digital experts from around Australia to discuss digital transformation – the trends, challenges and risks facing a new project in 2021. And it wouldn’t be a robust discussion without a wine tasting – kindly delivered by SocialTable and Price’s Wines.

Our moderator introduced two topics then guests were divided into groups of 6 to discuss. Upon return to the main track, guests then shared their unique discussion. And today, we wanted to share the key highlights.

Question 1

What are the biggest factors you think will influence investment and digital transformation over the next 12 months?

  • Customer-driven service channel
  • Being reactive to competitor demand
  • We’re not competing with competitors anymore, we’re competing with the most recent best experience the customer has had, and that’s the new benchmark
  • Depending on which industry the impact of COVID-19 varied (ie retail saw loads of money move into their ecommerce stores)
  • COVID-19 made getting sign-off easier on digital projects. Because digital was pretty much the only active channel
  • Increased emphasis on ROI now
  • Public sector using data in marketing campaigns
  • Coming out of COVID-19 lockdowns might be the perfect time to be disruptive

Question 2

What do you think are the biggest risks or pain points that companies aren’t aware of when embarking on a digital transformation project.

  • Budget 😊
  • Ensuring exec team is along on the journey
  • Lack of understanding of what digital transformation means
  • Finding the right agency to work with and trust
  • Exec team churn.
  • Getting staff buy in early
  • Ongoing costs of systems implementations not considered
  • Silo’d environments
  • Staff can be resistant
  • Defining success criteria
  • Lack of a clear project leader
  • Failing to train!

It was a fantastic event and we really appreciate the open sharing amongst the group!

Aceik – 2021 The Circle Back Initiative Employer

At Aceik, we believe candidate experience is all about being courteous and respectful, and we understand the time and effort that goes into every job application and recruitment process. We are pleased to announce that we are now a 2021 Circle Back Initiative Employer – we commit to respond to every applicant.

The Circle Back Initiative has been created by Talentrich to improve the experience candidates receive after submitting a job application. The initiative is a collection of Employers who commit to guiding standards on candidate communication. Initiative champions agree to respond to every applicant.

What does the candidate experience look like?

Once submitting your resume or responding to a job ad, any job candidate of Aceik can expect:

  • Aceik responds to each job candidate’s appliation with an ‘application received’.
  • Each application will be reviewed by Aceik and a shortlist of suitable candidates will be compiled and discussed internally.
  • If selection criteria is met, a candidate will receive a phone call to run through their application and experience in a little more detail.
  • Candidates not suitable for the role are advised as early in the process as possible.
  • Aceik aims to shortlist a role within 2 week of posting a vacancy.
  • A selected number of candidates are chosen to be invited to interview.
  • Interviews are conducted via video chat (presently).
  • If a suitable candidate is not identified during the interview stage, the shortlist may be revisited. Due to this, candidates on the shortlist may not be notified if they did not make the first round of interviews.
  • If necessary, second round of interviews take place.
  • Any testing or assessment takes place with preferred candidate/s.
  • Once a suitable candidate has been identified, reference checks are conducted and for some roles, Aceik also requires a police check.
  • Once the above assessments come back as successful, Aceik offers the preferred candidate the position.
  • Aceik responds to all candidates that have applied for the position, and provides feedback where possible.

Want to join the Aceik team?

Are you a digital enthusiast looking to work with a team that pushes the boundaries of technology? Email careers@aceik.com.au to tell us what you could bring to the Aceik crew or check out our available roles.

Six Aceik Team Members Named Sitecore Most Valuable Professional

Aceik today announced that an unprecedented six of its team members have been named a 2021 Most Valuable Professional (MVP) by Sitecore®, the global leader in digital experience management software. Our leader and team members, Jason Horne, Thomas Tyack, David (Danny) Newman, Jitendra Soni, David Goosem and Praveen Manchana are being honored among only 24 MVPs across Australia in the program’s 15th year.

Recognising professionals who deliver outstanding customer experiences through shared expertise on Sitecore’s products, the 2021 MVP program draws from a community of 12,000 certified developers and over 20,000 active participants. This year’s worldwide pool of 284 MVPs contributed invaluable knowledge to the community in 2020 and demonstrated true mastery of the Sitecore platform to support partners, customers and prospects.

“It’s an honour for one individual to be recognised for their community contribution, but to know we have six MVPs on our team is outstanding. This MVP designation recognises the unique skills, expertise and success that Tom, Danny, Jitendra, David and Praveen, alongside their colleagues brings to our customers’ digital experience every day,” said Jason Horne, CEO, Aceik.

About the Sitecore MVPs on the Aceik team

Jason Horne, CEO

From Jason’s initial experience of working with Sitecore 5.3 all the way back in 2008, he set out to become a Sitecore Specialist.

In 2014, Jason launched Aceik, a Sitecore specialist consultancy. And he followed this up with the launch of the Sitecore Melbourne Meetup community. His aim has been to provide an environment in which the Aceik team has the skills, tools, relationships, clients, and freedom to deliver the highest level of quality solutions in the Sitecore space.

Thomas Tyack, Chief Technical Architect

Thomas has been working with Sitecore since early 2009 and excitingly for Aceik, this is his third consecutive year as a Sitecore MVP-Technology.

Tom has his hand in many Sitecore pies including regular updates to the Sitecore Speedy module, sharing Sitecore hints through his blog and at meetups and creating a 6 Pillars of Page Speed video series (to name just a few of his contributions in the past 12 months). He also co-founded the AU Sitecore Slack workspace, a forum for Australian based developers to keep in touch.

David (Danny) Newman, Training Manager

Danny spent 8 years at Sitecore teaching developers, marketers and authors to create outstanding digital customer experiences using the Sitecore platform.

In 2019, Danny brought those skills to Aceik where he combined his Sitecore knowledge with Aceik’s practical experience to deliver a balanced Sitecore training program. Danny now provides complimentary training webinars to the Sitecore community.

Jitendra Soni, Sitecore Tech Lead

Jitendra’s very first Sitecore project was a jewellery channel in the UK all the way back in 2013. Since then, he’s delivered many Sitecore projects, including Mondelez International, Invista Group, Dentos Global USA, Manchester United, Bunnings, Bridgestone and RACQ.

Jitendra is an avid blogger on all things Sitecore.

David Goosem, Solution Architect

David has more than 10 years’ experience working both client-side and within agencies as a Sitecore developer, a role in which he delivered exceptional Sitecore websites and customer journeys. His first implementation was on Sitecore 6.4, when he became hooked on the platform’s potential and he has since worked on projects for RACQ, QSuper, RTA, ForceNet, Motorama, Endeavour Foundation and RSL Art Union.

Aside from contributing to SUGCON, David is an avid blogger on all things Sitecore as well as an active member of the Brisbane Sitecore community.

Praveen Manchana, Solution Architect

Praveen started working with Sitecore five years ago, and his first project focused on ecommerce. He considers himself privileged to spend time at Bunnings working on their Homebase project, including Click & Collect. From there, he worked with a couple of different Sitecore partners on other ecommerce projects, including Baby Bunting and Bridgestone.

Praveen has contributed many modules to the Sitecore open source community including Commerce Automation, Promotions Search on 9.2 and Sitecore Commerce 10 with SXA Storefront in Docker for Development.

When he’s not implementing or building on Sitecore, you can find him presenting at local Meetups and webinars.

“The 2021 Sitecore MVPs consist of stellar individuals who demonstrated incredible commitment to the Sitecore community during a challenging year which didn’t allow for in-person engagement,” said Tom De Ridder, CTO of Sitecore. “The 284 MVPs stepped up to the plate to bring critical knowledge and insights for the greater community through virtual channels. We are especially pleased to celebrate this group in the program’s 15th year.”

In recent months, Sitecore recognised Aceik’s success and expertise by naming the organization a Platinum partner, the highest-ranking tier of partner status in the Sitecore network and rewarded Aceik a Sitecore Experience Award Honorable Mention for its work with RAA.

More information can be found about the MVP Program on the Sitecore MVP site: http://mvp.sitecore.com.

People of Aceik: Praveen Manchana, Architect

Last year, we launched a new series to introduce you to our talented and hard working team mates. They’re behind the success of our client’s projects – working diligently to ensure we exceed our customers’ expectations.

This month, we sat down with our Architect and ecommerce expert, Praveen Manchana.



Praveen, tell us a bit about yourself.

Praveen: In terms of my background, I have been working with Microsoft Technologies for close to fifteen years now. I started as a junior developer at Dodo and from there I worked in a variety of roles across different technologies for roughly 9 years before moving onto Sitecore.

I started working with Sitecore five years ago, and my first project focused on ecommerce. I was privileged to spend time at Bunnings working on their Homebase project, including Click & Collect. From there, I worked with a couple of different Sitecore partners on other ecommerce projects, including Baby Bunting and Bridgestone.

After Bunnings, I joined another Sitecore partner for a time, where I worked on the Baby Bunting project. Again, this had a Sitecore commerce focus.

And eventually I landed at Aceik. I’ve been here a little over a year now.

You’ve spent a lot of time working on commerce projects. What do you love about it? Why the focus on Sitecore commerce?

Praveen: I have been with working with Microsoft technologies for fifteen years and to customize or add changes is a lot easier. It is a technology that I am really familiar with and it is easy to get into and learn about it. Extensibility is really good. You can achieve those customizations a lot easier, faster and cheaper using Sitecore commerce than other technologies.

Tell us about why did you decide to join Aceik.

Praveen: At the time I joined Aceik, it was really small. I wanted to be part of that growth journey. I wanted the opportunity to invest my time and energy into growing Aceik.

What are you working on at the moment?

Praveen: I’ve spent the last 9 or so months working on RACQ – trying to stabilise the environment and also working on compliance changes. Excitingly, I’m now getting involved in their rebuild project including shifting to the latest version of Sitecore.

I have seen your “deploying Sitecore on Kubernetes” blog posts and obviously, a meetup group covered the same topic not long ago. Why are you interested in that particular aspect of Sitecore?

Praveen: Sitecore had never supported containers for production use in the past. With the recent launch of Sitecore 10, they officially started supporting containers. If you run into problems and if you raise a support ticket, Sitecore will help us now. With Sitecore moving towards containers and Kubernetes, if we did not move along, we will be left behind.

Tell us about yourself outside of Aceik hours.

Praveen: Most of my time outside of work is catching up with family and friends. I love my barbecues by the way. I probably go through like two or three gas bottles every summer.

I found this really nice Middle Eastern recipe for chicken kebabs. I love it. All my friends and family, they love that as well. So, every time I am doing a barbecue they go, “Okay, make sure you do that.”

If someone wants to develop a career and follow in a similar set of footsteps as yourself, what advice or tips would you have for them?

Praveen: Set goals clearly and early. At the beginning of my career, I did not set my goals properly. I did not know what I wanted to do and I was not clear, but I think it is often the case with most of the developers. At the start of your career, you feel confused. You do not know what you want to get into. You do not know what your passion is. But as you work through a few years into your career, you will understand where your interest lies and you have to make sure that you steer in that direction. I definitely did that. I like technical things and I always made sure throughout my career when went into different roles they are all tech focused. I went into a tech lead role, but even then, I was hands on and never moved away from coding because I like it. If I was not coding, I would probably get bored.