Tampilkan postingan dengan label Flow. Tampilkan semua postingan
Tampilkan postingan dengan label Flow. Tampilkan semua postingan

27 Agu 2022

Top 4 Fundamental Knowledge To Master Power Automate

Now you want to learn Power Automate but you have no idea where to start? Below are the keys to mastering Power Automate in no time!


You can go to Microsoft Learn to take on self-paced courses on dealing with Power Automate in Get started with Power Automate - Learn | Microsoft Docs. But before that, here are the top 4 fundamental topics you need to master before jumping into Power Automate.

1. JSON

JSON, short for JavaScript Object Notation, is merely a lightweight data transportation format. Quoted from json.org, JSON is easy for humans to read and write. Mainly because the data structure is simple but can fit into different types of data. Imagine JSON is water, very fluid, and can fit into many different containers. The entire IT standards are now revolving around JSON as the format of the data transportation from one system to another.

In Power Automate, JSON plays a crucial element when coming to developing a system. Often we face an error while developing and it's important to pinpoint the core of the issue before we take action to fix it.


Power Automate, even the entire suite of Microsoft Azure products and Office 365, were built around JSON as the data payload. Calling a SharePoint site with API, getting data from Dataverse, and even working with NoSQL databases such as CosmosDB, they're using JSON. Below is an example.

{
  "glossary": {
    "title": "example glossary",
    "GlossDiv": {
      "title": "S",
      "GlossList": {
        "GlossEntry": {
          "ID": "SGML",
          "SortAs": "SGML",
          "GlossTerm": "Standard Generalized Markup Language",
          "Acronym": "SGML",
          "Abbrev": "ISO 8879:1986",
          "GlossDef": {
            "para": "A meta-markup language, used to create markup languages such as DocBook.",
            "GlossSeeAlso": [
              "GML",
              "XML"
            ]
          },
          "GlossSee": "markup"
        }
      }
    }
  }
}
My only reference for learning about JSON is from json.org.

2. Expression

You must also learn how to make Power Automate expression, which is essentially a code you call to get the value you want in every part of Power Automate. If you already know Power Automate, oftentimes you get data directly from the Dynamic content just like below.


But here's a secret, NOT ALL data are presented in the dynamic content. You sometimes have to run the flow to get the precedent actions/trigger data presented in JSON format, and then consume it.


  triggerOutputs()['headers']['x-ms-user-name-encoded']
  

The example above is the code for getting data from the Power Automate trigger, of the username in encoded format.


What if you want to check if the trigger came from a specific IP address that is stored in X-Forwarded-For header? Well, it's the same process.

  triggerOutputs()['headers']['X-Forwarded-For']
  

Now, what if you want to get a value that sometimes exists, but another time doesn't? Just put a question mark in between.


  triggerOutputs()['headers']?['X-Forwarded-For']
  

By giving a question mark, your code will not turn into an error if in the future X-Forwarded-For is not always there, the value returned will be null or empty.



3. OData

Now you know the data is transported using JSON format, how did it get transported? Some systems - if not, every system nowadays - are transported via an API, essentially a web service that you can call using a specific URL. OData itself is a standard most organizations follow including Microsoft, to build RESTful API.

SharePoint Online and Microsoft Dataverse use OData standards to communicate or get the data. This includes all administrative tasks such as get site collection, get environment (of Dataverse), and even the underlying Power Automate designer tool when you are working also uses OData standards. You can try pressing F12 in your browser, open up a Power Automate designer, and see it under the Network tab. That's a whole bunch of OData.


What makes OData unique is the ability to select, filter, expand, and sort, and of course it all depends on whether the vendor conforms to the OData standard. My go-to place to learn about OData is always SharePoint Online, with the reference from Get to know the SharePoint REST service | Microsoft Docs. If you don't have one, you can create an Office 365 Developer tenant via this link Developer Program | Microsoft 365 Dev Center.

Now, you can use Chrome or Edge (whichever you like), and install ModHeader - Chrome Web Store (google.com). This tool helps you to send an HTTP Web Request header along with your URL query. You need this tool because SharePoint Online uses XML to transport the data.

