Sonoma Partners Microsoft CRM and Salesforce Blog

Migrating and Integrating Dates to Microsoft Dynamics

Today's blog post was written by Rob Jasinski, Principal Developer at Sonoma Partners.

Whether migrating data into CRM from a legacy system or from an other external source or handling an ongoing integration sync into your CRM environment, handling dates can pose unique challenges. In CRM, dates are actually stored as date and time, even though there may be no time portion to the date. If no time is entered or supplied, it is defaulted to 00:00 (midnight). Also, the time portion is stored as UTC in CRM. When migrating data into CRM, the time zone of the user that is migrating (or integrating) the data is used.

So, for example, if the user is in the Central time zone, and a date of “10/15/2016” is passed into a field called birthdate, first “00:00” time is added to the date, then CRM converts the date and time to UTC. So it finally is stored as “10/15/2016 06:00” (+6 hours for CST) in CRM. Even though the time portion may never be displayed to the user, CRM is still always converting this date and time to the user viewing the data’s native time zone. Now if a user in the Mountain time zone is displayed this date, they will actually see “10/14/2016” in CRM. The reason for this is the date was migrated with no time, so it defaulted to midnight CST (since the user used to migrate the data was in the Central time zone). Internally, CRM then converts this to “10/14/2016 11:00pm” for the users in the Mountain time zone and since time may not be displayed, the user may only see the date portion, “10/14/2016”. This can be confusing and ultimately, the wrong date is displayed to the user.

There a couple of workarounds for this. First, instead of using a date field, use a text field in CRM and store the date as text. The problem with this is the date cannot be used in any date calculations or native CRM date filtering logic. The other workaround is to take the time portion and change it to 12:00 (noon). So in the example above, modify the date to “10/15/2016 12:00” before passing it into CRM. Once CRM converts this date to UTC, it will still allow for a 12-hour leeway, in either direction, for time zone conversions. So, in the example from earlier, a date of “10/15/2016 12:00” would be stored as “10/15/2016 18:00” in CRM. This date, displayed to a user in the Mountain time zone, would convert to “10/15/2016 11:00” thereby preserving the actual correct date once displayed.

If the time portion is required (i.e. for appointments, transactions, auditing, etc.) or if your CRM implementation is global, then this work around will not be the right solution. But if the time data is needed, then this is usually not an issue since the time portion would most likely be displayed to the user anyway.

Ease into the cloud with Microsoft Dynamics Lifecycle Services

Topics: Microsoft Dynamics 365

CRM and Yammer, Together Forever

Today's blog post was written by Ross Talbot, Principal Developer at Sonoma Partners.

Never underestimate the value of collaboration within your organization and Microsoft Dynamics.

In our previous post, we covered Activity Feeds as one option for promoting collaboration at your organization through CRM. Whether it is visibility regarding sales within your organization across functional areas in your organization or alerts within your team to provide status updates on deals in progress, both manual and automated options allow you to leverage Activity Feeds within your Dynamics 365 instance to enhance your team’s ability to collaborate. 

Going through collaboration options in Dynamics (hereafter also referred to as "CRM"), we will be looking at Yammer in this post. Connecting Yammer to your CRM instance replaces Activity Feeds; the two cannot co-exist. It is important to note that there is not a native way to remove Yammer once it has been configured in your CRM instance, but more on that later. For now, consider testing this in an instance you can reset if you find Yammer just isn’t the right fit for your organization.

To get things started, we need a Yammer network to use. For this example, we have a new Yammer network and will link it to a CRM Online instance. Detailed configuration information from Microsoft can be found here. Yammer configuration is found in CRM under the Settings > Configuration section. You need an appropriate security role (we are using a System Administrator account) to continue.

Rt 1

Give your consent to link Dynamics CRM Online and Yammer in the configuration page, and now we are really ready to go. This approval will replace the Activity Feeds in CRM, commandeer the social pane on records, take over as the centerpiece on the out-of-the-box social dashboard, and become the behind-the-scenes target for your system and user posts going forward (so this is important if you are using Activity Feeds already).

Rt 2

You will want to consider your options for the next two choices, so we want to explore the downstream effects of your options. I recommend using a specific Yammer group. The default is blank, which will direct posts to the “All Company” group in Yammer. This group is not configurable on the Yammer side and all users (regardless of their user status within CRM) will see posts in this area. The decision point here should be focused on cutting down noise for non-CRM Yammer users since All Company is a group everyone sees. One of the benefits is that you may want all users to see those posts, but a group named after your CRM Production instance also helps categorize these posts so even if everyone joins the CRM group, it makes the posts more meaningful. You also may want all users to see posts regardless of their CRM Access, so you want to choose the option that fits your needs best. The goal is to give the posts focus when needed and ensure that people won’t miss something that is valuable to them.

Up in Yammer, we will create a group called “CRM Production Blog” for this example. The reason we denote it as production is that we likely have at least one sandbox/lower lifecycle instance of CRM and when we test auto-posting options, we will want to ensure it is clear which instance of CRM the posts belong to (again more categorization/noise reduction for your production users than anything else). This will be the default group, but that can be changed when posting to target a different parent group. Note that if you copy a production instance to a sandbox for testing purposes, this configuration will need to be updated to match the Sandbox group in Yammer at that time.

