Get Contacts/Customers Used In A Customer Journey In Dynamics 365 Marketing

This is going to be a very short blog as I am going to just reference my previous blogs to achieve a solution for this.

I have talked about Customer Journey entity in dynamics in a recent post here:  The ‘Mysterious’ Customer Journey Entity In Dynamics 365 Marketing.

By now, we know that it’s not easy or straight forward to get any details from a customer journey from the back-end.

segment1

In a customer journey, customers are not directly added but rather through a “Marketing Segment”. Now we have seen in the blog above on how to get segment details used in the journey. Once we have the segment Id, the next step is to fetch the customers from the segment and for that I have another blog explaining it: Dynamics 365 For Marketing – Retrieve Contacts From A Segment

By doing the above mentioned, you should be able to get all customer that are part of a journey.

I hope this helps.
Cheers!

 

The ‘Mysterious’ Customer Journey Entity In Dynamics 365 Marketing

In today’s blog I am going to be talking about ‘Customer Journey’ entity in dynamics 365 for marketing app or to be specific the ‘Customer Journey Designer’ which looks like below:

customerjourney1

 

I call it ‘Mysterious’ because whatever happens in the journey ‘stays’ in the customer journey. i.e there is no way or its difficult to get the segment/contents being used in it. I am talking about Marketing Email, Marketing Page, Marketing Form etc. The question you might want to ask is why would I need that information? well, because of may be below:

  1. You might have some validations on the content you can use in the customer journey
  2. You might want to retrieve the data for reporting purpose

If you look into the relationships from customer journey to these entities, you wont find anything hence it gets difficult to retrieve these records or perform operations. In short Dynamics 365 Marketing works a little differently then our typical dynamics 365.

Whatever happens inside a customer journey designer sits in a field on this entity named as “msdyncrm_workflowdefintion“. It stores information about content added in this the journey in JSON format. 

customerjourney2

This is how it looks:
customerjourney3

 

Let’s understand what this JSON means:

  1. Each content is stored in a node called “ActivityTypeId“.
  2. The Id of the content is stored in property “Itemid“.
  3. To identify the type of content such as Marketing page form etc. refer to below table because it uses different names to each type of content:

Dynamics Entity Name Internal Name In Customer Journey
Marketing Page LandingPage
Marketing Form MarketingForm
SurveySurvey
Marketing EmailEmail
Marketing Event Event
Marketing SegmentSegment

If you debug and parse this field data into JSON, looks like something below:

customerjourney4

So when you retrieve/query this field, you have to loop through these JSON nodes and do validation using the Guids of these records like in the below example of Javascript:

 var workflowDefintion= formContext.getAttribute("msdyncrm_workflowdefinition").getValue();
 var workflowDefintionData = JSON.parse(workflowDefintion); //Parse it

                    var nodeLength = workflowDefintionData.length;
                    for (var i = 0; i < workflowDefintionData.length; i++) {
                        var node = workflowDefintionData[i];                        
                        /* Check if node is a Marketing page*/                       
                        if (node.ActivityTypeId === "LandingPage" && (i + 1) === nodeLength) {

// Perform Operations here
}

Same way you can do in the code if needed.

I hope this help!

Cheers!

Import Member/Contacts To A Marketing Segment

A segment in 365 for marketing app is an essential feature which lets you create a list of related contacts based on some criteria( similar to advanced find). Later it is used to target customers in a customer journey.

While you can define a criteria/search for contacts and add them in a Dynamic segment, you don’t have this facility in a “Static” Segment because contacts are manually added on a per-contact basis. hence, there should be ability to import these contacts in to a static segment. 

Now, there is no out of the box way I could find by which we can bulk update contacts into a segment, however after doing a bit digging, I found a working custom solution. 

Solution

If you look into segment entity, you will find a mysterious field named “msdyncrm_segmentmemberids” as below:

segment1

This field basically consists of the ids of the contacts in a JSON format prefixed with “crm”:

segment2

Hence, whatever contacts you manually select on the segment comes and sit in this field. So we just need to update this field with ids of the contact we want to include in this segment.

You can update this field either by WebApi or a Plugin. Its upto you how you want to design your solution. In my case I have placed button on the segment form which opens a web resource providing a flexibility to upload an excel/csv file containing these ids of the contacts which you can easily read, prepare the format of the guids(prefix with “crm”) and update using a simple web api request.

 var entity = {};
            var stringIfy = JSON.stringify(Prepared_ContactsArray);
            var entity = {};
            entity.msdyncrm_segmentmemberids = stringIfy;

            var req = new XMLHttpRequest();
            req.open("PATCH", GetGlobalContext().getClientUrl() + "/api/data/v9.1/msdyncrm_segments(" + segmentId + ")", true);
            req.setRequestHeader("OData-MaxVersion", "4.0");
            req.setRequestHeader("OData-Version", "4.0");
            req.setRequestHeader("Accept", "application/json");
            req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
            req.onreadystatechange = function () {
                if (this.readyState === 4) {
                    req.onreadystatechange = null;
                    Xrm.Utility.closeProgressIndicator();
                    if (this.status === 204) {
                        //Success - No Return Data - Do Something
                       
                    } else {
                        //Xrm.Utility.alertDialog(this.statusText);
                    
                    }
                }
            };
            req.send(JSON.stringify(entity));
        }

I hope this helps!

Cheers!

Enable Custom Entities For Marketing Segment Dynamic Query

