DEV Community

Cover image for Creating a Power Automate Flow in Code
david wyatt
david wyatt

Posted on • Updated on

Creating a Power Automate Flow in Code

The biggest strength of Power Automate is it's user interface, based on the Logic App UI, but even more user friendly, it's why anyone can create amazing automations.

So why would anyone want to create a flow in code instead of with the UI, I have no idea, but I did anyway.

How it Started

I first got interested in the code of a flow when I had to update 500 flows (they didn't have connection references so I didn't want to have to manually update every connection when deploying to a dedicated environment).

Looking at the definition.json I was able to identify the connections of the flow. So I made a flow that read the definition, did a replace with connection reference, then updated the json. And now I I had 500 flows that now only need 3 connections on import, not 1500!

A few other occasions I find editing the definition beneficial, generally for find and replaces or validating complex expressions. But exporting, copying out of zip, updating, copying back and then importing, was far to cumbersome. And then I found this chrome extension Power Automate Tools


Edit Flow live in Code

When editing a flow, click the extensions button and it opens the definition to edit and save right in the browser.

Image description

Best of all, it has intellisense and even the same Validation check as the UI does:

Image description

Image description

So now I had the tool to properly edit/create in code. I would start a new flow in the UI and then flip to code, after looking at examples, and reading the schema Microsoft.Logic/schemas I was able to create working flows pretty quickly.

Image description


Basics

The definition object is quite simple, with all actions/steps in a actions node (this is the same for container steps -steps that have actions/steps inside like Scopes and Conditionds).

The basic action structure is:

 "Name_of_Step": {
      "runAfter": {
        "name_of_previous_stepAction": [
          "when"
        ]
      },
      "metadata": {
        "operationMetadataId": "idNumber"
      },
      "type": "type",
      "inputs": "inputs from action/step"
    }

Enter fullscreen mode Exit fullscreen mode

An example would be a compose, named Get_id, which runs after an excel list all rows action, and has an input which is the utcNow() expression:

"Get_Date": {
      "runAfter": {
        "List_rows_present_in_a_table": [
          "Succeeded"
        ]
      },
      "metadata": {
        "operationMetadataId": "df2acb42-3954-4b98-b8d9-g571120509"
      },
      "type": "Compose",
      "inputs": "@utcNow()"
    }
Enter fullscreen mode Exit fullscreen mode

Image description

Actions will have additional nodes in inputs, like host- connection info, parameters- inputs from user and authentication (generally always the same):

"authentication": {
          "value": "@json(decodeBase64(triggerOutputs().headers['X-MS-APIM-Tokens']))['$ConnectionKey']",
          "type": "Raw"
        }

Enter fullscreen mode Exit fullscreen mode

Containers are very similar, but just have the actions node which contains all internal actions/steps.


Definition Tips

A top tip I found was a useful website called www.objgen.com, which converted simple text into json, helped speed up my workflow no end. It meant I had to have 2 windows open, and some copy and pasting, but definitely was quicker.

Image description

You can use the 'Peek Code' in the UI to see parts of the action/steps code.

Image description

Other interesting things I found out about the definition.json was

Order
The order of the steps/actions isn't related to order in the Json (the order is when the step was created). The runAfter key is what dictates the flow order, except within containers (steps that contain other steps like Scopes and Conditions). With these the first step within them is the flow order, as these steps don't have a runAfter(because in the flow they don't, they use the containers)

Object Structure
Within the steps the order of the keys doesn't matter, but with the UI generated the order isn't consistent

e.g runAfter

  • Standard Action: at beginning of object
  • Condition: before else

Or type

  • Standard Action: near beginning
  • Scope: at the end

Optional
Not all keys are required, biggest example is operationMetadataId

"metadata": {
    "operationMetadataId": "e76eee77-177d-47ef-b5c2-973ba7c29615"
 },
Enter fullscreen mode Exit fullscreen mode

This can be removed and has no impact (the operationMetadataId key was only added recently, some legacy exports won't have them).


Results

So would I recommend creating flows in code, the answer is hell no. When I said I could make working flows, I neglected to say only basic ones. Why... well:

Speed of the UI (especially with the complexity and inconsistencies of all the steps/actions) is faster then code.

Populated inputs (like listing SharePoint Sites), are auto populated by built in he api calls.

Selection of GUID's through dropdowns (e.g selecting mailbox folder by name in Outlook actually selects folder GUID). Trying to track down these GUID's can be almost impossible, let alone in anyway quick.

Expressions/Variable list, having them to hand is so much easier than trying to remember them all.

Order having to key order in the runAfter is a lot harder then the natural order in a UI, it's so easy to get wrong but not see.

But, and this is a big but, editing in code is incredibly useful. Where starting from scratch it is just to painful, but doing updates is really useful:

Updates with find & replace are so much easier.

Image description

Validating/Code Reviews can be so much easier buy just finding keys, like checking all the runAfter keys are right or Get action have Pagination turned on.

Editing huge/nested flows is not fun in the UI. I've had flows so big or nested that the browser struggles when every step is opened up. Doing edits in the code will never hang your browser, and using the find allows you to jump straight to the step instead of searching.


I don't think I really expected to replace the UI with code, but I was surprised how useful I found it as a tool. Flipping between UI and the code review more often than I thought. Shout out to Kamil Rithaler, the developer of Power Automate Tools, it's a great tool which without it editing in code isn't practical, and it's free.


Further Reading

Top comments (0)