Rt 3

Rt 4

Never overlook the next setting option or assume its meaning, as public versus private posting is next on our list to review. Since the group is configured for all of CRM, or All Company if you choose to leave the default as is, this privacy setting may also be useful in cutting down the posts in CRM that may not apply to all of your CRM users. This setting only applies to Yammer in CRM though, as posts will be available in Yammer itself under the CRM Production Blog group in our example and all members of that group can see the contents. This is more of an obscurity setting than a security setting, so you want to choose the option that makes sense for your setup. Security itself is not shared between CRM and Yammer, so you will want to ensure that information you need truly private is stored in a place like CRM with more granular record security. Yammer does have private groups, but the default group linked to CRM would then need to include all CRM users for collaboration purposes which would defeat it. 

Going back to the configuration, I recommend using public unless you have a need to switch this setting. Collaboration works best when more people are involved and if the content will be relevant, you want your team to see it. For this example, however, I will show what setting this option to private looks like so it gives you a better look at the CRM and Yammer possibilities.

Rt 5

To configure Yammer and CRM with the private setting, we just switch the setting in the configuration panel. Unlike so many places in CRM, there is no OK or Save button, and these options auto-save. I usually verify by navigating away and then back to the Yammer configuration page to ensure my changes stay in the system.

Rt 6

Let us now head to a CRM record to review what private configuration looks like to the user. The social pane will show Yammer posts on a record only if the current user is following that record. If a user is not following the record, they will see the message below. They will see a gap for the “missing post” on the Social Dashboard instead of this message.

Rt 7

You now want to follow the record in CRM to make the posts visible in both places. We can now see posts related to the record made by other users and can reply with additional posts or comments of our own. The social activity dashboard will show posts in the CRM group for records you follow or posts made in the group itself unrelated to records.

Rt 8

Down in the record’s Yammer feed, we can change the target group of our post in addition to adding our post text to ensure we get the visibility we need. We now add our post to the record’s feed. It is now visible on the record wall, social dashboard, and in Yammer for those who have access to each location. This will get eyes on the post that are not members of the CRM Yammer group.

Rt 10

Never miss an automation opportunity, either. Configuration posts can target Yammer as well, so the automated posts from Activity Feeds can be updated to post to Yammer from CRM. We navigate to Settings and choose Activity Feeds Rules. Opening the rule for a New Account, we note that the checkbox is checked for “Post to Yammer Activity Stream” on the form. This shows in CRM as a system post in a record feed and in Yammer under the Recent Activity section on the right side. The automatic posts work the same as Activity Feeds, and if you want to customize the content of these posts, you will need a workflow assembly or plugin to do so. This can give awareness to users in different areas of your business about new customers that different business segments should be looking to target or opportunities with customers shared across segments.

Rt 11

Going into more detail on the CRM and Yammer record links, this is built on Open Graph objects. The link contains a few actions and whether you are looking at this in CRM or Yammer, these functions pertain to Yammer. We will start with the options shown as you hover over this link as shown below.

Rt 12

To start, you will see a “Follow” link which is similar to a concept in CRM, but they are not related. The Yammer Follow shown here will follow the thread in Yammer only. If posts are made in a record’s thread and your integration option is set to Private, you would still need to follow the record in CRM to view the record’s wall. The Yammer follow affects posts and comments you see when you filter your Yammer feed to Following as opposed to All or Discovery.

Rt 13

Run back to the link options, and let’s look at share next. Again, this is a similar concept to CRM but unrelated. Sharing in this Yammer context allows you to send the link as a private message to a Yammer user or to share a copy of this link in another Yammer group. Share is only a visible option when viewing this link in Yammer and not in CRM.

Rt 14

Around the right side of this list, we see a “Go to Page” option. Clicking this launches the full thread for the graph object. The name of the record, the type, creation timestamp, and link to the record in CRM appear at the top of the thread. Posts and comments regarding this record are shown in this thread with new posting options similar to posting in a Yammer group. You also will see additional posting and commenting options that are not available with the Yammer feeds embedded in CRM (for example attaching a file) when viewing threads and groups in Yammer itself.

Rt 15

And there are more options just below the link as well, although most are only visible in Yammer so I will list them at a high level. Like, Bookmark, and Email Me should be self-explanatory, and reply will just add a comment to the thread. Share functions the same as the link, but with the post’s thread instead of the graph link. Stop Following will remove your follow from this post. View conversation will open the thread in its own window, but unlike the page this is for the post’s thread not the graph object’s which can contain multiple posts and their replies. Adding topics will add hashtag topics to the post for increased search ability. Delete will only show if you have permission to delete the post, otherwise there will be a “Hide Conversation” option instead to remove it from view. Note: Only the Like, Reply, and View Conversation options are visible from CRM.

Rt 16

Desert Yammer if you feel this is not the right fit for your organization. CRM does not actually give you the option to remove Yammer from your CRM instance (and that is the reason for the title of this post), however the OrgDBOrgSettings tool found here can accomplish this with a button found just under the list of settings. Just install the managed solution from Codeplex, and you can switch your organization to another method of collaborating if Yammer isn’t a fit for you.

Rt 17

