Timing Microsoft PowerAutomate Approval Reminders

In Microsoft PowerAutomate (previously called Microsoft Flow), Approvals are a great way to automate the sign-off on a process or document. Approvals can be actioned right in the email in Outlook as well as in the PowerAutomate phone app or in the web portal.  Unfortunately, sometimes the email notification for the approval gets overlooked and the approval will just sit there until it times out. In this blog I’ll show you how to create reminder emails that can handle the timeout and progress the workflow without failing it.

simple flow chart
Simple reminder flow

The plan is to start a Do Until loop as a parallel branch to the approval step. The loop runs until a variable value shows “complete”. Inside the loop is a delay, then the variable is checked. If the variable value is “pending”, an email reminder is sent to the approver.

When the approval has been processed, the next action sets the variable to “completed”, so after the current delay is over, the loop will end.

This approach is easy to set up, but it has a few issues.

  • The delay period must be completed before the loop can be ended. This can lead to undesired lag. For example, if the delay period is one day, the following can happen: The flow sends a reminder email at, say,  1 pm and a new delay is started. The approver actions the approval at 1:30 pm, but the flow will still wait until 1 pm the next day before the loop is ended and the next action after the loop is carried out.
  • If despite all reminders the approval times out, the next actions after the approval don’t run. That means the variable never gets set to “completed” and the reminders keep getting emailed until the flow itself times out.

Let’s see how to fix this.

Shorten the delay without spamming the approver

For the first issue, I’ll shorten the duration of the delay and use a counter variable that gets incremented in each iteration of the loop.  Let’s say one hour instead of one day (24 hours). We don’t want email reminders to go out every hour, though. The approver would certainly not appreciate getting hourly reminders. I only want to send the email once a day, so before I send the email, I divide the counter by 24 (the number of hours I want to wait between emails reminders) and look at the remainder. If the remainder is zero, the counter is a multiple of 24 hours and the email will be sent. The mathematical term for the “remainder of a division” calculation is the “modulo”. Very conveniently, PowerAutomate has a function to calculate that.

mod(variables('varCounter'),24)

I use that expression in a variable of the data type float and then check if that variable is zero. That way I can see the result of the mod() function in the run history after the Flow has run.

So here is what the Do Until loop looks like now.

Do Until actions
Do Until actions – click to enlarge

Caveat! Be aware that the Do Until action has its own limits for how often it runs and when it times out. The default limits are 60 runs and a one hour timeout. If either of these limits are reached, the loop will end and no more email reminders will be sent. You can change the limits to a higher run count and a different time period, though. Just click the Change Limits drop down. In my scenario, my approval will be set to time out after 5 days, so I’ll set the Do Until to the same timeout limit. The duration is written in ISO 8601 duration format, so for 5 days I need to write P5D.  With 24 hrs in a day and hourly delays that means I need a count of no fewer than 120 hours.

Do Until limits
Do Until limit settings

Now the progress of the approval is checked every hour and a reminder is sent once a day while the approval is still pending.

Managing the approval timeout

By default, an approval times out after 30 days. It will then vanish from the approval portal page, as if it never happened. The Flow itself also times out after 30 days. When that happens, the Flow registers as “Failed” and conveniently (NOT!!) also disappears from the run history, which keeps only 30 days of Flows.

While you cannot do anything about the Flow timeouts, you can change the approval timeout to something shorter and take action while you are still in control. The timeout can be changed in the Settings of the approval action, which you can find in the three dot menu of the action. Change the duration to the value you want to use and set the Retry Policy to None.

Approval Timeout settings
Approval timeout settings – click to enlarge

The screenshot shows a timeout interval of 15 minutes, i.e. PT15M, which I used during testing the flow. I later changed it to five days, i.e. P5D to align with the loop timeout.

The next step after the approval is a condition that checks the approval outcome.  That will be either Approve or Reject if the approval is actioned in time, but if the approval times out, this next action step does not run unless it is set up with a Configure run after.  Click the three dots of the condition step and select Configure run after. Now tick two options, i.e. is successful and also has timed out.

Configure run after
Configure run after

