Contents

Build a custom channel for Dynamics 365 for marketing

I recently had a requirement from a customer to track additional activities with their customers, but beyond the normal marketing activities. The customer have a mobile application and would like to track if they email a contact a mobile market place link, if they installed the mobile application or not.

I played around with marketing’s customer journey capabilities and there’s some really awesome functionality included. I decided to create a custom channel for two reasons..

  1. Cause I just didn’t know how
  2. Whenever something needs to be send in bulk (like sms) architects tend to write a bunch of plugins and code to achieve this.

The documentation contains a lot of information on how to develop a custom channel. You basically only need two files. a config xml file where you will define your custom entitiy, compliance field and response types

<?xml version="1.0" encoding="utf-8"?>
<!-- file name should only contain alpha-numeric characters and underscore -->
<!-- format: <fileNamePrefix>CustomerJourneyDesignerTileConfig.xml> -->
<LibraryTile>
  <!-- mandatory -->
  <!-- icon: CSS class defining your tile icon-->
  <!-- fontFamily: CSS class defining font-family for your icon-->
  <!-- cssFileName: your CSS file name in CRM-->
  <Definition icon="cod_AppStoreTitle" fontFamily="cod_AppStoreTitleSymbolFont" cssFileName="cod_AppstoreCustomerJourneyDesignerTileConfig.css" />
  <!-- mandatory -->
  <ChannelProperties>
    <!-- mandatory -->
    <EntityType>cod_marketplacetemplate</EntityType>
    <EntitySetName>cod_marketplacetemplates</EntitySetName>
    <TitleFieldName>cod_name</TitleFieldName>
    <ComplianceField>cod_donotmarketplace</ComplianceField>
    <!-- optional -->
    <!-- Lookup view id for your entity-->
    <LookupViewId>33BDD9CE-E17E-4437-B0B1-4661E8C8A553</LookupViewId>
      <!--Quick view form id for your entity -->
    <QuickViewFormId>CBE4E13B-8723-48B1-91E7-23CCCE0ED47C</QuickViewFormId>
  </ChannelProperties>
  <!-- optional -->
  <ResponseTypes>
    <ResponseType id="sent">
      <Labels>
        <!-- Labels should always have a Label for 1033 -->
        <Label locId="1033">Sent</Label>
        <Label locId="1031">[Sent]</Label>
      </Labels>
    </ResponseType>
    <ResponseType id="delivered">
      <Labels>
        <!-- Labels should always have a Label for 1033 -->
        <Label locId="1033">Delivered</Label>
        <Label locId="1031">[Delivered]</Label>
      </Labels>
    </ResponseType>
    <ResponseType id="keyword" custom="True">
      <!-- there should be only one response type with attribute custom=true -->
      <Labels>
        <!-- Labels should always have a Label for 1033 -->
        <Label locId="1033">Keyword match</Label>
        <Label locId="1031">[Keyword match]</Label>
      </Labels>
    </ResponseType>
  </ResponseTypes>
  <!-- mandatory -->
  <Labels>
    <!-- Labels should always have a Label for 1033 -->
    <Label locId="1033">Appstore Link Provider</Label>
    <Label locId="1031">[Appstore Link Provider]</Label>
  </Labels>
  <!-- mandatory -->
  <Tooltips>
    <!-- Tooltips should always have a tooltip for 1033 -->
    <!-- mandatory -->
    <Tooltip locId="1033">Send Appstore link</Tooltip>
    <!-- optional -->
    <Tooltip locId="1031">[Send Appstore link]</Tooltip>
  </Tooltips>
</LibraryTile>

some of the important things to remember :

  1. The compliance field determines if the user opt-in or opt-out for communication
  2. The file is case sensitive
  3. Lookup view and quickview id’s will be used to retrieve records and display data in the customer journey
  4. You upload both files as web resources in Dynamics
  5. For each custom channel interaction a record will be created, the custom channel’s are not as optimised as the out of the box functions like mail
  6. It is recomended to create a record within Dynamics and offload the record to a service bus, or have a polling service pick up and proccess the newly created records

Get started

First step is to edit the current contact entity and add your consent field.

The next step is to create your custom entity that will be used as the custom channel record. In my case it is called cod_marketplacetemplate.

Create a new xml file in your favourite editor. Visual Studio code works great for editing the xml files. You will need to use the template from the docs site and change the properties to reflect your entitiy changes. You will also need to update the css file and set icons, colors etc. Something to mention here, you can make use of embeded images in the .cod_AppStoreTitle::before css element

.cod_AppStoreTitle::before {
      content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEZSURBVEhL7ZOxTgJBEIb/vSOBziOhELDQN/AhLHwIC+lMfB4SEkigw8LGJ9DCxBegtDgKjIXBiyGRAm74N0yBcrcbcqG7L5nsv//c7d7OzqGkpDBGRy+tb1wGBqdpikoa4LN6gsnUYKnpYrQSXDGe2wnEBvVbe44bTTsJdMxHUDGCMY8aqWO9hgToN3/QUCcXZ4nOElyvgK8QuFfrD2ugGwrOZ3U8qrWHcwOW4pcPPFDebp1/GPR4mrtZlL+Os0R8q6YyG/Hkif8OCuLbIBYgUb2PYOrME+cGrO0FO+hJp1m8fESoq87EW6I0xIRfOdDpq4ZlxDZ6V52Ls4t2sT+YCDpWG4Ohq3N2OeSSY664YMTUi61VUnJ8gA3PTkRUmF36nwAAAABJRU5ErkJggg==');
}

Lastly upload the two files as web resources in your Dynamics solution.

Configure Dynamics Marketing to use your custom channel

You will be all set now, and your custom channel should show up in the customer journey.

You are basically done, easy right? For each execution of the custom channel, Dynamics marketing will create a custom channel activity record, this will contain the informaiton about the channel, the customer journey and the entity type.

You can now use PowerAutomate / plugins to execute on the creation of the record, to create your instance of the record.

Adding custom channel activities to a contact timeline

In order to have the custom channel activity display as an interaction on the contact record, you would need to call the msdyncrm_CustomChannelActivityCreateInteraction action.

I’ve created a simple workflow that calls the action and creates the interaction.

This solution works great if you need to build a custom communication channel like SMS or even a generic way to fire off a bunch of flows.. that can integrate into a bunch of other communcation channels. Be sure to use the execute batch operation to update multiple records in a single api call.