You want to select the right collaboration tool for your organization and in summary, Yammer provides a bit more than Activity Feeds as far as options are concerned. Yammer gives you the ability to include users outside of CRM in your collaboration. It gives users the ability (if desired) to see posts about records they may not have access to so they are aware of high level information, such as an opportunity from another department for a shared customer. Yammer provides the ability to have non-CRM related conversations as well for interests other than work (sports, movies, music, you name it). Yammer also provides similar functionality to Activity Feeds, so if you have non-CRM users that you want involved in your collaboration, Yammer might be for you. You also may have heard about some upcoming changes with Yammer, and you may be aware of other collaboration options within Dynamics, so stay tuned for more updates here!

Topics: Microsoft Dynamics 365

How to Be Awesome at Sonoma Part 4: Just Do It


This post continues our “How to Be Awesome” series, highlighting exemplary Sonomans who live out the different elements of our “How to Be Awesome” list.

So we’ve heard from some of our pros, quality deliverers, and communicator extraordinaires. Next is the fourth item on the “How to Be Awesome” list: just do it.

We feel that “just do it” emphasizes that you do what you say you will. Telling a client or a co-worker that you’ll get something done is a commitment. Your colleagues can feel confident that you’ll complete your work in a timely manner. When necessary, you’re willing to work late nights or weekends to meet your deadlines.

Here is how some Sonomans are just doing it:

Katy Moy – Graphic Designer
“Katy is unstoppable. She has never missed a deadline, is always handling multiple projects with competing due dates, creates effective marketing materials, and does it all without ever complaining. Her work ethic is second to none. I have worked with very few people like Katy in my life and feel lucky that I get to be on her team.”

What advice do you have for others trying to “just do it”?
Set realistic goals and be enthusiastic about what you do. Collaborate with your team members. Surround yourself with people who inspire you (which is abundant at Sonoma Partners!). Try to learn something new every day within your work.

Pete Majer – Principal Consultant Pete
“Pete is always very responsive and keeps on top of things. He’s always willing to do what he can to help out and jump in to provide whatever support he can. I can’t think of a time when he told me or the client he would get something done and didn’t."

What does “just do it” mean to you?
Nobody likes to work late nights or weekends, but sometimes it’s mandatory. The biggest thing about “just do it” to me is being honest. If you promise someone that you’ll get something done by a specific date, you better do everything in your power to get it done by that deadline.

Vickie Stevens – Sr. HR Generalist
“Vickie is a powerhouse in getting things done and doesn’t let anything stand in her way. I always know she will meet her deadlines, and I never have to remind her to get something done. She is a joy to work with.”

Why is “just do it” an important part of the “How to Be Awesome” list for Sonoma?
“Just do it” is an essential part of our “How to Be Awesome” list. We rely on each other as an organization to do what we say we will. Sonomans love the people they work with in big part because they can rely on them to put in the extra time or effort to get the work done and “just do it.”

Interested in joining our awesome team of Sonomans? Check out our open positions here.

Topics: Careers at Sonoma

CRM On-Premise to Online Conversion

Today's blog post was written by Jen Ford, Principal QA at Sonoma Partners.

For those of you using Microsoft Dynamics On-Premise (2011/2013/2015), there is now a way to get assistance from Microsoft when converting from CRM On-Premise to Online using Dynamics Lifecycle Services.

Dynamics Lifecycle Services is an Azure-based collaboration portal to help you manage your Dynamics 365 for Operations implementations.

At a high level, Lifecycle Services (LCS) allows you to manage projects and its related tasks. If you have a CRM Online usage license, you can log into Lifecycle Services with that same account with no additional cost. And now, we can also use it to facilitate the conversion process.

Dynamics implementations have many things that make an upgrade or migration not-so-simple: custom code/entities/fields/reports, new options added by Microsoft, or depreciations removed by Microsoft. Tackling this by yourself requires someone dedicated to review the code, fix the code, and migrate your customizations, code, and data. This could end up being a time-intensive, costly effort that can require many resources, require you to engage your partner for a large scale project, and/or can produce significant amounts of manual testing to verify that the migration and upgrade were successful. Many clients end up purchasing third party tools to help facilitate this effort – another added expense.

Dynamics Lifecycle Services aims to automate some of these steps so that time spent reviewing and fixing code, upgrading, and migrating are all minimized so that you can focus your efforts on more important aspects of your implementation, such as taking advantage of the new features in Dynamics 365.

Right now, using this feature to convert from CRM On-Premise to Online is available through nomination into the Preview program only. Feature improvements to the conversion process will be made available in monthly releases. You can contact your Dynamics Partner to get nominated. Once your nomination is accepted, you will receive an access key that you can use to add a new Private Preview Feature in Lifecycle Services and create a Project specifically for the CRM On-Premise to Online Migration.

Jen ford migration 1

This sets up the three-phase Project in Lifecycle Services to guide you through all of the necessary steps to move to CRM Online.

Phase 1 – Customer Information Gathering Phase

This step is all about prep work. In this phase, you are identifying your organization and making your data available for eventual migration/upgrade. You will connect Lifecycle Services with your Azure subscription, and upload a backup of your SQL database to your Azure environment, as well as an Active Directory User file to set the users in your new Online instance.

Jen ford migration 2

