Taking PDF snapshot of any SharePoint list item for approvals with Flow

This is a post about combining two steps I've blogged recently.  Combined they form a technique that can be used with approval workflows to provide a point in time snapshot.

I have been building up a library of really useful Flow blocks.  Because you can combine them in pretty interesting and important ways.

Flow: List Item to PDF

  • Using Flow-Each - we iterate through each property of the SharePoint List Item
  • Use Select to map each property and its value to an array
  • Use Create HTML table and we have a table
  • Sprinkle some CSS for decoration
  • Send to PDF

PDF Result

This isn't too bad - definitely workable.  Need some cleanup.  But right away, we can already do:

  • Send pre-approval list item (or document metadata) as a PDF attachment along with the approval email
  • Save a post-approval list item as part of the record keeping process.

Bonus Points: Clean up HTML

  • Create new JSON with just Author and Editor's email (you can also use DisplayName)
  • Union that with Get List Item
  • Use the new result as the Object to continue.
  • Add Filter-Array after Flow-Each
  • Create new Array, keep only elements that doesn't contain _x
  • Use this in the Pivot arrays to table

PDF Result: round two

pdf-second.png

A successful run

This is how everything looks at the end.  This doesn't show the details of each step, but is intended to show you how all the pieces look together at the end. 

Final thoughts:

  • Special thanks to Andrew Jolly who commented in an earlier blog post that we can use PDF to create records
  • I use this as a Nested Flow as part of our Approval workflows to create PDF snapshots of list items. 
  • Create PDF as attachment along with the pre-approval email
  • Create PDF as snapshot after approval
  • If you want to use SharePoint's Records Management features - you can declare the PDF as records.  You will need a simple AzureFunction to do this.
  • Lots of techniques for manipulating JSON - filter, select and union
  • You can use For Each as well, if you are using that - then it's better to use Array Variable, and use the Append action.

Oh, I went out of my way to not use variables - they are overrated if you don't want to use For-Each

  • Special mention to the Culmsee's that you don't have to use variables if you want to keep things pretty ;-)
no-variables.png

You must copy all your Flows to SharePoint - simple ideas are the most brilliant

Another crazy idea while travelling on the train home.  This one is so simple, in hindsight, I reckon others will come up with this soon.  So I'm writing this first.

When I was testing the idea on Friday night, I did a livestream hack and that's on Mixer https://mixer.com/Sousily?vod=12283142 - skip to 13:50 that's when we started the hack.

Plan

