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
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.“
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’
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.
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.
Mark Ready to Use
This sounds ludicrous I know, but stay with me. On this page select ‘Ready to use’.
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.
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.
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()
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
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!
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