Thursday, December 14, 2017

Provision a Microsoft Flow to a new site

What if...
... you had developed a site provisioning process that creates a new SharePoint site based on a great, custom PnP template.
... all the sites are created identically or have certain identical list, columns, content types.
... the process starts from the creation of a new list item in SharePoint.
... it even reports back to the list to say that it has successfully finished creating the site!

Super sweet! All is well.
Or not? What if the client wants to have a Microsoft Flow (running on new item created in a list) in all of the newly provisioned sites? That smells trouble!

Guess what? Thanks to new Flow management actions in MS Flow it is now possible to build reusable Flows and have them listen to a new list in a newly created site!

Here's how to do it, in general steps. You'll have to adapt it to fit your unique case.

You already have a Flow that runs after the sites have been created, and it has access to the URL of the new site.
Now create the 'template flow'. This is the flow that will have to be deployed on all your new team/project sites.
Create a very simple Flow in order to follow this procedure without too much trouble. Call it something like ReusableFlowMaster
The 'template flow'. Starts when an item is added to a list.
This is a pretty bad example because it updates the same item it runs on, so it will loop a few times. Who cares! It's not about this Flow.

Now that you have a new Flow, you probably think: This Flow holds a unique URL and unique GUIDs to the list it runs on. How are we going to make it reusable..?

From your main Flow that runs after site creation, we 're going to add a few Flow management actions and instantiate a new Flow (based on the ReusableFlowMaster flow) that is connected to a freshly created site.

1. Add an action and search for Flow.
2. Select the action Get Flow and select the ReusableFlowMaster
3. Create a new Compose action. Set it to the Flow definition that comes from the Get Flow action.
4. Now we're going to replace all the URLs and Guids that the Flow depends on so it points to a different list in a different site.
5. Add a new Compose action and put in the expression:
replace(string(outputs('ComposeActionThatHoldsFlowDefinition')), 'originalUrl', 'newSiteUrl') where originalUrl is the site the ReusableFlowMaster works on, and newSiteUrl is the URL to your newly created site. Note that we're casting the Flow Definition to a string and than replacing the old url with the new url.
6. Add a new compose action and put in the expression:
replace(outputs('New_Flow_Definition_-_replace_URL'), toLower('originalListGuid'), toLower('newlistGuid'))
where originalListGuid is the GUID to the list the ReusableFlowMaster works on, and new Guid is the Guid to the new list in the New site. How to get that is out of the scope of this article, doh!
7. Add a new Compose action and parse the previous actions' output to JSON:
json(outputs('YourFlowDefinitionStringWithAllUniqueThingsPointingTotheNewsite'))
PS: Don't give the actions such long titles :-)
8. I'm not sure this is necessary but i'm doing it anyway. Initialize a new variable of type Object and set it to the output of the JSON Parse Compose action. Call it something like FinalJsonObject
9. Now add a new Flow management action - Create Flow. Fill in the following:
Flow display name:  concat(body('GetReusableFlowTest')['properties']['displayName'],guid()). This is an expression, you can select the first part of the concat method by seleting the Display name property of the Get Flow action. You're appending a guid here to the title of the flow in order to make it unique.
Flow definition: Put in your variable FinalJsonObject
Flow state: Select started because you want it to do something right!?
Connection references: Select the button that says you want to input an array. Select the same connections that you got from the Get Flow action.
10. You're done!
11. Run the flow.
12. It Fails!!! Oh noes! The error is something along the lines of 'request is invalid and could not be serialized at line 4 column 1929'.

Ok, what you have run into is an issue with the MS Flow GUI. The way it has saved the variable with the FinalJSonObject does not work with the Create Flow action. Luckily a certain John Liu already found a solution.
What you need to do is export this flow to a zip file. Unpack the zip and in it (a few folders deep) is a definition.json file. Open it and search for @{variables .
You will find, for example: "@{variables('FinalJsonObject')}"
FinalJsonObject is the variable name you chose to put in the Create Flow parameter Flow Definition.
This syntax is incorrect. It needs to be like this "@variables('temp')" so without the accolades {}
Save the file and put together the zip file again in the same way as you unpacked it.

Upload the zip to Flow and give the Flow a new name. This one should work!
You can also still edit this flow, but I assume you should not touch the Create Flow action anymore otherwise you'll have to take the steps of manually editing the flow definition again.


Your main Flow will now generate a new, unique Flow based on a 'template' and attach it to a freshly created site!



Word of warning: Seriously test this solution if you want to use it, and think about how you would do about updating all the instances of the ReusableFLowTemplate once you've created dozens of Flows connected to new sites. I just did this as a Proof of Concept, it's not a solution of industrial strength.
Also, in case you want a more extensive Flow in the site, take note that anything unique in the Flow related to the site, URLs, lists, etc will have to be replaced by the actual values for the new site you're connecting to. If all your sites are provisioned with PnP a lot of the Guids of content types and columns will already be the same in each site. but for example list Guids are always unique. You will need to save the ReusableFlowMaster to JSON and check out the contents to see what you have to update in it.

4 comments:

  1. Great article. But I am getting an error. Any one else getting the same on the create flow?

    InvalidTemplate. Unable to process template language expressions in action 'Create_Flow' inputs at line '1' and column '2551': 'The template language expression 'concat(body('GetReusableFlowTest')['properties']['displayName'],guid())' cannot be evaluated because property 'properties' cannot be selected. Please see https://aka.ms/logicexpressions for usage details.'.

    ReplyDelete
  2. Since it is missing, and maybe useful:
    To get the list guid (sp online), just go to list settings and the guid can be spotted in the settings page url tail.

    ReplyDelete
  3. You made a meaningful contribution to this blog post. The processes you have discussed here has given us a more focused direction. Wordpress website optimization

    ReplyDelete
  4. Thanks for this significant contribution from your side. Good work! flowers dubai

    ReplyDelete