Phase 2 – Staging Environment Setup and Validation Phase

This is an iterative phase, and you may need to cycle through this a few times to make sure your customizations and code are ready for conversion.

First, the project will guide you through creating a CRM staging environment. Then, Validation services are initiated from Lifecycle Services. Two tools are run: the Upgrade Assessment Tool and the Code Conversion Tool. This is trying to uncover unsupported customizations and code that will not upgrade. When these tools are done running over your CRM database, errors will be saved in a SQL Azure database and will be shown to you on the Power BI dashboard. You will need to fix the errors and rerun the validation services again. Then, lather, rinse, repeat until the errors are all cleaned.

The next step is to go through the upgrade process to get the database to the minimum possible version that it needs to be before it is converted to CRM online. If you are on CRM 2011, it will first upgrade your database to CRM 2013, and then to CRM 2015, before it is ready for CRM Online. If you are on CRM 2013, it will first upgrade your database to CRM 2015 before it is ready for CRM Online. At the time this blog was posted, converting from CRM 2016 to CRM Online was not yet supported, but will be in the future.

Phase 3 – CRM Online Migration Phase

In this last phase, the database is upgraded to CRM Online. Your users are created in CRM, and the data uploader service provides a way to get your data and customizations set in your new Dynamics 365 Online organization.

Once all steps of the guided project are completed, your CRM Online organization will be ready to use.

Topics: CRM Upgrade

Filtering Connection Roles by a Property of an Account

Today's blog post was written by Sonoma Partners' Principal Developer Argyris Anargyros and Senior Developer Jeff Young.

As part of a recent project, we had a client request to limit native and custom Connection Roles available to an Account based on a set of properties on the Account. While it is possible to filter the Connection Role field as you would any other lookup field, there is no native behavior to support filtering based on some specific property of an entity. Meeting this requirement required some custom development and, as we can see this being very useful, we are sharing the technique we developed.

The Use Case

In our case, the Account entity had been customized with a set of Yes/No fields that, if selected, would control the set of Connection Roles available to the Account, defining restrictions on how the Account could connect to other Accounts and Contacts.

Argy young 1

Figure 1: An example of the fields available to our entity. Here we have created a section on our form labelled 'Connection Role Filtering Fields' and added the fields controlling the available Connection Roles. In this example, the Connection Roles associated to fields 1, 3, 6, 7, 10 and 11 will be used to filter the Account’s available Connection Roles. The schema name for the field “Role Filter Field 1” would be new_rolefilter1.

Business logic determined the Connection Roles available to each field; the set of available Roles for the Account would be determined by which fields on the Account were selected as “Yes” and by the type of entity to which the Account was connecting.

Further, all the fields could be selected “Yes” or none could be; there could be any combination of fields.

Our first step was to determine what native functionality we could utilize, then decide how to extend it.

Filtering a Lookup

As we’ve said, CRM provides a way to filter values presented in a lookup field by JavaScript natively. Also, the Connection Roles form is just that - a form - so it’s possible to add JavaScript to it and have it run on form-related events, such as onLoad.

There are two JavaScript methods that are members of the lookup control that are utilized when applying a filter: addPreSearch and addCustomFilter.

addPreSearch is essentially an event listener that is attached to the lookup control, triggered when the lookup control is clicked. The argument for this method is the function that should run when the event is triggered. 

From within addPreSearch (and only from within addPreSearch) the addCustomFilter method can be called. addCustomFilter accepts two arguments: a subset of FetchXML which is the filter applied to the lookup and the schema name of the entity the filter is being applied to. This method is run on the lookup when the user clicks on it, which can easily be confirmed using a breakpoint on your favorite F12 tool.

It’s important to note that when using these methods, promises, or other non-synchronous methods can exit from the closure of the listener method and make applying the filter difficult to impossible. We discovered this as we have an extensive library of JavaScript tools at Sonoma Partners that we use to extend and enhance functionality of the Xrm API, including both synchronous and asynchronous use of the Org Service.

Our original implementation of this solution utilized the asynchronous Org Service methods, which gave us some problems because the promise, once invoked, had lost the context of the lookup (specifically, the closure in which the reference to the lookup had been exited). In our experience, it’s easiest to apply a filter using a sequence of synchronous calls instead of capturing the context of addCustomFilter and passing it to the promise when it runs (perhaps capturing ‘this’ and passing it as an argument to the promised method).

Our next step was to figure out some way of identifying the subset of Connection Roles to apply to the lookup filter.

Configuration Setting Entities

Configuration Setting entities are a common way of managing CRM behavior at Sonoma and elsewhere; giving System Administrators a convenient way to manage CRM behavior without editing code. In our solution for this project, we created a Configuration Entity that possessed simple key/value fields. We utilized these records to manage behavior of multiple entity scripts, just like this example.

For use with Connection Role filtering, we created some Configuration Setting records whose keys were a unique string based on our purpose and the schema name of the fields on the Account entity we wanted to control the filtering. This made the name of the record something like “Connection Filters for your_field_here”. So, if our Account entity had a field named “new_rolefilter1” and this field was checked as “Yes” we would retrieve the Configuration Setting record named “Connection Filters for new_rolefilter1.

Argy young 2

Figure 2: An example of the Configuration Settings record associated with Role Filter Field 1 (schema name new_rolefilter1)


