Managing Preferences, Consent and Subscriptions with Dynamics 365 Realtime Marketing
**IMPORTANT UPDATE FEBRUARY 2024**
The below solution uses msdynmkt_contactpointconsent2 but due to changes in the product to support business units and multi-brand consent compliance profiles a new table has been created called msdynmkt_contactpointconsent4 you will need to amend the below solution to work in alignment with the new table and data requirements
Following on from my previous blog post on how to trigger a flow when a marketing or subscription list is updated, this post will show you how to automate the update of contacts consent and marketing permissions so that it aligns with the subscription changes made.
TLDR: don’t unnecessarily block marketing emails - hide all the Realtime marketing consent stuff and automatically update both the Marketing Allow/Do Not Allow and the Contact Point Consent records when a customer updates their ‘Outbound’ subscriptions.
Why do we need this?
Dynamics 365 Marketing is in it’s transition from Outbound Marketing (childhood) to Realtime Marketing (adulthood), right now we are riding the rollercoaster of adolescence. Whilst exciting new features and enhancements are landing on a monthly basis, a few things aren’t quite there yet (growing pains and mood swings). The safe option is always available - stay with Outbound Marketing until Realtime Marketing has become more matured and established but where is the fun in that? One particular (and very important) feature that’s going through a big transition in Dynamics 365 Marketing was previously known as ‘Marketing Permissions’ but now referred to as ‘Consent’. It gets even more complicated if we start layering in SMS consent or any other marketing channels, so lets stick with email for now.
Outbound Marketing Permissions Customer consent is stored per Contact record ‘Record based’
Realtime Marketing Consent Customer consent is stored per email address or phone number ‘Contact-point based’
Ideally you would use one or the other. With all my customers I apply the rule of ‘Realtime first’ so if we can use Realtime marketing to achieve the desired outcome - we will. The current Realtime Marketing Consent page is an eyesore and cannot be customised (except the text wordings), there is also no way to support subscriptions. The Outbound Marketing Subscription centre is full customisable for you to style according to your brand, you can use it to manage subscriptions ad also for users to update their data if you so desire. I know which one I would choose.
“Use outbound subscription centers in real-time journeys”
Yes it’s a thing - you CAN have your cake and eat it (kind of), this article shows how to set it up nicely and a seriously recommend you do it. However, it doesn’t take into account the need to synchronise consent changes across the consent models. If a contact has Marketing Emails to allow and active subscriptions, their email can still be blocked if they also don’t have their ‘consent points’ set to allow - it’s good that its erring on the side of caution (don’t send without full consent) but absolutely crushing that you are missing out on potential new customers who have given you their consent to be marketed to.
The solution (according to Amey - for now)
Step 1 - implement this so that you can act when a subscription for a customer is updated
Step 2 - hide everything Realtime consent based from the forms (yes it’s pretty but it’s not ready for the world yet) - NOTE: hide don’t delete, its easier to get back later - future you will be grateful.
Step 3 - get your good friend Power Automate to synchronise a customers subscription/marketing preferences into their contact point consent. We will need two flows - one that is triggered as a child flow after a subscription is updated, and another child flow that is triggered when this action is complete. It could be wrapped into a single flow but the separation means I could use the flows independently of each other for other pieces of automation.
After Subscription Updated - Set Bulk Email Permissions
Welcome to Step 3 - image of the complete flow end to end can be found here -> After Subscription Updated - Set Bulk Email Permissions
_entityid_value eq _YOUR_MemberID_VARIABLE
The Contact might not belong to any Marketing Lists at all
Add a Condition action which will filter to check if the ‘ListMarketingMemberships’ search returned any results - if not we can assume they need to be unsubscribed. In the ‘No’ pathway add a compose action which simply sets the value to ‘true’. Why true you ask? We just said there were NO subscriptions and they are unsubscribed. Because the ‘Do Not Allow Bulk Marketing’ field is the most confusing double negative backwards logic I have seen in my life.
true = Do Not Allow (Marketing Emails)
false = Allow (Marketing Emails)
empty(body('ListMarketingListMemberships')?['value'])
//FILTER msdyncrm_issubscription eq true and listid eq MARKETING_LIST_VALUE //INCREMENT if(empty(body('ListContactsSubscriptions')?['value']),0,1)
One or more subscriptions?
Outside of the ‘Apply to each’ loop, but still inside the ‘Yes’ pathway on the condition we can add another Condition action to check to see if the ‘NumberOfSubscriptions’ variable is greater than or equal to 1, if ‘Yes’ their Marketing Permission is Allow (aka false), otherwise Marketing Permission is Do Not Allow (aka true). Set the value accordingly in each branch using a compose action.
We need to come back here later to call the subsequent child flow (grand child flow?) but we need to create it first
Sync Bulk Email Permissions to Consent Records
Now that the Bulk Email Permission is correct, lets align the consent records accordingly. This will be run as an ‘Instant’ child flow, it will take two inputs - the contact email address and whether they have ‘Allow’ or ‘Do Not Allow’ for their marketing email consent. Admittedly this is not the most efficient flow I have ever built and could easily be chopped down to less actions but at the time this set up was really handy for debugging and getting things to work smoothly.
Image of the complete flow end to end can be found here -> Sync Bulk Email Permissions to Consent Records
NOTE: you need to have a Dynamics Marketing sandbox or full license installed where you build this, the flow will not run successfully in a ‘solution only’ marketing instance - trust me I tried it.
msdynmkt_contactpointvalue eq '_YOUR_EMAILADDRESSS_INPUT'
SWITCH! (Hey! Hey!)
Using your integer variables from earlier, add a Switch statement and set the corresponding integer values for the Consent Status and Reason on the Contact Point Consent record based on whether the response for Marketing Permissions was Allow or Do Not Allow. No Default case here because if it’s not Allow or Do Not Allow then something else has gone very wrong.
Update existing consent
Add a condition action to check if any consent records were found already existing for that email address. If yes - go and update them. Add an ‘Update rows’ action to loop through each consent record (the apply to each will create itself for you) and use the variables you set earlier to update the records. You can add whatever you want to the ‘Who requested the change’ box - but it’s useful to know where this update came from.
empty(body('ListConsentRecords')?['value'])
Call the grandchild!
Last but not least… we have to tie it all together. GO to the first flow you created ‘After Subscription Updated - Set Bulk Email Permissions’ and add a final step to call the second flow as a child. Be sure to send the Bulk Email output as the word version (Allow/Do Not Allow) rather than true/false mostly because it is confusing but also because your switch statement is looking for the human words too.
outputs('GetContactOData')?['body/donotbulkemail@OData.Community.Display.V1.FormattedValue']
And with consent - they all lived happily ever after
If you actually made it this far I will be surprised and impressed - I can’t say this is my most thrilling or ‘sexy’ post but this stuff is important to get right, and expensive if you don’t. This is my best attempt at a visual summary, ENJOY!