Amey Holden

View Original

‘Distribution List’ Emails and Appointments with Power Automate

Following on from my previous post, where we created a custom page that allows you to send emails or appointments to a list of contacts, such as a distribution list. This post will focus on building out the power automate flow that does the magic behind the scenes of the custom page.

Quick recap GIF at the bottom of this page or check out the post: ‘Distribution Lists’ in model-driven apps

Find or fail

Since the user accessing the custom page is doing that from within Dataverse I can be pretty sure they do exist as a user but it’s always nice to fail gracefully. The condition checks if any data has come back from the list rows action, if yes we can capture the Dataverse GUID for later use, if not - you have bigger problems.

UserFound
Action: Condition Control
Condition:
empty(body('LookupUserID')?['value'])
is equal to
@{false}

True - UserID
Action: Compose
Inputs: first(outputs('LookupUserID')?['body/value'])?['systemuserid']

False - Terminate
Action: Terminate
Status: Failed

Find the relationship name

For this part, you need to know the relationship name between Contact and your list table, in this case ‘Distribution list’. Yours may be different to the relationship table name/the one I used below. In your solution you can find the correct relationship name to use in the filter below.

Combine the Distribution List members into an array

In this step we will turn a comma separated string of GUIDs for each Distribution List selected, into a list of contacts who belong to those list(s). It appears in this step I had a moment of insanity and used the inputs directly from the trigger, oops.

UniqueListOfContacts (loop)
Action: Apply to Each
Output from previous step: JSON(triggerBody()['text_2'])

GetContacts
Table name: Contacts
Action: List Rows (Dataverse)
Select columns: contactid
Filter rows: (statecode eq 0 and emailaddress1 ne null) and (TABLE-RELATIONSHIP-NAME/any(o1:(o1/DISTRIBUTION-LIST-TABLE-GUID-NAME eq @{items('UniqueListOfContacts')?['Value']})))

Union-MergeRemoveDuplicates - this step allows us to combine the array on contacts generated from the list rows step, with the array on contacts already on the list, rather than appending each contact one by one. It also removes any duplicate values as once contact could belong to many lists.
Action: Compose
Inputs: union(outputs('GetContacts')?['body/value'],variables('ListRowsArray'))

SetListArray - you cannot use the variable value within the setting on variable, hence using compose first then setting the variable (not appending) with the new combined list
Action: Set Variable
Value: outputs('Union-MergeRemoveDuplicates')

Create appointment or email?

Finally, the hard work is done, now we just need to pull it together by checking if we need to create an email or an appointment. In this case its either Appointment or Email but you could scale this out to more activities and use a Switch Control instead.

Appointment
Action: Condition Control
Condition: outputs('ActivityPartyType') is equal to Appointment


The end

Hopefully by now you have been able to put together the custom page in this blog post and this flow, to be able to manage your Distribution Lists in your model driven app. If nothing else I hope it got your creative juices flowing on other ways you can build similar things like this that would otherwise be custom code, a bad UX or just a no can do.

P.S In case I lost you anywhere along the way you can find below an image of the full flow end to end. I like to use parallel actions where possible in the hope of it being a little bit quicker but it’s definitely not essential.