Create custom Dataverse triggers for Dynamics 365 Marketing - without a developer!

In the world of Dynamics 365 Marketing (aka ‘Dynamics Marketing’) things have being bit crazy lately and there is some huge changes in motion. One of these is Real-time marketing - if your wondering what on earth that is then check out this link - install it - go play - get excited. Then come back here when you want to start building your own customs triggers based on activity/data in Dataverse (without a developer!).

First the disclaimers

  1. This feature is not yet available in all regions - at time of posting “Real-time customer journey orchestration features are available in the United States, Europe, the United Kingdom, and Australia. The features will be available in Canada and Asia-Pacific geographies in October. Availability in other geographies will be communicated at a later date.“

  2. Using Power Automate for the Dataverse triggers is a ‘work-around’ until something a bit more business user friendly comes along - this is not a supported solution. I would not recommend you adopt it for high volume triggering or any enterprise level use cases due to potential cost/scale problems of using Power Automate to ‘trigger the trigger’

  3. It’s brand new - its going to be quirky and ever changing, be sure to keep an eye here for known issues regularly. Rome wasn't built in a day,

TLDR (Too long didn’t read): Trigger an unbound action in Power Automate to trigger the Marketing Event Trigger

Scenario

I have a custom table in Dataverse called ‘Licences’ which stores all the details of each customer licences including licence type, start/end dates and much more. I want to automate some marketing communication around the customer experience of taking out a free trial license. Not just a ‘hello thanks for starting your trial’ but also providing relevant information along their trial journey, notifying them about pending expiry dates, offering an extension, maybe saying goodbye but hopefully thanking them for their purchase.

Set up Event Trigger

There are already a whole bunch of pre built triggers which come with the installation such as ‘Contact Created’ and ‘Lead Created’ but obviously none for my custom Licence table. Add a new Event Trigger then you will land on the ‘Set up’ stage. This looks pretty easy - define some attributes, so this is the useful stuff that you want to know in your journey to be able to do the smart stuff. For obvious reasons the Customer data is included (either a Contact or a Lead(!) NOT opening that can of worms). Then you can add up to 10 of your own attributes and define their data types, you can call them whatever you want so make them useful so you remember what they are. The syntax I use is TableNameColumnName e.g. LicenseStartDate is the Start Date on the Licence table or AccountUnplugged is a column on the Account table. You will thank yourself later I promise! When you have all your Attributes - Save & Continue.

CreateTrigger.png

Don’t Integrate the Code

So you see a message saying ‘The code snippet can be shared with your developers in a number of ways.’ - my brains says What developers!? Why!? Low code my ass! but fear not, its a decoy! Select Next.

DontIntegrateTheCode.png

Mark Ready to Use

This sounds ludicrous I know, but stay with me. On this page select ‘Ready to use’.

ReadyToUse.png

Your ‘Integration Status’ might look like it’s waiting for something - ignore it and carry on!

Trigger the trigger in Power Automate

Ok so its not that simple this trigger won’t actually work yet, we need to find a way to trigger the ermm trigger. Open Power Automate, create a new cloud flow and choose the appropriate trigger.

When a Licence is created

In my case it needs to be when a Licence record is created. I use the ‘When a row is added, modified or deleted’ trigger. I could also use ‘filter rows’ to trigger only for trial licenses but later on I might want to reuse this flow for creation of other licence types (aka product). So instead I’m going to pass the license product name as one of the attributes and let the user do the filtering in the journey.

If you are using the trigger for ‘modified’ be sure to use select columns and filter rows so that you trigger only fires on the change event you want to trigger for - reducing unnecessary load and noise on Power Automate. It is not an all you can eat buffet! Need help with this? Check out Citizen Can episode 9 & 10!

Get Licence and related attributes with expand

I find that attributes do not always come back reliably from the ‘row added trigger’ so using a ‘Get a row’ action then the magical Expand query I can get all the data I need from the Licence, Product, Contact and Account tables in a single action. This is optional and you could achieve this in other ways you are more comfortable with. P.S yes there is a column called tk_naked and I thank whoever named it that from the bottom of my heart 😂

Trigger the trigger

So the trigger you created in Dynamics Marketing, is actually an ‘unbound action’ that was magically created for you. So now we need to add an action for ‘Perform an unbound action’ then look for your trigger, it will be called mdynmky_yourtriggersnamewithoutspaces. It can be a little slow to load the unbound actions list so be patient.

