Sitecore 9 Dynamic CRM Connector: Custom pipeline to filter contacts (Part 4)
Part 3: Sitecore 9 Dynamic CRM Connector: Sync Known contacts (Part 3)
As per my requirement, I had multiple Sitecore 9 Forms, in each form I am saving contacts in xDB but I want to sync contacts to CRM which is submitted by a specific form.To fulfil this requirement, I have created custom model & facet and according to custom facets, I have applied logic that only those contact will be sync which contact has the custom model. Also, I have created a pipeline to get the required properties.
As per my requirement, I had multiple Sitecore 9 Forms, in each form I am saving contacts in xDB but I want to sync contacts to CRM which is submitted by a specific form.To fulfil this requirement, I have created custom model & facet and according to custom facets, I have applied logic that only those contact will be sync which contact has the custom model. Also, I have created a pipeline to get the required properties.
Step 1: Create custom pipeline template
- Navigate to this location “/sitecore/templates/Data Exchange/Framework/Pipeline Steps” and create new template
o
Template :/sitecore/templates/Data Exchange/Framework/Pipeline
Steps/Base Pipeline Steps/Base Pipeline Step
o
Item Name: Custom Filter Pipeline Step
- Add IterableDataLocation field:
o
Name: IterableDataLocation
o
Type: DropLink
o
ID: {DD61BBDB-CF41-40F6-9923-3031C7AB47C8}
o
Shared: true
- Add DataLocation field:
o
Name: DataLocation
o
Type: DropLink
o
ID: {DD61BBDB-CF41-40F6-9923-3031C7AB47C8}
o Shared: true- Add ContactFacetsToRead field:
o
Name: ContactFacetsToRead
o
Type: DropTree
o
ID: {D6E7B01E-9E17-4237-AEE9-05EBFD1DF9D2}
o
Shared: true
- In standard value select below default values:
Step 2: Create custom plugin
- Navigate to Visual studio and create custom class “ReadFacetSettings”
using Sitecore.DataExchange;
namespace Namespace.Plugins
{
public class ReadFacetSettings : IPlugin
{
public string FacetNames
{
get;
set;
}
}
}
Step 3: Create custom processor “CustomFilterPipelineStepConverter”
using Sitecore.DataExchange.Attributes;
using Sitecore.DataExchange.Converters.PipelineSteps;
using Sitecore.DataExchange.Models;
using Sitecore.DataExchange.Plugins;
using Sitecore.DataExchange.Repositories;
using Sitecore.Foundation.Forms.Custom.Pipelines.Plugins;
using Sitecore.Services.Core.Model;
using System;
using System.Collections.Generic;
namespace Namespace.Converters
{
[SupportedIds(new string[]
{
"TemplateID"
})]
public class CustomFilterPipelineStepConverter : BasePipelineStepConverter
{
public CustomFilterPipelineStepConverter(IItemModelRepository repository) : base(repository)
{
}
protected override void AddPlugins(ItemModel source, PipelineStep pipelineStep)
{
this.AddDataLocationSettingsPlugin(source, pipelineStep);
this.AddReadEntitySettings(source, pipelineStep);
}
private void AddDataLocationSettingsPlugin(ItemModel source, PipelineStep pipelineStep)
{
Guid guidValue = base.GetGuidValue(source, "DataLocation");
Guid guidValue2 = base.GetGuidValue(source, "IterableDataLocation");
pipelineStep.AddPlugin<IterateDataSettings>(new IterateDataSettings
{
DataLocation = guidValue,
IterableDataLocation = guidValue2
});
}
protected virtual void AddReadEntitySettings(ItemModel source, PipelineStep pipelineStep)
{
ReadFacetSettings readEntitySettings = new ReadFacetSettings();
IEnumerable<ItemModel> referencesAsModels = base.GetReferencesAsModels(source, "ContactFacetsToRead");
if (referencesAsModels != null)
{
foreach (ItemModel current in referencesAsModels)
{
string stringValue = base.GetStringValue(current, "FacetName");
readEntitySettings.FacetNames = stringValue;
}
}
pipelineStep.AddPlugin<ReadFacetSettings>(readEntitySettings);
}
}
}
Step 4: Create custom processor “CustomFilterPipelineStepProcessor”
using Sitecore.DataExchange.Attributes;
using Sitecore.DataExchange.Contexts;
using Sitecore.DataExchange.Models;
using Sitecore.DataExchange.Plugins;
using Sitecore.DataExchange.Processors.PipelineSteps;
using Sitecore.DataExchange.Providers.XConnect.Models;
using Sitecore.Foundation.Forms.Custom.Pipelines.Plugins;
using Sitecore.Services.Core.Diagnostics;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Namespace.Processors
{
[RequiredPipelineStepPlugins(new Type[]
{
typeof(PipelinesSettings),
typeof(IterateDataSettings)
})]
public class CustomFilterPipelineStepProcessor : BasePipelineStepProcessor
{
protected override bool CanStartProcessing(PipelineStep pipelineStep, PipelineContext pipelineContext, ILogger logger)
{
if (pipelineStep.GetPlugin<IterateDataSettings>().DataLocation == Guid.Empty)
{
this.Log(new Action<string>(logger.Error), pipelineContext, "No data location is specified.", Array.Empty<string>());
return false;
}
return true;
}
protected override void ProcessPipelineStep(PipelineStep pipelineStep, PipelineContext pipelineContext, ILogger logger)
{
IEnumerable iterableData = this.GetIterableData(pipelineStep, pipelineContext, logger);
if (iterableData == null)
{
this.Log(new Action<string>(logger.Debug), pipelineContext, "Iterable data is null.", Array.Empty<string>());
return;
}
ReadFacetSettings facetPlugin = pipelineStep.GetPlugin<ReadFacetSettings>();
if (facetPlugin == null || facetPlugin.FacetNames==null)
{
this.Log(new Action<string>(logger.Debug), pipelineContext, "Contact Facets To Read is null.", Array.Empty<string>());
return;
}
List<EntityModel> list = iterableData.Cast<EntityModel>().ToList();
List<EntityModel> filterList = new List<EntityModel>();
foreach (var data in list)
{
if (data.Facets.Keys.Any(x => x == facetPlugin.FacetNames))
{
filterList.Add(data);
}
}
IterableDataSettings newPlugin = new IterableDataSettings(filterList);
pipelineContext.AddPlugin<IterableDataSettings>(newPlugin);
}
protected virtual IEnumerable GetIterableData(PipelineStep pipelineStep, PipelineContext pipelineContext, ILogger logger)
{
IterateDataSettings plugin = pipelineStep.GetPlugin<IterateDataSettings>();
return this.GetObjectFromPipelineContext(plugin.IterableDataLocation, pipelineContext, logger) as IEnumerable;
}
}
}
Step 5: Create custom pipeline
- Add the following item.
o
Template: /sitecore/system/Data Exchange/XXX/Pipelines/xConnect
Contacts to Dynamics Sync Pipelines/Read Contacts from xConnect Pipeline/Custom
Filter Pipeline Step
o
Item Name: Custom Filter Pipeline Step
- Navigate to “ContactFacetsToRead” field and select custom facet]
- Update Converter Type and Processor Type field
Step 6: Run Batch
- Now run “xConnect Contacts to Dynamics Sync” batch
Next article will be about "Scheduled Pipeline Batches"
Comments