Set the request header just like above, and you're good to go.

4. HTTP Web Request

Knowing the concept of HTTP Web Request is also crucial to better understand how things work in Power Automate. Every single action in Power Automate is essentially a block that will run HTTP Web Request depending on how it was developed.

Most importantly, the concept of different types of requests, to understand how to set a setting of your HTTP Web Request in the Request Header or Body, to retrieve the data you want according you your specification.

8 Mei 2022

Spider Workflow in Action

After my previous post about the conception of the spider workflow, let’s put this into action. Let’s think about multi-level of approvals that you might have in your requirement.

Let’s imagine we have this simple requirement for a workflow in Power Automate, and we need to express the logic in Power Automate using the spider workflow concept. First of all, let’s work the trigger header, because we might need some of the information in it especially which account triggered the workflow.

Next, let’s work on the variables. Like previously mentioned, we need a boolean variable which will be the stopper of the workflow just like a cork of your wine bottle. Next is the entire workflow configuration just like I have shown you earlier (read the previous post for more) but with a little twist.

If you want a quick escape, just copy and paste the following code below.



[
  {
    "Index": 1,
    "Stage": "Review",
    "Status": "Pending Project Admin Review",
    "Type": "CustomApproval",
    "Approval": {
      "Actions": [
        "Checked",
        "Return"
      ]
    },
    "SendAttachment": true,
    "AssignedTo": {
      "AssignmentType": "Custom",
      "Assignee": [
        "radityo.ardi@radityoardidev.onmicrosoft.com"
      ]
    },
    "Outcomes": [
      {
        "Outcome": "Checked",
        "Next Index": 2
      },
      {
        "Outcome": "Return",
        "Next Index": 7
      }
    ]
  },
  {
    "Index": 2,
    "Stage": "Approval 1",
    "Status": "Pending Approver 1",
    "Type": "BasicApproval",
    "SendAttachment": true,
    "AssignedTo": {
      "AssignmentType": "Custom",
      "Assignee": [
        "radityo.ardi@radityoardidev.onmicrosoft.com"
      ]
    },
    "Outcomes": [
      {
        "Outcome": "Approve",
        "Next Index": 3
      },
      {
        "Outcome": "Reject",
        "Next Index": 6
      }
    ]
  },
  {
    "Index": 3,
    "Stage": "Approval 2",
    "Status": "Pending Approver 2",
    "Type": "BasicApproval",
    "SendAttachment": true,
    "AssignedTo": {
      "AssignmentType": "Custom",
      "Assignee": [
        "radityo.ardi@radityoardidev.onmicrosoft.com"
      ]
    },
    "Outcomes": [
      {
        "Outcome": "Approve",
        "Next Index": 4
      },
      {
        "Outcome": "Reject",
        "Next Index": 6
      }
    ]
  },
  {
    "Index": 4,
    "Stage": "Super Admin",
    "Status": "Pending Super Admin",
    "Type": "CustomApproval",
    "Approval": {
      "ApprovalType": "customresponse",
      "Actions": [
        "Complete Request",
        "Return"
      ]
    },
    "SendAttachment": true,
    "AssignedTo": {
      "AssignmentType": "Custom",
      "Assignee": [
        "radityo.ardi@radityoardidev.onmicrosoft.com"
      ]
    },
    "Outcomes": [
      {
        "Outcome": "Complete Request",
        "Next Index": 5
      },
      {
        "Outcome": "Return",
        "Next Index": 7
      }
    ]
  },
  {
    "Index": 5,
    "Stage": "Closed",
    "Status": "Completed",
    "Type": "Closure"
  },
  {
    "Index": 6,
    "Stage": "Closed",
    "Status": "Rejected",
    "Type": "Closure"
  },
  {
    "Index": 7,
    "Stage": "Resubmission",
    "Status": "Pending Resubmission",
    "Type": "Closure",
    "SendAttachment": true
  }
]