A segment in 365 for marketing app is an essential feature which lets you create a list of related contacts based on some criteria( similar to advanced find). Later it is used to target customers in a customer journey.

So when you create a new segment you have an option to create it as static or dynamic. A dynamics segment is what lets you add a query to filter contacts.

picture depicts a dynamic segment query designer

However, there is one thing that will bother you which is, it will not let you add a related custom entity to form a query ( click on add group and select union as relationship)

Solution

There is a settings available in Marketing app which will let you enable this feature for any entity in your system. To check this, go to Marketing App — > Settings Section:


Under Marketing Settings, click on advanced settings.
Now click on Customer Insights Sync under marketing setting section which will give you the list of entities on the right side with check boxes.

Enable for the entities which you need and click on publish from the header.

You might see the box is grayed out and you will not have option to enable. To enable the box you need to enable the change tracking on that entity. to do that you have to go to that entity definition and enable change tracking check box. https://docs.microsoft.com/en-us/power-platform/admin/enable-change-tracking-control-data-synchronization

Once published give it some half an hour.

Navigate to your query now and you will be able to add related entities to your query just like advanced find.

I hope this helps!

Plugin on Retrieve Multiple in CRM.

Filtering records using javascript in subgrid or a view is unsupported and doesnt work hence here is how you can/should filter subgrid records using a plugin.

Nishant Rana's Weblog

Recently we had a requirement to filter sub grid on one of the forms. We thought of using Plugin on Retrieve Multiple for this.

Here we were showing Opportunity Sub Grid on Account form.

So we created a view for Opportunity that will be used as Sub Grid. Used it as Related Record Sub Grid so that we can have the GUID of the Account record being passed to the plugin.

The problem we faced à Sorting and Paging stopped working for the Sub Grid.

http://crmtipoftheday.com/2015/10/05/limitations-of-retrieve-plugins/v

Hope it helps..

View original post

Quick Fix : Mandatory Field Error Shows Schema Name Instead Of Display Name

Quick blog on how to fix the error you get when you save a record which has some required fields on the header of the form and CRM shows the schema name instead of display name like below:

1.png

it shows the error which includes specific field logical name instead of display name which might be confusing for user and doesn’t look very much user friendly. In my case its still very much understandable but sometimes people change name on the form and in that case it will be worse situation.

FIX :

All you have to do is put the same field on the form which is there on the header and hide it on the form. Open the form editor > select the section > look for the field and add it. Go to field properties and hide it by unchecking the visible by default box:

1

Save and publish all your changes and now try to save the record:

1.png

I hope this help!

Handle Boolean/Two Option Fields In Scribe Data Migration/Bulk Update

I know many CRM developer get into Data migration or bulk update operation from CRM system to other external/CRM system.

I have gathered few useful tips while dealing with boolean fields as in how to check the value , reverse the value , use nested if with OR & AND conditions etc. I have categorised them into below and provided explanation & solution.

  1. Check Values from Source & Set New Value 

    To check value of a boolean field from source do this and set other value:

    IF(S1=1, 0 , 1)

    (Here i am checking if S1 field value is “1” which is “TRUE” then set the new value to “0” which is “FALSE” otherwise the default will be to “1”.)

  2. Check Combination of boolean fields and Set New Value

    To check the combination of values i.e If a=1, b=0 then set some new value, Do this:

    IF(AND(S1=1, S2=1), 0 , IF(AND(S1=0, S2=0),1 ))

    (here i am checking if S1=1 AND S2=1 then outcome should be “0”.
    please note: you can use “OR” operator as well as per your requirement.)

  3. Check If the value is Null or Any error in retrieving the value and set default value

    You might have to handle null values in the package, to do this:

    IF(ISERROR(S1),TRUE(), FALSE())

    (here I am checking if S1 is null or any error then i am setting the value to TRUE otherwise FALSE.)

    you can also combine this with checking other values to such as if S1 =1 then 1 , S2=0 then 0 & if S2=Null then TRUE().

    IF(ISERROR(S1),TRUE(),IF(OR(S1 =1 ), 0,IF(OR(S1=0),1)))



    I hope this helps! I will try post help blog on other types of fields.
    cheers!

Solution Import Error 0x80044150 – Object reference not set to an instance of an object.

Issue:

While importing a solution I got a generic SQL error but when i downloaded the log file i saw below error:

import error1

0x80044150 – Object reference not set to an instance of an object 

I have seen this error in plugins several times but never in import but root cause and underlying issue remains the same.

The import was trying to find something which was not there in target.

Solution

There was a relationship in my solution exist as N:1 to an entity which was deleted from target system way back hence this error occurred. Using the relationship given in solution, CRM was trying to find related entity which wasn’t there.

 

Hope this helps.

Error While Connecting To CRM Online Using Kingsway SSIS Connector

Issue:

I have recently got this error when i was preparing an SSIS package for Dynamics CRM 365 Online and used Kingsway SSIS connector.

Kingsway1

Resolution:

After digging in further this error is mainly caused by the request and reponse timings,So, when i checked i found out my system time was somehow 5 minutes ahead of the current time, hence the request going to CRM server was of a future time and hence this error showed up.

All i had to do is fix my system time. Sometimes even if your system time is fine, you might still get the error, In that scenario too try to change the time as 5 minutes less.

 

Once i did that -my organisation name popped up without any issue.
kingsway2.png

 

Hope this helps!

Cheers!