Copy all your Flow definitions to SharePoint
On File Change, push your change from SharePoint into Flow
(TODO warning: make sure you don't create an infinite loop)

Why SharePoint

Primary benefits:

  • Backup
  • Versioning - see changes
  • Kick-ass built in JSON Editor for advance hacks
  • For your team to collaborate
  • And by the end of this blog post - you can push change back into Flow, you have both Backup AND Restore.

Copy all your Flow definitions to SharePoint

some notes:

  • You don't need the Filter array if everytime you run the Flow you will copy everything into SharePoint
  • I only want to do "changed in the last day" filter, because I want to put this Flow into a Schedule
  • Then in SharePoint, because it has versioning controls, I will only see an updated version if the Flow was changed that day 

SharePoint JSON Experience

A big thank you to Sohail Merchant who told me how to get to JSON Editor via the Preview Panel in SharePoint.  I was going to write this whole post about using OneDrive for Business.

In May 2015 - I put up a SharePoint User Voice request to allow .json as an allowed file type in SharePoint and OneDrive.  This was done and rolled out in October 2017.  

But the SP/OD team went beyond and included a JSON editor.  Which is why we have this kind of amazing integration between products.

Wonderful.

On File Change, push your change from SharePoint into Flow

The dance with Update Flow action is very delicate.  The note is:

  • Set definition to string variable first
  • Update Flow will now 'see' this variable, and let you assign it
  • Then change the object definition back to "Object" type

You must do these steps or it won't work

Nearly

Make sure you check On Change - Upload.  I suggest you use a different account to write Flows to SharePoint.

Then On Change - if the Modified By is this Flow account, skip the upload.

Otherwise the schedule trigger will download the Flows, and trigger the File change which will upload the Flows and tomorrow the schedule trigger will re-download the Flows.  It would be quite silly.

Now we are in an Awesome place

Look at all the Versions

 

Simple ideas are the best ideas.  You need to build one of this.

Immediate Next Self-Inception-Hack

Any time, you think, hey I have a tool that can update itself.  Then you realize Flow is Self-Hosting.

And you can use it to improve itself.

I have a For-Each in the Copy Flows to SharePoint

So I immediately hacked parallel settings into the first Flow above.

scan-flows-faster.png

Scanning changed Flows is now faster.  (slightly, since the for-each is in parallel).

 

 

ForEach Property in #MicrosoftFlow JSON. With XPath? #microblog

I can't think of a way to do "ForEach Property Of JSON" in MicrosoftFlow or LogicApps - so I came up with this method that involves XPath.

Take example this JSON

{
  "a": 1,
  "b": 2,
  "c": 3
}

I want to do ForEach over the properties, so I need a way to convert this into:

[
  "a",
  "b",
  "c"
]

The usual suspects don't seem to work:

  • ForEach (only array)
  • Data Operations - Select (only array)
  • Array (wraps one object into array of one object)
  • CreateArray (wraps multiple objects into array)
  • Split - this could be used, but we'll have a hard time with nested JSON

Lets do XPath

XML objects must have one root element.  So let's wrap a root around our JSON

{
  "root": {
    "a": 1,
    "b": 2,
    "c": 3
  }
}

This next XPath splits each XML element under /root/ into a Nodeset (array of XML elements).

xpath(xml(outputs('Compose_2')), '/root/*')

Data Operations - Select

for each XML node, select just the name, map this for each node

xpath(item(), 'name(/*)')

Result

[
  "a",
  "b",
  "c"
]
for-each-json.png

I'm sure there'll be a better way one day.  But for now this will get me through.  I need this to be able to read nested JSON structures as part of my bigger plan.

Microsoft Flow makes everything Awesome. Yes, including InfoPath #microblog

This is a write up of various ideas and thoughts that I've shared over Twitter separately, but needed to be linked together and the example steps needs to be explained in a bit more detail.

Plan

On Reading many XML Forms in a Forms Library

Crazy InfoPath and PowerApps cross-app idea

with game state managed with Microsoft Flow, with JSON and XML dual binding.

API Management TIP

from @darrenjrobinson

Flow Details

In this Flow, we will do something fancy.  We will use the new Flow Management connector to list all the Flows in my environment.

Configure the HTTP Request method must be GET
The response must be XML - use xml() to convert JSON into XML output.

Check this in Postman

This is how you test a webservice.  You poke it with Postman.

check in postman.png

See this returns XML.

The rest is done in InfoPath

Connect it via REST connection.

data-connection.jpg
infopath-datasource.jpg
flow-run.jpg
infopath-run.jpg

This is pretty amazing.  InfoPath is listing in a repeating section the names of all the Flows I have in my environment.

Result

  • Because of Flow, InfoPath got server side superpowers it never had
  • Flow gain the ability to work with Managed Metadata today.  And so did InfoPath.  Only 7 years after MMD was shipped without InfoPath support.
infopath-meta.png

Flow is awesome.

Sending Custom Actionable Messages via Flow

Actionable Messages is a way that we can send a small bit of JSON within an email message, it gets picked up by Outlook (Web, App, Desktop, Mobile) and parsed as quick actions, or a way to collect additional information.

We can easily create Actionable Messages with Microsoft Flow, and this will extend our ability to build "disconnected human workflows"

Plan

  • Use MessageCard Playground to build our JSON
  • Send Actionable Message via Microsoft Flow as HTML embed

Message Card Playground

https://messagecardplayground.azurewebsites.net/

Use Message Card Playground to quickly try a few templates and see the JSON we need to build.  

Microsoft Flow's "Send with Options" as well as "Approval" actions use Actionable Messages - you can see the templates that's used.

Build a custom message with Flow

The Flow is quite simple.  A trigger, build a custom HTML string, then Send Mail with HTML.

flow.png

My test compose has this JSON

 <script type="application/ld+json">{
    "@context": "http://schema.org/extensions",
    "@type": "MessageCard",
    "originator": "Provider-id-from-developer-dashboard",
    "hideOriginalBody": "true",
    "themeColor": "0072C6",

 "sections": [
        {

            "heroImage": {
                "image": "https://minecraft.net/static/pages/img/addons-feature.8b0a274be963.png",
                "title": "This is the image's alternate text"
            },

    "title": "John how are your Flow and Minecraft doing?",
    "text": "Click **Learn More** to learn more about Actionable Messages!",
}],
    "potentialAction": [
      {
        "@type": "ActionCard",
        "name": "Send Feedback",
        "inputs": [
          {
            "@type": "TextInput",
            "id": "feedback",
            "isMultiline": true,
            "title": "It is doing great!"
          }
        ],
        "actions": [
          {
            "@type": "HttpPOST",
            "name": "Send Feedback",
            "isPrimary": true,
            "target": "http://..."
          }
        ]
      },
      {
        "@type": "OpenUri",
        "name": "Learn More",
        "targets": [
          { "os": "default", "uri": "https://docs.microsoft.com/en-us/outlook/actionable-messages" }
        ]
      }
    ]
  }
  </script>
<p>
Hello, please take an action.
</p>

A few notes - I did not register this JSON, so I'm only sending this to myself for testing.  This will ONLY work within my current tenant and internal email addresses.

Additionally, this doesn't seem to work on mobile Outlook.  I assume if I'm taking this to mobile I will need to submit and register the action.

https://docs.microsoft.com/en-us/outlook/actionable-messages/actionable-email-dev-dashboard

Make sure Send Email sends HTML

send-option.png

Results

I receive this in my Outlook (Web) mailbox.

email.png

What can we build with this?

In the JSON for Potential Action - we can specify HttpPost actions.  This is idea to chain into a new Flow action and start a new step.

I think about the "Pick your own adventure books".  Each time this runs, it presents me with the next chapter of the story, with buttons that lets me choose what's the next step to take to continue my journey.

So this is another piece of the tool that we can mix into our toolset.