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!

Dynamics 365 For Marketing – Retrieve Contacts From A Segment

I had a hard time trying to figure out a way to retrieve members from a marketing segment in my code.

The link-entity between contact and msdyncrm_segment isn’t materialized in CRM. I even raised it here :Basic operations on segments using the Segmentation API

Solution:

Finally fetch xml came to rescue. You can use below xml which can be executed by WebAPI or Organization service and it works on both static and dynamics segments.

<fetch version="1.0" output-format="xml-platform" mapping="logical" returntotalrecordcount="true" page="1" count="5000" no-lock="false">
<entity name="contact">
<attribute name="fullname"/>
<attribute name="contactid"/>
<order attribute="fullname" descending="false"/>
<link-entity name="msdyncrm_segment" from="msdyncrm_segmentid" to="msdyncrm_segmentmemberid" alias="bb">
<filter type="and">
<condition attribute="msdyncrm_segmentid" operator="eq" uitype="msdyncrm_segment" value="bfc9d5d6-d6aa-e911-a859-000d3a3159df"/>
</filter>
</link-entity>
</entity>
</fetch>

Now lets try to execute this first in web api.
Use below format : https://orgurl/api/data/v9.1/contacts?fetchXml=<xml here>
1

Now lets try to execute this using organization service, note that i am using paging here because the number of records can be more than 5000:

var fetch = @"<fetch version='1.0'  page='##pagenumber##' count='5000' no-lock='true'>
<entity name='contact'>
<attribute name='fullname'/>
<attribute name='contactid'/>
<order attribute='fullname' descending='false'/>
<link-entity name='msdyncrm_segment' from='msdyncrm_segmentid' to='msdyncrm_segmentmemberid' alias='bb'>
<filter type='and'>
<condition attribute='msdyncrm_segmentid' operator='eq' uitype='msdyncrm_segment' value='6f5846d5-e5ae-e911-a84b-000d3a802d92'/>
</filter>
</link-entity>
</entity>
</fetch>";



 var contactss = organizationService.RetrieveMultiple(new FetchExpression(fetch));                  
                        foreach(var contact in contactss.Entities)
                        {
                            var id = contact.ToEntityReference();
                            Console.WriteLine(contact.GetAttributeValue<string>("contactid"));
                        }

result:
2

Apart from this fetch xml there is no way to retrieve members from the segment.  There are some issues and limitation i faced during this operation, will try to share them in another post.

I hope this helps!