Covering his love of Brazilian JuJitsu, occasional wrestling matches with friends/colleagues, & how it can help with day to day life. Delving into a last minute RFP with a surprise inter-continental trip (such a shame that Concorde wasn’t around!), delivering a pitching session whilst carrying out discovery as well, and how the right approach can win what may seem to be an unlikely deal!
If you’d like to come appear on the show, please sign up at http://bit.ly/2NqP5PV – I’d love to have you on it!
Click here to take a look at the other videos that are available to watch.
I come from an ‘on-premise’ background. I’ve spent years in organisations with on-premise systems such as Dynamics 365. Take me into a server room that’s alive with whirring fans, and I get quite nostalgic. Those were the days…well, in some ways, anyhow. But having recently discovered some quite helpful functionality, I thought I’d share it with others!
See, when it came to Dynamics 365 security, there was no way to automate things. Yes, users had to be created in Active Directory (and also, in a folder that the Dynamics install could refer to within AD!), but they had to be manually added to Dynamics 365. There was no way to automate this (from recollection – then again my memory grows dim with the fog of time).
So what the system administrators needed to do was to manually go to Settings/Security within the system, and there they could either add a single user at a time, or multiple users. They would then assign role/s (for multiple users, all of the users would need to have the same role/s – it wasn’t possible to modify individual users within this process).
One way to slightly speed up time in handling different security roles was to have teams, relating to the business needs. The security role/s would be created, assigned to a team, and then any user added to the team would automatically get all of the permissions that they needed.
Then came the heady world of Dynamics 365 being online! Well, nothing much changed really, at least not for a little while.
But then, things really did change, in May 2019. Functionality for security teams within Dynamics 365 was increased. Notably, there was now something called a ‘AAD Security Group Team’:
So what was this magical new item?
When we create a team, and we set the Team Type to ‘AAD Security Group’, we’re now able to set an AAD Object ID. In fact, it’s required! After we’ve created this object within Dynamics 365, we can then apply security role/s to it directly (as we could to any other team records beforehand):
Let’s take a moment to reflect & think on this. Until now, we’ve had to handle security directly within Dynamics 365. Now, we have the ability to have an Azure Active Directory (for that is what AAD stands for) group, and reference it within Dynamics 365.
Suddenly new possibilities open up. As part of the on-boarding process (for example) we can users to specific AAD security groups, which will then give them access with appropriate permissions within Dynamics 365. We’re also able to have multiple AAD groups, each inheriting a different set of Dynamics 365 roles, and thereby create a multi-layering approach to different business & security needs.
We’re also able to use tools such as PowerShell, LogicApps, Power Apps & Power Automate to carry out automation around this. There’s an Azure AD connector (https://docs.microsoft.com/en-us/connectors/azuread/) which gives the ability to set up & administer these.
We’re actually using this functionality now in some of our COVID-19 response apps. Instead of needing our own support desk to manage the (external) users, we’ve provided an interface where client IT departments can quickly log in, upload a list of users, and assign them to the relevant AAD group/s. It’s very quick, and allows the users to onboard to the Power Apps within minutes!
So with knowing this, how do you feel it might help benefit you? Comment below – I’d love to hear!
Recently we’ve been rapid producing & deploying solutions, due to the current pandemic. One of the apps that I’ve been working on required quite a few fields for data capture. Well, truthfully most apps require quite a few fields, but I thought that I’d talk about this one in particular, due to something that I discovered.
Now, we all know how to create fields in the Power Platform maker experience. It’s really quite simple – you select that you want to add a new field, put in the details/type of field, & save. Hey voila – you have yourself a nice new field! You can then go on to add it to forms, views, etc etc. We all know how it’s done:
What I’ve found myself doing recently though is not to create fields through the Maker interface (make.powerapps.com), especially when there are lots of fields to create. Instead, I’ve been using the XrmToolBox to do this. There’s a very helpful tool within it called Attribute Editor, which allows you to use an Excel spreadsheet. It takes this, and creates the relevant fields through the Dynamics 365 API.
One of the reasons for doing things this way was that it allows me to get on with other things whilst the fields are being created. Although it doesn’t happen in the blink of an eye (especially when there are a lot of fields to create), I can leave it whizzing along, and do something else. This, of course, makes me feel VERY productive!
Right – back to what I was saying. So I had a lot of fields to create, and many of them needed to be datetime fields. Actually, all I needed was the time component, but unfortunately Dynamics 365 DOESN’T allow you to just show the time. It’s either Date, or DateTime, but no option for JUST Time. A flaw, in my opinion, for what it’s worth….
So I created the Excel template, started the process, and went on to do something else. I of course made sure to specify that the field type should be ‘DateTime’.
Coming back to it when it had finished, I started to place fields on forms, and noticed something strange. All of the datetime fields that I had created through this were date ONLY. This was…puzzling! Going to check the fields themselves, they were set as Date ONLY, not DateTime!
I went back to check my upload spreadsheet, and it was set correctly there. I even tried uploading another field, but still the same issue was occurring.
Now, with the way that Dynamics 365/Power Platform works, once you’ve created a field & saved it, you can’t change the field type. When it’s created it’s saved down to the underlying database structure as the specified field type, and that’s it. No way to change it…or at least not through the front end!
With this in mind, I fired up another one of the XrmToolBox tools, namely Attribute Manager. What this handy tool does is, behind the scenes, allow you to change the field type. Well, it doesn’t ACTUALLY change it directly – it clones it, deletes the original, then clones it back. There are some caveats to it working properly (ie that the field isn’t used in a view somewhere, for instance), but it’s really helpful.
Note: It only works for custom created fields, not the default OOB fields!
Depending on the field type that you’re wanting to change it to, you can select different options. However for DateTime, there’s only one option. OK – I was going to see what happened.
Well, I ran the update, but nothing changed. It was still ‘Date’ only within the interface, which was really being incredibly annoying. It wasn’t as if I could just delete & recreate it (well, I could, of course). I had dozens & dozens of these to do, and quite frankly didn’t want to spend all of that time in doing this.
Thankfully (with the help of one of my colleagues, who’s an experienced & devoted developer – thanks Sid!), we found the solution.
See, I had been doing everything within the ‘new’ interface. This is the one that Microsoft keeps pushing everyone to, as they don’t want people to really be using the Classic Interface anymore. That’s all very well & good, but the ‘new’ interface isn’t on parity (for some things).
Reverting back to the Classic interface (note that the option below is only available when working within a solution!), we discovered some hidden behaviour
We located the entity that we needed, and the field itself, and opened it in Classic. With the screen that’s presented (I do miss this in some ways – I remember the days where I almost lived permanently in here!) we AMAZINGLY have the following option:
We can CHANGE THE TYPE!! Now, this is just with the field that we’ve selected. To be frank, I have no idea at this point about any other field types, and would need to explore that separately. But for the moment, my problem has been solved! (well, to the point that I have ‘time’ values available – I’d still like to see JUST time values being an option).
So with this in mind, I merrily waded through the dozens of fields in the Classic UI, changing them all as needed. It wasn’t just a few minutes of work, but it was definitely much less time that deleting & manually creating each one!
So, really quite helpful. The only other thoughts that I had around things were that it would be nice if the various tools within the XrmToolBox could do this as well. However, the fact that they don’t seem able to actually seems to be a limitation of the API. Having gone to check the different field types & how they’re set programmatically (https://docs.microsoft.com/en-us/powerapps/maker/common-data-service/types-of-fields), I’ve noticed the following:
There really doesn’t seem to be any way to specify the different sub-type, which is a shame!
Have you ever had a similar situation with fields? Drop a comment below- I’d love to hear about it.
Chatting with Thomas Sandsør about his celebrity status as one of the National Beach Football team, how he got there, and his experiences from the game. Also talking about starting on projects as a junior consultant, & why it’s SO important to ask questions & not just blindly follow instructions.
If you’d like to come appear on the show, please sign up at http://bit.ly/2NqP5PV – I’d love to have you on it!
Click here to take a look at the other videos that are available to watch.
Routing is used to send customer interactions to specific queues, in order to have them handled by the agents best suited. This could be based on the language that the customer is using, the query that the customer has (involving pre-chat survey questions), etc.
The way that this is done (included in the previous articles) is by selecting the details that we want to use. This could be the contact (when recognised as a record in the system), pre-chat survey responses, or several other options.
However, to date we’ve only been able to use fields/variables from the chat session itself. It’s not been possible to connect to other data that we’re holding within the system, and use that for routing. We’ve only been able to use items that are directly linked to the conversation:
Account
Case
Contact
Context Variable
Live Chat Context
So if we had identified the customer as existing in the system already, we weren’t able to query related records to them, eg accounts etc. That’s all changed now though – we are now able to do this!
Let’s see an example of this. We have a customer, and we know from within Dynamics 365 that his company is a VERY large customer of ours. They spend a great deal on our products every year, and as a result, we want to route any interactions with them to a special VIP queue. Previously we were unable to do this, unless we somehow set a flag on the contact record to display this.
What we’re now able to do is go and get values from the linked account record, and use these as the routing variables within the workstream:
We can add multiple rows here, all connecting different parts of the data.
Note: The only caveat is that the entity needs to be linked to one of the Omnichannel items (which are listed above). We can’t daisy-chain non-related entities, eg Contact-Account-Invoices
These can obviously be put together in groups, to satisfy more complicated conditions, using AND/OR conditions. With this, we can therefore address very specific scenarios, tying together conditions across multiple entities.
Even nicer, we’re not restricted by the relationship type. We therefore can select an entity that’s related to the primary Omnichannel entities as:
One to Many
Many to One
Many to Many
With this being in place, we’re now really able to ‘fine tune’ how we can route customer interactions, and set up specific places for them to be directed to. Through this, we can identify & serve identified sectors of our customers in different ways, as we feel is best appropriate.
This is also applicable to skill attachment routing, where the same level of functionality is provided.
So with this in mind, how would YOU think that you would go ahead and use this? Leave a note in the comments below!
I’ve previously touched on macros in https://thecrm.ninja/omnichannel-productivity-tools/, but with some new functionality that’s now come out, I thought it would be quite interesting to dive deeper in them. By doing do, we can see how they work, the functionality that they offer, and some really cool & interesting scenarios!
Let’s have a quick reminder of what macros are all about (for those who don’t know, yet):
Macros allow customer service agents to carry out repetitive tasks that can span multiple entities. Eg opening forms (model-driven apps), pre-populating data into the form, etc. Through this, not only are there less manual tasks/steps to carry out, there’s now the ability to carry out the same tasks, without worrying about a step being missed, or the wrong data copied in, etc.
With that in mind, let’s see what there is for macros in Omnichannel. As a default, there were always the following 3 pre-defined automation actions:
With these, we’re able to do things like:
Opening a form to create a new record. This could be used to create a new contact automatically
Opening an existing record. This could be used to open an existing contact (based on pre-survey questions, such as email address etc
Searching the Knowledge Base using specified keywords/phrases
Opening an email form with a pre-defined templated
Linking records together
There’s now a new option available:
Hmm. This looks interesting. What happens when we select it?
We get a condition block! Clicking ‘Add an action’ will allow us to then add either one of the pre-defined automation actions, or another Control/Condition block.
OK – so you’re now thinking that I’m getting over excited about this. But hold on – let me explain further why I’m really liking this.
So when using Power Automate, frequently I’ll use condition blocks to check/satisfy things (it’s obviously available in Logic Apps as well, but I have minimal experience of those to date). Some of them can get quite advanced, but it comes in useful. However for Omnichannel macros to date, it’s not been possible to do this. We’ve been limited to just a few options, without being able to specify branching criteria based on variables.
Now we’re (finally) able to do this. The Condition field works in the same way as Power Automate does, with being able to string multiple statements together, and have actions that result from them. We’re also able to use slugs in them, to populate variables & use customer-entered data.
Let’s see an example of this. We have a customer who’s opening an Omnichannel chat session. They’ve filled in the pre-survey questions, in which we’ve asked for the following pieces of information:
First Name (required)
Last Name (required)
Email Address (required)
Company Name
With the condition check in place, we can either create just a contact record (if the customer didn’t fill in the company name field), or we can create both account & contact records, and link the two together. We could also check if the customer already exists as a contact, and then not need to create any records for them.
This means that there will be much less manual work for the agent to carry out, as they won’t have to manually create all of these records.
We’re able to string these together in ‘multi’ step scenarios, to allow things to flow on from each other:
There are also other options available to use, such as the ability to clone, and the ability to open a new application tab. I’ve covered application tabs at https://thecrm.ninja/omnichannel-application-tabs/, so we can see how helpful this could actually be. We wouldn’t need to automatically open a specific system for all customers contacting us; instead we’re able to selectively open things based on the actual customer. This makes for a much cleaner & better agent experience, in my opinion.
In summary, this is a really helpful & useful feature that’s been added, bringing even better functionality to macros. We’ve been able to do these sorts of things elsewhere to date, and being able to do it here now as well is great. All I can say is that I’m wondering what else we could do…perhaps kick off a Power Automate Flow as well? We’ll have to wait and see 🙂
One of the really nice things about the Omnichannel Agent experience is that it uses tabs. The conversation itself is in the left side of the screen, with the Customer Summary open in the right side of the screen. However this isn’t fixed into place – it’s possible to open additional tabs next tot he Customer Summary tab, and navigate to various places in the system.
This allows agents to easily look up additional information on records such as contacts & cases, as well as other places.
Agents are therefore able to quickly flip between different system records, getting the information that they may need to satisfy the customer interaction.
So that’s great. Clicking the + icon on the tab allows new tabs to be opened, and the agent can select which record type they’d like to see:
The system allows movement between these if they disappear off the screen with arrow buttons being available:
So all of this is really good, and is provided as system default behaviour, without any customisation or configuration being needed to be done.
So let’s now think about several other types of scenarios, and see what could be done to enable them:
You want the agent to see a dashboard showing how long the production line is currently taking with different order types
You want to be able to look up an item in another stock system
You want to carry out a custom search in your distributor network
All of the above items (and many more) are things that aren’t native within Dynamics 365. It’s therefore not possible to display this with native system functionality…or is it?
Well, it is! Omnichannel has something called ‘Application Tab Templates’. These allow you to specify custom tabs to open when a chat start. With these, you’re able to point to any web-based resource, even if it’s not within Dynamics 365!
Note: It’s not possible to point to a bespoke desktop application using Application Tab Templates. The resource that you’re wanting to point to needs to be web-based. This is one of the main differentiators between Omnichannel & Unified Service Desk – USD allows you to point to a desktop/server application within the window.
Setting up a new Application Tab Template is not too difficult, thankfully:
We’re able to select what the Application Type should be. There are various options here, including web resources, ‘third party’ websites, entity lists, etc:
When we save the record, we can then input the necessary parameters for that type. These parameters are system-defined, so we have to work within these, and can’t add any additional ones (at this point in time). We can also use values from pre-chat surveys based on information that the customer has provided before the chat starts. Imagine being an agent with a new conversation, and you already have the entire purchase history for them open, or their billing records!
Once this has been created, the next step is to associate it with a session template. Session templates govern the following items:
The behaviour of the chat by default (Docked, Minimized or Hidden
The name of the session
The application tab/s that open (you can add as many as you want to)
The agent scripts that are available to be used.
To do this, open the relevant session template, and then add the application tab/s to it that you want to appear:
Save & close the session template record, and refresh the agent interface. When a new chat session comes in, Hey Presto!
Using the ability to have different chat widgets, it’s possible to customise each one in a different way. So for example:
The Sales team could have the distributor system open, to know how long it’ll take to fulfil an order
The Billing team could have their invoice/finance system open, to have the customer billing history
The Motorbike Servicing team could have their system which tracks all work done on your motorbike open, to see the entire service history
It’s really up to you how you choose to best make use of this. I feel it’s really quite helpful, and will cut down on the time that agents need to spend to pull up different pieces of information to help the customer.
How do you think you would use it in your company? Comment below to share 🙂
With all of that, I thought it would be helpful to take a further look into how sentiment analysis actually works, so that we can understand it a little better.
Now, the actual nuts & bolts for sentiment analysis are provided by Azure Cognitive Services. There are a wide range of tools available through this, but we have no need to go into Azure to configure this. It’s a simple setting within Omnichannel to get it working, rather than needing to fiddle around with many different things:
However, what’s actually going on during a conversation, and how is the sentiment analysis worked out/calculated? We see the pretty little face icons (with the different colours), but how are these actually being set?
Well, there are two ways in which algorithms are used to calculate the sentiment that’s shown:
Natural language processing (NLP)
Machine learning (ML) algorithms
With these two ways methods, it’s possible to not only see what the current interactions are showing, but also to enhance the model to understand sentiment better.
Note: In a session that I presented recently, one of the attendees asked if it’s possible to train the model, to result in a custom algorithm. Unfortunately this isn’t possible to do – the machine learning that takes place is the general Azure one, rather than one for a single company or customer
The following diagram shows the sentiments that are used. They’re nicely colour-coded, for ease of reference as well:
When a customer interacts through Omnichannel, the sentiment shown is based on the last 6 messages received from the customer. As a result, the sentiment shown can very well fluctuate & change during the conversation, based on how it’s going.
Obviously, customers aren’t just going to use English to communicate. Companies are based around the world, and will use their native/local language when providing support. Omnichannel allows for this without an issue, utilising the Azure Text Translator API behind the scenes to provide this. If you’re interested to see which languages are supported for this, head to https://docs.microsoft.com/en-us/azure/cognitive-services/translator/language-support which is the latest source of information for this.
There are some interesting things to know around how this actually works:
When a language other than English is used, the Text Translator API translates the text to English, and then it’s analysed/scored for sentiment
If a language isn’t supported by the Text Translator API, it won’t be scored
If profanity (eg a swearword) is detected, the sentiment will automatically be shown as Negative or Very Negative, regardless of the rest of the last 6 lines of conversation
Some people have expressed their concern to me around how accurate the Azure translation actually is, but to date I haven’t seen any major concerns resulting out from it. As with the other Azure services, Microsoft is continually refining & improving it. That being said, there are several languages with very nuanced terms. I’d like to think that these would be supported without issues.
There is, however, somewhat of an interesting behaviour when starting off the analysis at the beginning of the conversation:
If the initial language is detected as English, it’s assumed that all of the subsequent conversation will be in English. As a result, if the customer switches away from English, the system won’t recognise this, and a Neutral sentiment score will be shown
If the initial conversation is not in English, then the system will check every conversation line & re-detect the language as necessary.
This seems somewhat strange to me, as I’d have thought that the system would automatically check the language for each conversation line. I can think of plenty of scenarios where different languages are used in a single conversation, even if it does start with English being used. I’d like to think that this will be updated at some point, to make the experience better.
Going into Matt’s love of films, and why we think we should set up a ‘Quiz Supper Night’ team as a service to others. Discovering the story of the first data migration that he ever did, and his discovery of the special fields to use when uplifting data into a system.
If you’d like to come appear on the show, please sign up at http://bit.ly/2NqP5PV – I’d love to have you on it!
Click here to take a look at the other videos that are available to watch.
This is about some interesting behaviour around workflows & managed solutions, which I’ve recently discovered. Let me give a bit of background first.
Currently I’m working on several COVID-19 apps for local authorities, to be able to help them assist people in need. As part of this, each local authority has a portal within the solution. The portal itself is a Power App Portal, and I haven’t really had exposure to them before.
Default portal view, not the one we implemented!
Installing a Power Apps Portal comes with quite a large number of solutions in order to get it to work. More on this below.
Due to the way in which we’re engaging with our clients, the solutions are built in a single tenancy (different environments, of course!). We’re then inviting the users in as guests through Azure Active Directory, to be able to access functionality etc. This works well – we don’t need to worry about managing user accounts, AAD permissions, etc. However it also means that we don’t have any Office 365 licenses within the environment itself.
Now we have workflows that are sending emails out around the portal – registrations, password resets, etc. These are being generated automatically by the system, but as there’s no Office 365 mailbox for the user, they’re queuing up.
It’s not possible to authenticate a mailbox belonging to an external user (we tried!), as the system needs a native (full) user with an active mailbox to be able to send out emails. This is of course unlike Power Automate, where you can create a Send Email action and use specified credentials for logging in to send an email.
So, we did what any normal system administrator/configurator would do. We opened up the relevant (managed) solution, and from there opened up the workflow that we needed to modify. Things looked normal at first – we deactivated the workflow, and started poking around it to see what made it tick.
We came across the part that actually took user credentials to send the email that was being generated, and modified this accordingly. Then we saved the workflow, which was successful. However, upon trying to then reactivate the workflow, we got the following error message (helpful, isn’t it!):
Nicely it gives the option to download the log file around the error. This can usually be quite helpful (at times), so we thought we’d take a look at it. Behold the following (I’ve had to shrink the screenshot to allow it to fit on the screen!):
Isn’t that ‘beautiful’. Don’t worry if you can’t actually make out the error information – none of it makes any sense, at least not in a practical sort of way.
Being stuck at this, I thought to reach out to one of the community Power App Portal champions, Mario Trueba. I’ve known him for a while, and he’s just simply amazing. Having asked if I could jump on a call with him for 15 minutes to diagnose (& hopefully find an answer!), we spent almost an hour!
He suggested trying to use the classic interface, as I had been doing all of this through the new UI. So off I went to open up Classic (I’ve missed this, I will freely admit). Through there, we opened up the solution, opened up the workflow, and re-activated it. Or not, as it happens – even through the Classic UI, we weren’t able to do so. We tried a variety of things, but to no avail. It just simply wasn’t happening!
I was slightly concerned that there was an underlying issues with Portals, perhaps from some legacy CafeX code. I had tried searching with Mario for error details contained within the log file, but we couldn’t find anything that would fix it.
The next morning on waking up & checking Twitter, I noticed someone tweeting around Portals, and engaged with them. They turned out to be on the Portals development team, and told me to shoot them over an email with the details, which I did. They then replied to me, saying that it wasn’t anything specific to Portals, and that I should raise a support ticket. That crossed one item off my list (a Portals issue), but I was still needing to get things resolved.
So I went off & raised a support ticket. A few hours later, a very nice tech support person called Siva gave me a call to discuss the issue. We hopped into Teams, and in what I can only describe as the SHORTEST period of time that I’ve ever experienced, the issue was resolved (it took 7 minutes in total. Yes, I know…). Don’t worry – I’m not going to leave you hanging here!
See, what the ‘issue’ (and I’m deliberately putting it in quotes) was turned out to be something quite simple, yet quite strange.
Essentially opening the workflow from the managed solution somehow (& I don’t know HOW) inherits the ‘managed’ property. This is whether we open it from the new UI, or the classic UI. As a result we’re able to deactivate it, but we CAN’T reactivate it due to the system thinking that we’re modifying a managed component (as an aside, it is interesting how I did manage to save it though?). This was what was causing things to fall over, and the error message was really not helpful at all.
It’s also not a matter of being a Microsoft (or ISV) managed solution. I’ve replicated this happening with a solution that I’ve built, exported as managed, & then imported.
So how did we do it? Well, there are two ways in which this can be dealt with:
Either we can go to System/Processes, find the workflow there, open it up, and then reactivate it:
Or we can open up the Default solution, navigate to processes, select the workflow, and then reactivate it:
Both methods work just fine, and as mentioned earlier on, I’ve since replicated this on workflows in other managed solutions.
To me, this is somewhat strange, and should work regardless. According to Siva, it’s the desired system behaviour, though I have no idea why someone should want it to work in one way, and not in another.
So if you’re reading this, and you might just happen to know someone in the necessary Microsoft engineering/development team who’d be able to answer this, could you point them my way? I’d love to engage them to find out why, how, and if they could pretty please change this?