To reflect the business logic the value of these records, then, were the names of the Connection Roles we want to filter by; specifically, comma separated string of the names of the connection roles, such as “Accounting,Administration,Coordination,etc…”

Strings are a convenient way to express this data as we can split them easily into an array once we’ve retrieved the record. They may not be so easy to administer, however, especially if the list of the record maintains becomes long. In this case, expanding the entity to include multiple fields would be one option which would present a more user-friendly way of managing the fields, but we would lose the programmatic convenience of getting and splitting a string and would be introducing issues with forward maintainability; adding Connection Roles would require editing this form, for example. For this reason, we went with strings.

Having all the pieces in place, now we need to bring them together.

Using the Configuration Entities to Filter Connection Roles

We attached a script to run on load of an Account form. This script retrieved the values of the fields that will control the available Connection Roles, determined which fields were set to “Yes” and then retrieved the configuration record for each one of these fields.

Using the value of each configuration record, we build an array of unique Connection Role names (some records may contain the same Connection Roles, see below) by retrieving the value of each configuration record and splitting it by a comma.

Then, using this array, we construct the Fetch XML fragment that will be applied to the lookup. The fragment is part of an ‘AND’ condition appended to the query for the lookup. Because we want to filter on a name or a set of names, we must nest the Role names we want to match against within an OR condition. The final XML looks much like below:

<filter type="and">

<filter type="or">

<condition attribute="name" operator="eq" value="Accounting"/>

<condition attribute="name" operator="eq" value="Advisory"/>

<condition attribute="name" operator="eq" value="Provisioning"/>

<condition attribute="name" operator="eq" value="Communications"/>

<condition attribute="name" operator="eq" value="Scheduling &#038 Maintenance"/>

<condition attribute="name" operator="eq" value="Logistics "/>



The result of applying the filter will look similar to the below image:

Argy young 3

In sum, when we load the Connection Roles form for an Account, we:

  • We add a listener to the Connection Role lookup field.
  • When the lookup is selected, we query the account to get the set of properties that effect the Connection Roles.
  • Using this set, we query for the Configuration Records for each positive field.
  • From this query, we build an array of roles that are available to the Account.
  • From the array, we build XML that applies a filter to the lookup.