Next up, is to parse the JSON configuration well enough so that it’ll save time when you want to reference a specific JSON object property. And the subsequent action is to initialize the first index we need to tag as the first entry of the stages.

Just for your own sake, Index is just one idea to ID the current workflow stage. In the real world, you can use string, GUID, text, numbers, or anything that can identify what is the current stage and it has to be unique.

Now, here’s the heart of the spider workflow. We can’t use a state, pointer, go-to, or something like that in Power Automate to make the flow goes back to the controller. To overcome, we use Do-Until action until the [Keep Looping] variable turns false. You need the [Stop the loop] in case of any error or time out, so it doesn’t go to endless loop. Optionally, you can get the controller’s error message.

[Stop the loop] basically just to set [Keep Looping] to false.

Inside the controller, you probably need to find what is the current stage from the configuration. The next step up, is to filter the parsed body of the entire configuration that come out from [Parse Flow Configuration] action. This is where it gets interesting, you have to filter where the [Index] is equal to [Stage Index] which is 1. Then, parse the JSON value simply by taking the body of [Filter Flow Configuration on Index] which will return an array and take the first one.

Parsing the JSON is always helpful especially when you want to work the flow quickly without doing too many trial-and-error.

But then the next action is just simply notify the requestor what’s the current stage coming up. It’ll be just a message saying “Hi requestor, your flow now is in ___ stage with status of ____”. Simple enough…

Then, you [Switch on Type] that will be the path of your next bus stop of your flow. In this case, we identify 3 different types based on the configuration: BasicApproval, CustomApproval, and Closure. We can put [Closure] under [Default] which makes the logic more broad as if like “if the type is either Closure or everything else, then stop the loop”. Let’s take a closer look how the routing done on approval side.

Now you clearly see, that we’re going to filter the [Outcomes] array where [Outcome] property is equal to the outcome of the flow and return what’s the [Next Index] of that outcome and assign back to the [Stage Index]. Eventually, the loop will be executed once again to see whether it’s the Closure or another step of approval.

No bluff, that’s it!

Last words

Now, all I can say is just congratulations that you now can work with any kind of approval flow. Your stakeholder asks for more approval? No problem, give ‘em that!

But just don’t be too happy first and hear me out. If your workflow configuration is salty, the entire workflow may go ugly too. So, make sure you have done your thought process while thinking out loud what’d be the configuration for this flow.

via GIPHY

5 Mei 2022

Implementing Spider Workflow in Power Automate

There are many patterns to implement different types of workflow using Power Automate. But one that strikes me a lot in terms of the dynamicity, is the spider workflow. There are not much of reference out there, it was (in my work history) implemented in a project in one of the prestigious client in Singapore, sparked by my technical architect.

Drawing1

It’s called spider because… of course it looks like a spider. This pattern can be repeated in many projects and even one can implement the template for it in Power Automate. This pattern mainly to overcome a problem when the workflow is not well-defined, prone to change, or to provide dynamic ever-changing workflow without re-work of the entire workflow.

Implementing Spider Workflow

The main concept of this workflow is to loop the process back to the controller after the decision of the next path. The first step to work this out, is to define how many distinctive tasks that a process can do. In the sample diagram above, there are 5 paths that goes everywhere with one of them proceed to end the workflow. The other four, goes back to the controller to decide what’s the next path after an outcome is reached. In the real-world, it can spawn more than 5 or less, depending on the requirement.

The second step, you need to run your thought process to link up between an outcome with the next path. To give you an example, if say the initial flow goes to Approval first (Path 1), definitely it will have 2 outcomes whether it’s Approve or Reject. You could make a story where after the first approval, it will go to another level of approval if the outcome is Approve (Path 1). Otherwise if it’s Reject, you then decide to flow it to End the workflow (Path 3). If you get the feel of your own thought process thoroughly, you could end up having the exact same flow like in the diagram below.

Drawing2

Now, how do we take care of the workflow’s most important mechanism such as notifying the requestor or setting the workflow status once it’s completing one stage? These mechanism you actually can put under the controller itself since it’s executed every time it passes with another path decision.

