Make a wishing wand - why we need a MicrosoftFlow Custom Connector for MSGraph $Batch

A question that has been in the back of my mind since my late night demo of building a Microsoft Flow Custom Connector for Microsoft Graph is this.

I focused on the "how" - because I wanted to show that the whole thing can be done in about 10 minutes.  And I didn't want to skip steps like "oh here's how you register an Azure AD app".


But (and this is my fault, I did only ask for 10 minutes) I should have spent some time to talk about the "why"

Why do we need this?  What problem does this solve?

Why does John think this is super special?

This is special because, a $Batch connector is a "Send HTTP Request to MS Graph" as me.

It is a wishing wand that grants wishes. Creating MSTeam is a wish. We didn't build a wish. We built a wishing wand. Then we waved it around.  MS Teams API currently is delegate permission only, so we call it through a $batch connector.

Planner API is delegate only.  Any time you see a delegate permission MSGraph you remember you have a wishing wand.

The Ingredients:

Microsoft Flow and Logic Apps has concept of connectors (these are essentially API definitions) and connections (these are instances of connectors bound to a resource as well as cached automatic authentication)

A Flow is a JSON description of how actions and triggers on the connection are chained together to perform automation.

We do have a general purpose HTTP action, and it works very well for app-only permissions that needs client-id/client-secret or client-cert.  But HTTP action is not backed by a connectors framework so it can't remember credentials.

To build a general purpose tool and remember credentials for Microsoft Graph, we have to build a custom connection.  This is basically a swagger API file that tells Flow and LogicApps what APIs exist on the resource.  In the case of MSGraph, that list is enormous.

The Recipe:

The crazy part though, is MSGraph provides a $batch endpoint, so the recipe for building the magic wand is simply this:

  1. Build a custom connection with one method - $batch - this is a POST
  2. Pre-authenticate it with a delegate permission
  3. Wrap requests (1 or many) as a JSON array and call them via the $batch connection.
  4. We have a magic wand

Where do we go from here?

I demoed this with a Manual button trigger.  Jeremy mentioned (in the video) that this can easily be a SharePoint trigger.

This can also be a HTTP Request trigger, turning your Teams Provisioning into one simple HTTP Webservice.  You can hook that up to external systems, PowerApp or a bot.

A technical note

Sometimes you discover you need extra permissions on that Azure AD app.  We do this by going back to Azure AD portal and add the extra permissions.  You can "grant permission" through the AAD portal.

If the cached connection in Flow refuses to work, I find that we may need to right-click on the custom connection and re-authenticate.  Sometimes this requires us to switch to a different user then switch back.  Because Azure AD dynamic consent is just so hard to do.

But it will work.  Just need to toggle a few times.  I do this a lot.