As we developed this solution, we encountered a few issues that provided some challenges.

  • Filters must be URL escaped. When testing our solution, we ran into immediate problems with the Fetch XML we were building; CRM was reporting Malformed XML. Looking closely at the XML, we noticed that custom Connection Roles created by the client contained the ampersand and forward slash characters, which are special characters in XML. In order to correctly handle these characters when applying the filter XML, they need to be replaced by their encoded HTML value (‘&’ becomes ‘&#038’ as can be seen in the example FetchXML above).
  • Make sure to remove duplicates from the filter list.
  • Methods used to filter the lookup can’t be asynchronous. Forewarned is forearmed!

We hope that this technique will help you towards your CRM endeavours.

Topics: CRM Best Practices

Is Your CRM (Einstein) Smart?

Today's guest blogger is Aaron Robinson, an Engagement Manager with Sonoma Partners.

As the year comes to a close, Salesforce is wrapping up their New York World Tour - one of many for the coming year.

Even if you only watched with one eye open, you probably picked up on the common theme driving the conversation around the Salesforce platform – artificial intelligence, or AI for short.

While most people's personal experience with AI is probably summed up in the decades of sci-fi movies, it has inched its way into the consumer world of apps we use everyday. I would be willing to bet most people don’t even recognize AI in action when they see it, which is partly the beauty of having intelligent applications. Ever wonder how Netflix knows which movies to recommend for you or how Pandora can play hours of music you will enjoy without you having to select each individual song? These types of algorithms and the predictive power amassed by AI drives these types of little life improvements. Its the tip of the iceberg in terms of what we will see in the future, and if you want a little taste of how life changing this can be, take a ride in a self-driving Tesla.

AI for the (Business User) Masses

Einstein 1One of the great things that Salesforce is known for is marketing, and they do marketing on their own products about as well as anyone. AI has been taking shape in the technology world in many different forms because it’s such a broad topic – natural language processing, activity recognition, bots, machine learning, and sentiment analysis. There are many more, but Salesforce wishes to embody the spirit of their brand of AI into something easily recognizable and understood by anyone who encounters it. And what better way than to identify with one of the most revered human minds that ever existed: Albert Einstein. Also in traditional Salesforce style, they have created a cute and crazy haired little persona for their branded technology.

Salesforce Einstein is branded as “the first comprehensive AI for CRM.” Salesforce has integrated artificial intelligence technologies into the underlying platform to make their Customer Success Platform smarter and more importantly, usable by the average business user without the need for significant training. Salesforce states their differentiation in the marketplace in three key pillars:

  • Data-ready — You don’t have to do data preparation or manage models. Just put the data in Salesforce, and it works.
  • Modeling-ready — Multi-tenant, automated machine learning means the right model automatically fits to your organization.
  • Production-ready — No DevOps needed. It’s part of the same trusted Salesforce platform, with model management and monitoring tools.

All of the available clouds offered by Salesforce can take advantage of Einstein as its built into the platform layer of the application, shown in the graphic below. Einstein encompasses those forms of AI which I mentioned previously such as predictive analytics, machine and deep learning as well as natural language processing.

Einstein 2

The Smarts in Action

During the various cloud keynotes, Einstein was shown in action, driving analysis and serving up logical next steps to help improve various outcomes.

Sales Cloud Smarts

The Einstein conversation around sales focuses around leads and opportunities and how we can identify and develop the customers who have not only just raised their hands, but performed actions to tell you they are serious about your product or service. Depending on the industry, market, regulation, or service, selling always comes with its unique set of challenges. But what if your CRM platform could help evaluate how your sales team should be spending their time, recommend best next steps, and even facilitate automated follow-up? Ultimately, this would help focus their time to managing relationships and providing true engagement before, during, and after the sale.

Einstein 3

For the Sales Cloud user, the goal is to help your reps sell smarter with the help of Einstein. Salesforce starts you on the process with two key features: Predictive Lead Scoring and Opportunity Insights. For the inside sales team, predictive lead scoring ranks their leads in Salesforce using the attribute data. The insights pane on the lead will not only show a score but also the factors from the lead record that influenced the score, including lead data and activity performed by the individual tied to the lead. Assuming you’re using some related Salesforce marketing technology, you can even view a history of the engagement with the individual, including website visits, meeting acceptance, and from completion. This allows the rep to have a more intelligent and engaged conversation around your product or service.

Service Cloud Smarts

Providing great service isn’t just about solving a case quickly, but in the consumers’ eyes a connected and “conversational” approach to service. As a consumer with a basis towards the use of CRM systems, I’m totally befuddled by my interactions today with service reps, and the experience leaves me feeling like they know nothing about me. Not only does Salesforce help to bridge that gap, but they are using Einstein to serve up relevant information to the agent at the time of service to make that interaction personal and engaging.

To do this, Salesforce is enabling some new functionality, such as engaging customer through SMS text messaging, chat through Facebook messenger, and enabling Service Cloud bots. These features will help to drive quicker connection for service. But the real power comes through in how Einstein can help improve the customer interaction.

Einstein 4

Take this scenario, talked about during the Service Cloud key and a real frustration of mine when I call for service. Imagine chatting with an agent for support, only for them to ask if you mind being put on hold while they do a bit of research. And often that first hold isn’t enough, but they will come back and ask repeatedly for you to hold. With help from Einstein, agents can get recommendations based on the information they have collected, to help guide the experience in real-time, versus having to make the customer wait while the agent searches for a solution. And as cases get resolved, the system only gets more intelligent using the actions performed to solve the case to better predict how to solve similar cases in the future.

Marketing Cloud Smarts

Now why should sales and service get all the cool tools? Well, in Salesforce they don’t. Marketing is also served up a healthy dose of IQ points to make their engagement more effective. Consider a few of the following use cases conveyed during the Einstein Keynote...

Marketers can utilize the Journey Builder to build smart journeys that are individualized by the specific customer’s preferences. One such feature is the Smart Split which determines what are the best channels to reach a customer based on their preferences. Einstein will analyze the activity for a given customer to determine which channel is most likely to illicit a response – for customer A this may be email, while for customer B is might be text, and customer C is a Facebook ad. When a customer reaches this step in the journey, Salesforce will use the appropriate channel for that targeted communication. A similar intelligent path is based on time – when is the most optimal time to send the message to a customer. Using a time-optimized step in the flow, the message can be sent at the optimal time for the particular consumer. And this is just the beginning, so check out the keynote in full to see other options for features like predictive vision services (in beta) for product recommendations.

The Future is Here

At first blush, this is very compelling. It can be applied to such a wide range of challenges for different industries and business models. The part to keep in mind is that while it seems tempting to just jump in head first, it’s important to look at your business and where there are processes that can be improved with the use of AI. Also, there are distinct use cases where Einstein makes sense today, so it’s important to make sure your use cases match those. In the upcoming releases for 2017, we’ll look for improvements to Einstein and how that can be leveraged even further.

If you’re interested to learn more, head over to the Salesforce’s Trailhead and search for Einstein. If you’re curious how Salesforce Einstein can potentially help improve your business, we’d be happy to talk to you as well. 

Three Steps to CRM Success

Topics: Salesforce

Dynamics 365 & Flow – 3 Simple Steps to Email Sentiment Tracking

If you’re not familiar with Microsoft Flow yet, it is definitely worth checking out.  It allows you to easily connect many different applications, one of which is Dynamics 365, to each other.  Earlier this year, the ability to connect to Microsoft’s Text Analysis API was added which takes in a string of text and returns a sentiment score from 0 to 1 with 0 being negative and 1 being positive.  This means we can painlessly connect Dynamics 365 to the Text Analysis API which I will walk through in this post in the form of Email sentiment tracking.

The first thing we need to do is create a custom decimal attribute on the Email entity to track sentiment.


Once that attribute is created, navigate to Microsoft Flow and create a new blank Flow.  In the “search for more triggers” box, type “create a record” and choose the Dynamics 365 option.  You will need to authenticate to your Dynamics 365 environment and then select your Organization Name from the list.  Once that is done, select Email Messages from the Entity list as well.


Next, click “+ New step” and select “Add an action” and in the “Search for more actions” box, type “sentiment” and select the “Cognitive Services Text Analytics” option.  You will then need to sign up for Cognitive Services and provide your API Key to Flow.  It is free to try for up to 5,000 API calls per month.

Once you provided your Cognitive Services details, put your mouse cursor in the “Text to analyze” box and a sidebar should show up with a list of options like so:


Find “Description” in the list and select it.

Next, click “+ New step” and “Add an action” again.  Search for “update a record” and choose the Dynamics 365 option.  Again select your Organization and Email Messages.  Highlight the “Record identifier” box and choose Email Message from the sidebar list of options.


Then click the “Show advanced options” at the bottom of the Update a record section.  This will expand the section with a big list of Email attributes.  You should be able to find the custom Sentiment attribute that we created in the beginning of this post. 

Highlight the Sentiment text box and select Score from the sidebar list of options.


That’s it!  The Flow is complete so you can give it a name at the top of the page and then click “Create flow”.

In the list of Flows, make sure the toggle control is set to On.


Now in your Dynamics 365 environment, create a new Email record and save it.

Back in Flow, click the circle icon with an ‘i’ in the middle.


This will show a history of runs for the Flow.


Once you see that your Flow was successfully ran, go back to your Email record in Dynamics 365 and you should see the Sentiment field populated.


Now all emails created in Dynamics 365 will have a sentiment value populated.  You could even extend it further and add a native Rollup field to Contact to store the average Sentiment across all emails that were sent by the Contact.

There is a caveat that the Text Analysis API is only free for 5,000 calls per month.  Below is the pricing chart taken from the Cognitive Services pricing page:


Topics: Microsoft Dynamics 365 Microsoft Dynamics CRM Online

Enabling Configurable Plugin Trace Levels

As we mentioned last spring, Dynamics 365 now supports tracing messages from plugins without requiring an error to be thrown.  However as plugins become more complex, we often find ourselves wishing for more granular control over the level of detail traced without requiring code recompilation.  With these requirements in mind, we will build an elegant solution that has minimal impact on performance.

First, we'll define an enum that introduces the different levels of tracing we want to support.

This should start to look familiar if you use log4net or similar logging frameworks.  The different levels (Debug, Info, Warn, Error, and Fatal) provide the granularity we are looking for when configuring how much detail we want in our Plugin Trace Logs.  The other two values (All and Off) provide a more explicit way of completely enabling or disabling tracing.

Next we’ll add an internal class to our plugin assembly to wrap all of our trace calls.

The main constructor starts by getting the ITracingService from the passed in IServiceProvider and storing it in a field for later use.  It then goes on to look for a shared variable on the IPluginExecutionContext which will define the minimum tracing level to trace.  If that shared variable doesn’t exist, it defaults to the minimum level passed in to the constructor.

Now we’ll add a method that will actually perform the tracing.

The Trace method takes a level, a format, and an array of arguments.  If the level is at or above the minimum, the format and arguments are combined and then passed to the previously saved _tracingService.  We prefix the message with the trace level, to provide extra detail.  This could be further enhanced to provide timestamps if you are investigating performance concerns.

Finally, we’ll add a few convenience properties and methods to our Tracer class just to make it easier to use.

The properties provide a quick way to check and see which trace levels are enabled.  For simple messages there isn’t a need to check these properties, but some more detailed traces have to build up a complex messages.  In these cases, it is worth it to check and see if the targeted level is enabled before building the message.  The methods here are simple shortcuts for Trace with the level specified as the method name.

Now we’re ready to write a plugin that takes advantage of our new class.

While this plugin’s logic is very contrived, it demonstrates how to use the Tracer class.  There are examples of tracing at different levels and checking which levels are enabled before composing a more complex message. 

We can register this plugin to run during the Create of a contact using the following configuration:


If the plugin is left registered by itself, it will always be configured to run at the “Info” trace level (The simpler Tracer constructor it uses defaults to TraceLevel.Info for the defaultMinimumLevel).  If we want to change the level without making code changes, we’ll need to introduce another plugin.

The TraceConfigurationPlugin uses the Unsecure Configuration value to set the TracingLevel shared variable on the execution context.  As long as we register this plugin to run before any of our other plugins, it can specify the level the plugins following it should use.  We could even register multiple steps for the same message with different Execution Order values if we wanted to have different trace levels for different plugins.

Here is an example of how we could register this plugin to run before the BusinessLogicPlugin and set the trace level to “Debug”:


Now we can use the Tracer in all of our plugins and feel comfortable adjusting the trace level as more details are needed during troubleshooting.  No additional API calls are made to read the tracing configuration values, so this will have a minimal impact on performance.

To see how to enable tracing and where to read the logs, please reference our earlier blog post.

Topics: CRM Best Practices Microsoft Dynamics CRM Microsoft Dynamics CRM 2016 Microsoft Dynamics CRM Online

PowerApps with Dynamics 365 Update

Back in October 2016 I posted a step by step instruction for creating a basic contact application using the PowerApps preview designer with the new Dynamics 365 connector.

Today, I provided an encore presentation for the CRMUG. So, in preparation for the webinar, I went back through the steps using the new production version of the PowerApps studio. As I guessed, some fantastic updates to application were deployed, which prompted changes and new screenshots for our original application. Our original post was updated reflecting the changes as of today.

I am sure there is a more comprehensive list somewhere, but listed below are a few the differences & improvements I found useful for updating my contact application.

  • The default Dynamics 365 contact app now includes a refresh icon/functionality.
  • The 'Theme' functionality is no longer on its own Design tab. It is on the Main tab, but isn't readily discoverable if your window is too small.
  • The PowerApps team added support for multi-environments. Learn more at
  • You can now search for advanced properties. Super nice!
  • More properties are exposed in the ribbon, making it easier to change them without having to go and search in the Advanced tab.
  • Added an application description field. Doesn't sound like much, but when you start creating a lot of applications, it is nice to have more context about them. Smile
  • The default icon size appears to be larger than the preview. We still recommend using the search icon and sizing it the same as the text box height, but added some padding to make it look better.
  • Overall performance of the client was improved. I am sure they are still making further improvements, but the latest version was noticeably faster than the preview.


Should you need to submit ideas or help with your apps, please use the following forum link:

There two forums for you, support and ideas.


The PowerApps team uses these sites for feedback and will forward any Dynamics 365 connector questions to the Dynamics team where appropriate.

Topics: Enterprise Mobility Microsoft Dynamics 365

Integrating MDR education and school data with your deployment

Sonoma Partners works with multiple customers in the education industry, and they frequently ask us about integrating MDR's school data with their CRM system. If you're not familiar with MDR, they provide the most comprehensive set of data about schools and school administrators throughout the United States. Most folks consider MDR data as the "gold standard" in the education industry. If your business works with schools, that means you have a fixed universe of customers to sell to. Consequently, having clean and accurate data about schools and their contacts becomes hyper-critical!

To help make sure that our education customers have clean school data in their CRM system, Sonoma Partners developed a process to update CRM with the latest and greatest MDR education industry data on a regular basis. The MDR data updates include detailed information about both schools (accounts in CRM lingo) and administrators (contacts). Some of the data points provided by MDR include:

School / Account Sample Data Points (this is not the full list, there are over 300+ MDR account fields and 85+ contact fields)

  • MDR District Enrollment
  • MDR District Classification
  • MDR District Grade Span
  • MDR District PC Computers
  • MDR DMA Code
  • MDR School Improvement
  • MDR School Type
  • MDR Technology Sophistication Index
  • MDR Student Enrollment
  • MDR Student to Computer Ratio
  • MDR Number of Classrooms
  • MDR Number of Schools
  • MDR Open Date
  • MDR Total Budget
  • MDR Total Number of Students
  • MDR Total Software Budget
  • MDR Total Technology Budget

Administrator / Contact Sample Data Points (this is not the full list, there are ~25 MDR contact fields)

  • MDR Status
  • MDR Title
  • MDR Last Name
  • MDR First Name
  • MDR Middle
  • MDR Name
  • MDR Preferred Title
  • MDR Gender
  • MDR Last Update Date
  • MDR Job 1
  • MDR Job 2
  • MDR Computer User
  • MDR Advanced Placement
  • MDR Years at School
  • MDR Years of Teaching Experience
  • MDR Highest Degree Level
  • MDR Email Address

 After integrating the MDR data with, the end users can view and access the data through the user interface and it will appear like the following:


MDR publishes refreshed and new data several times per year. Our integration updates all of the Account and Contact MDR data fields with each MDR refresh.  We recognized that our customers will be updating their Account and Contact data directly in Salesforce as well, and they may have more accurate information earlier than what MDR collects.  Therefore, we set up an exception process so if a user directly updated any of the MDR data fields, the integration will not update a manually modified data field with the MDR refresh for at least 6 months. Please keep in mind that we setup this exception process on a field-by-field basis.  For example, if a user updated the Phone number last month, but all of the other fields have not been updated in over 6 months, when the MDR refresh is run, all of the Account fields listed will be updated except for the Phone, which will not be overridden by the MDR integration.

We also recognized that you might NEVER want some fields overriden by the latest MDR data refresh (for example the email, Billing Address or Shipping Address).  To accommodate these scenarios we created a “Never Update from MDR” checkbox directly below each of these three data fields.  If you do not want your information overwritten, users can check this checkbox for the appropriate field.



Lastly (and maybe most importantly), MDR provides hierarchy data about how the schools rollup to districts, sub-districts, etc. This hierarchy data allows companies to perform rollup calculations of they well they perform within districts at an aggregate level. Consequently, companies could answer questions like "What's our total sales pipeline in District XYZ? How much of product X did we sell to sub-district ABC in the last 12 months?" This screenshot shows how we modeled the school hierarchy within


The MDR data integration with CRM provides our education industry customers with several benefits, including:

  • Accurate, cleansed account and contact data
  • Access to full universe of education customers based on standardized industry database
  • A repeatable data load process
  • Reduced need for manual record maintenance
  • Better information to make informed sales and marketing decisions

And yes, if you're curious, Sonoma Partners could help Microsoft Dynamics CRM customers setup a similar integration with MDR data!

Please contact us if you're interested in learning more about our experience integrating MDR data into your CRM system.

Topics: Microsoft Dynamics 365 Microsoft Dynamics CRM Salesforce