Be very careful when you run your thought process, do avoid any process that potentially goes into an endless loop (because it can happen). The design itself is perfect, this endless loop can happen due to misconfiguration. Wait, there’s configuration?

Spider Workflow Configuration

There is a configuration to accompany this flow. You could actually leverage on anything to store, literally. Back in my old days, all workflow data are stored as a row in a SQL Server database. Nowadays, you can just work out the JSON configuration and let the configuration be parsed by the flow. Let’s take a sample on how you can define the JSON structure for just one single stage.


{
	"Index": 2,
	"Stage": "Approval 1",
	"Status": "Pending Approver 1",
	"Type": "BasicApproval",
	"SendAttachment": true,
	"AssignedTo": "Dynamic",
	"Outcomes": [
		{
			"Outcome": "Approve",
			"Next Index": 3
		},
		{
			"Outcome": "Reject",
			"Next Index": 6
		}
	]
}

As above is just a simple sample, you could define your own JSON that depicts the flow process. To summarize,

  • Index – defines the index of this current path.
  • Stage – defines the current stage name (or whatever you want to define as the state of the current flow).
  • Status – defines the workflow status for the current path.
  • Type – defines the path where to go. If you could link this up with the first diagram above, it’s the Path 1.
  • SendAttachment – typically the current controller’s configuration to send attachment to the approver. You can also add your own other configuration.
  • AssignedTo – is also the current controller’s configuration to take the approver list dynamically from a table or database. The other values can also be “Requestor” where it will assign to the initiator of the flow.
  • Outcomes – defines the routing! You can read it simply by say if the outcome is “Approve”, go to the object that the index is 3. Else if it’s “Reject”, go to index 6.

Now, if you run your thought process, you could define a JSON configuration for the entire process just like below.


[
  {
    "Index": 0,
    "Stage": "Resubmission",
    "Status": "Pending Resubmission",
    "Type": "Closure",
    "SendAttachment": true,
    "AssignedTo": "Requestor"
  },
  {
    "Index": 1,
    "Stage": "Review",
    "Status": "Pending Project Admin Review",
    "Type": "CustomApproval",
    "SendAttachment": true,
    "Actions": [
      "Checked",
      "Return"
    ],
    "AssignedTo": "Dynamic",
    "Outcomes": [
      {
        "Outcome": "Checked",
        "Next Index": 2
      },
      {
        "Outcome": "Return",
        "Next Index": 0
      }
    ]
  },
  {
    "Index": 2,
    "Stage": "Approval 1",
    "Status": "Pending Approver 1",
    "Type": "BasicApproval",
    "SendAttachment": true,
    "AssignedTo": "Dynamic",
    "Outcomes": [
      {
        "Outcome": "Approve",
        "Next Index": 3
      },
      {
        "Outcome": "Reject",
        "Next Index": 6
      }
    ]
  },
  {
    "Index": 3,
    "Stage": "Approval 2",
    "Status": "Pending Approver 2",
    "Type": "BasicApproval",
    "SendAttachment": true,
    "AssignedTo": "Dynamic",
    "Outcomes": [
      {
        "Outcome": "Approve",
        "Next Index": 4
      },
      {
        "Outcome": "Reject",
        "Next Index": 6
      }
    ]
  },
  {
    "Index": 4,
    "Stage": "Super Admin",
    "Status": "Pending Super Admin",
    "Type": "CustomApproval",
    "SendAttachment": true,
    "Actions": [
      "Complete Request"
    ],
    "AssignedTo": "Dynamic",
    "Outcomes": [
      {
        "Outcome": "Complete Request",
        "Next Index": 5
      }
    ]
  },
  {
    "Index": 5,
    "Stage": "Closed",
    "Status": "Completed",
    "Type": "Closure"
  },
  {
    "Index": 6,
    "Stage": "Closed",
    "Status": "Rejected",
    "Type": "Closure"
  }
]


Lastly, this blog is just a conceptual idea that you can implement in each project you go on either with Nintex, Power Automate, K2, or any other cloud workflow out there.