NOTE: the time from setting the Trigger to ‘Ready to use’ and it being ready/showing up as an ‘Unbound Action’ in Power Automate can take some time - go take a walk outside and sniff the flowers. If you still can’t find it - jump to ‘Can’t find your unbound action?’.

Select the action and before your eyes the attributes you defined earlier will be waiting for you to fill them in. Plus a few other additional ‘friends’, let me explain your new friends, courtesy of the wisdom from the ever helpful Gianugo Rabellino at Microsoft:

  • msdynmkt_signalingestiontimestamp & msdynmkt_signaltimestamp capture when the event was sent from the client (timestamp) vs. when it was actually ingested (ingestiontimestamp) - these can safely be set to utcNow() or to any date/time of your choosing.

  • msdynmkt_signaluserauthid & msdynmkt_profileid in the regular event pipeline first captures the signaluserauthid, then in a separate step the userauthid is resolved it to a full profile to populate the ‘Customer’ parameter. This method bypasses both steps so you need to provide both parameters at the same time. They should be set to the contact ID (GUID). They should be the same.

The rest are your attributes that need to be passed in the trigger which you fetched for the previous ‘Get a row’ action.

TriggerTheTrigger.png

Warning

All attributes are mandatory for the trigger to be successfully fired so if one of your attributes in the unbound action is empty the flow will fail and no trigger will be sent. I suggest you use an operation such as Coalesce() (how to link courtesy of Flow Joe) which will ensure that if the attribute comes back blank, you populate it with something so the trigger doesn’t fail. In my case I used false for all Yes/No columns (yes they can still come back blank!) and ‘NULL’ as the default value for any other attributes.

Yes/No = false

Coalesce(outputs('GetLicenceExpand')?['body/tk_contact/parentcustomerid_account/tk_naked'],false)

Any other attribute '= NULL

Coalesce(outputs('GetLicenceExpand')?['body/tk_contact/parentcustomerid_account/tk_signupstep@OData.Community.Display.V1.FormattedValue'],'NULL')

HINT: now is a good time to test your flow, if the trigger is not used in any live Journeys then it won’t cause any marketing emails to fire in Dynamics Marketing - but we can still check the unbound action is firing and the attributes are coming through ok

Can’t find your unbound action?

The name of the action doesn’t always align to the name of the trigger, for example if you create a copy of an existing trigger - the action name becomes mdynmky_copyofyourtriggername or if you use any special characters in the name such as - or | the underlying name becomes a lovely GUID e.g. mdynmky_a87483hjbdja2.

OpenCodeSnippet.png

To find the trigger name open the code snippet you were supposed to give to the developer and the name will be found in the JavaScript code snippet here (the bit in bold function track_msdynmkt_copyoftriallicenceupdated()

Full credit to Ashraf Omar for finding this one! ⭐

Full credit to Ashraf Omar for finding this one! ⭐

Use the Trigger in a Journey

So the trigger is working and it’s actually ready to use now! Create a ‘Journey’ in real-time marketing (note not a ‘Customer Journey, yes they are different…), Select ‘Event-based journey type then use the lookup to find your shiny new trigger

CreateJourney.png

Branch based on Attributes in the Trigger

Remember earlier the flow was set up to trigger when any licence is created. But this journey is focused on when a TRIAL is created. Good thing we passed the Licence type across in the trigger hey? You can now branch the Journey using the attributes in the trigger - hello LIcenceProductName!

ConditionalJoruney.png

There is so much more we can do with these custom trigger, but that enough mind blowing for one day. Go forth and automate my friends!

Questions and comments always welcome but please be constructive & kind 😊

Handy links

Real time marketing user guide https://docs.microsoft.com/en-us/dynamics365/marketing/real-time-marketing-user-guide

Guides to get you started with Dynamics 365 Marketing by Jesper Osgaard https://lystavlenhistoric.home.blog/2021/06/11/getting-started-with-dynamics-365-marketing/

The magical expand blog post https://www.ameyholden.com/articles/expand-query-lookups-power-automate

The magical expand blog video part one https://www.youtube.com/watch?v=vK0oymNG9Jc

The magical expand blog video part two https://www.youtube.com/watch?v=3FsUsqSovtI

SmallLogo.png

Thank you Calxa

Big shout out to my lovely customer Calxa for being such willing and eager Guinea-pigs to go ‘all in’ on the real-time marketing. It was a bit tricky at times paving the way in an unexplored space but was it worth it? Hell yeah!

Previous
Previous

Set Customer Voice Survey Variables using Dynamics 365 Marketing

Next
Next

Drop down list of options when a flow step is executed