The condition action will now be executed when the approval is completed (a Reject outcome is still a successful outcome). If the approval has timed out, there will be no outcome. I can exploit this behaviour with a nested condition in the No branch. In words: If the approval outcome is “Approve”, send an email with the approval news. Else, if the approval outcome is “Reject”,  send an email with the rejection news, otherwise it must be a timeout, so send an email with the timeout news.

This gives me a handle to deal with each outcome differently.

After that, the varApproval is set to “complete” and within the next hour the loop will exit and the Flow can process the actions following the parallel branches.

Approval processing
Approval processing conditions – click to enlarge

The nested conditions are not pretty, but this approach works. I tried a Switch instead of a Condition, but the Switch will fail after a timed out approval, since there is no outcome. The Condition handles that scenario much better.

That’s it. We can now send reminders, control the timeouts and process the result of the approval.

34 comments

  1. This is very helpful. I am trying to setup for an approval and have one question so far. What is the value for the Increment varCounter?

    Thanks.

    Like

    • Hello, in this scenario, the varCounter is incremented by 1, so with hourly delays it will reach the value 24 1 day after the start of the loop. At this point the modulo will be zero and the condition for sending the email will be TRUE. You could use other combinations, of course, depending on the unit of the delay time frame and the desired frequency of the email notification.

      Liked by 1 person

      • I was trying to check every 10 minutes. So my delay is 10 minutes and my modulo would be mod(variables(‘varCounter’),144) I thought for one day. This isn’t working correctly. Am I thinking this through incorrectly? Thank you!

        Like

      • Yes, there are 144 ten-minute periods in one day. It’s not clear what isn’t working. Maybe you can write a log entry into a spreadsheet or a list after each wait period, listing the current counters and variable values, so you can see what’s happening while the loop is running.

        Like

  2. Hi! Is it possible to have a screenshot of of your variables? We are using this method to approval time off requests so the reminders have definitely been helping. But I am having issues getting the responses to end and stop repeating once completed.

    Like

    • Hi Eboni, varCounter is initialised to 0 and incremented by 1. varApproval is initialised to “pending” and changed to “complete” (all without the double quotes). varMod is a Float data type and initialised to 0. The mod formula is as per above. If you want to check the variables inside the loop while the flow is running, you could use a SharePoint list and create a new item with the variable values. Or, while you’re still developing the flow, use minutes rather than hours as the delay period. That will shorten the wait.

      Like

  3. Thanks, very nice solution. Have you tried this with reassignment? I’ve found that when approver will reassign the task, a new approver will receive notification email. But reminder will still go the old one, and I have no idea how to make it work with new approver.

    Like

    • What dynamic email are you using in your reminder email? I think if you use the dynamic element of “Approvers Email Address” in your reminder email that it will automatically update based on whoever the approval is assigned to no matter the reassignment.

      Like

  4. Thanks, very nice solution. Have you tried this with reassignment? I’ve found that when approver will reassign the task, a new approver will receive notification email. But reminder will still go the old one, and I have no idea how to make it work with new approver.

    Like

  5. Help what have i done wrong – i have set the timeout and tehn setup the nested conditions but i get the following error
    ExpressionEvaluationFailed. The execution of template action ‘Apply_to_each_6’ failed: the result of the evaluation of ‘foreach’ expression ‘@body(‘Start_and_wait_for_an_approval_2’)?[‘responses’]’ is of type ‘Null’. The result must be a valid array.

    Like

    • I have seen this before sometimes after updating the names of the action cards or connections changing from your data. You will want to go and reinsert your dynamic data elements into the action cards that your error message is indicating.

      Like

  6. I would like my flow to check for approval every 5 minutes and send an email after an hour. Much smaller scale of course. I have the delay set as 5 minutes, then add 1 to my counter, and then my varmod formula division setting is for 12 being that there are 12-5 minute intervals in an hour.

    Like

  7. Thank you for the information. If you have multiple approvers and all must approve, does this send a reminder to those who have already submitted an approval decision?

    Like

    • Hi Samantha, I’ve only used this for sequential approvals, where each approval is actioned by only one person. If you want to do parallel approvals, you may want to set up multiple approvals that run at the same time, instead of one approval sent to multiple people. That way, you can track each approval with this method.

      Like

  8. Hi Teylyn,I am a noob in Power Automate,The same can be achieved by having an extra “Delay” action before sending the “Reminder mail”. Total 2 “Delays” One as you suggested within the “Do until” “check approval is equal to complete” with frequency set to 1 minute & then another “Delay” after the logic “check approval is equal to pending” in the “Yes” nest before sending reminder email.
    This way both reminders frequency can be achieved at our likings & as the first delay is set to 1 min frequency immediately 1 min after the Approver response it will move to the next Action or Approver.
    Please correct me if I am wrong as I am a noob.

    Like

    • Hi Sanjoi. I’m not sure I understand what an additional Delay would achieve. You cannot get rid of the loop, because you need the actions to run again (and again) until the approval has been actioned. Having an additional Delay before sending the email would not help with that. Feel free to message me if you want to elaborate.

      Like

  9. Hi, great post.
    Although I wonder what content you put into the reminder email.
    From a user’s perspective it would be awesome to receive the original “approval-email”.
    Because currently I can only send some mail with the text: you should have received a mail a few days ago – please go and find it and try to approve.

    Is there a possibility to resend the original (or a similar) approval mail?
    Do you have any idea how to enhance the usability on this part?

    Like

    • At this point, there is no option to re-send the original approval email that has the clickable button to submit the approval response. My email reminders contain a link to the Approval Center, where all approvals that concern this person can be viewed. As an alternative, you can first create the approval (not with the “create and wait” action, though, just the “create”). Then you can reference the approval to get its adaptive card contents, which you can post to the person in a Teams chat.

      Like

  10. Hi Teylyn,
    I achieved the same having the steps(and also sorted out the loop) mentioned above my me…if you want I will be glad & can share my flow with you….

    Like

  11. Hi Teylyn,

    I was able to get the basic Approval email reminder to work. However I am running into issues with shortening the Delay. Can you please share an over View screenshot of your flow? If possible expand the variables located in the do until.

    Thanks!
    NK

    Like

    • The delay period depends on how often you want to check for a change. I want to check every hour, so my delay period is one hour. That means that each hour, the counter variable will also increase by one. I want to send an email only once a day, so the varMod formula will calculate the modulo for 24, because there are 24 hours in a day. You may want to test this not with hours but with minutes, so you don’t have to wait a week while you test. You may also want to create a new list item in a workflow log list that writes the variable content and other info after each action, so you can see from the log list what the workflow is doing while it’s still running. When everything works as expected, change the Minutes to Hours and delete the actions that write into the log list.

      Like

  12. For example, the system has sent out 2 reminder emails out
    But what if the user approves/rejects by responding to the 1st email? << Since i see that even if an approval is timed out, user can still respond to the corresponding approval email

    Liked by 1 person

    • Hi Jason, The email is just an email. It doesn’t contain any approval buttons. Instead, it just says, “hey, you need to approve this” and contains a link to the approvals portal where the user can see all approvals that they are involved in. Once they action the approval, the approval result will be available to the workflow and it will continue to next actions in the flow.

      Like

  13. Hi Teyln,

    Great article, tried it right away, but have the problem that it does not work in a for each scenario because the variables influence each other. And with a lead time of 5 days I can not turn off the parallelization.
    Any ideao on that?

    Like

    • Hi Bernd, if the variables are set up and addressed correctly, there is no reason why this approach would not work inside a for/each loop. The lead time can be configured. I just used 5 days in this scenario, but you can change it to other time frames. Just make sure that the approval timeout period and the loop have the same time frame. Otherwise there could be approvals with a longer time frame than the loop, and that can lead to confusion.

      Like

      • Thank you Teylyn for the fast response.
        This is strange because I get untraceable variable values when I check the flow after the run. And Power Automate also warns me when I set a variable inside the loop with this message: Enable concurrency control for the apply to each loop and set its degree of parallelization to 1 when using a Set Variable action inside an apply to each loop.

        Like

  14. Hi, Thanks a lot your great solution. However, i have another situation with multiples records should send Approvals (including reminders). PowerFlow doesn’t support variable in the loop (for each), any idea about this case .. ? Thanks again for your time !

    Like

Leave a comment