Workflow Lazy Approval
What is lazy approval? It is the ability to reply to an approval email with the word “Approved” or “Rejected”, without need for the approver to go to a site in SharePoint. With the mobile workforce, this is a feature that is in high demand, for people to quickly be able to read an email and approve or reject instantaneously. In this blog post, I’ll show how this can be done with SharePoint 2013, specifically with SharePoint 2013 workflows. This is only an on premises solution, and is NOT available in Office 365, this specific solution also cannot be done with a SharePoint 2010 workflow. Office 365 does not have the functionality that SharePoint on premises has, where you can turn on “incoming email”. On premises, this is something that your SharePoint server admin had to have set up at the server level.
Incoming email can be used for Document Libraries, Announcement lists, and Calendars.
When you turn on incoming email in a list or library, you assign it an email address. In this solution, this will be useful for lazy approval, because the approval email that they send can arrive in a SharePoint list, and then a workflow can go out and complete the associated task automatically.
The components of this solution:
- A request form that needs to be approved. My example is a very simple travel request form. This has been created as a custom list.
- A task list. In this example, I’m just letting the workflow use the default “Workflow Tasks” list on my SharePoint team site.
- An Announcement list. When I created this list, I used the “Announcements” list template. I named this list “Approval Email”.
- Approve Travel. Running when new items are created in the travel request list (1)
- This is a site workflow, and will wait for emails to arrive in the announcement list (3)
Some of the trickiest workarounds we’ll be dealing with in this solution are the lack of list relationships. First of all, task lists are inherently not related anything. There is no lookup field that connects a task to the thing that is being approved. So we’ll have to use the task name as a unique field. Also, when we receive incoming emails, they will not be related to anything either. Another challenge is that when you create a workflow ON the list where the emails are arriving (3), the arriving items do not trigger a workflow. This is why our workflow will be triggered in a different way. I’ve heard about people making configuration changes on the server or doing something with PowerShell to make this work, which would also make it work in 2010, but this solution is NOT going to make you do server changes.
My associated video:
Here’s how to build this.
- On the approval email (announcement) list (3), go to list settings, and click Incoming Email Settings. I used the following settings. In this case, I only need simple information as to whether or not something is approved. The subject and body of the email will automatically fill in the Title and Body fields in the list. I don’t need any email attachments, and I don’t need the original *.EML email file. Also, I chose the email security policy to accept messages based on permissions. That way, I can let only a certain group of approvers have Contribute permissions on this list, and no one else. That way, I won’t get random other people trying to send email here, or approve things they’re not supposed to approve.
- Create the SharePoint Designer workflow, Approve Travel, on the list of travel requests. Set it up to run when new items are created.
- For the first action, use “Assign a task” or “Start a task process”. I usually prefer the first one for several reasons, one to point out for this solution is that the task name will be identical for all tasks that get assigned for any given travel request. I named my stage Assign Task. Click the blue this user.
- For the participant, pick a user or group. For the task title, pick just the ID of the current item. Yes, in real scenarios that is not a feasible task title, but we will make this more complex later as we go along.
- Expand Email Options, and click the first Open email editor button, for the task creation email.
Don’t forget, you may want to modify the task overdue email in the same way, if you use these and if you want your users to have lazy approval links in these emails as well. Notice it in the screenshot above.
- This standard email tells the task assignee some info about what they’re approving, with a link to the task and a link to the item needing approval. For a scenario where you want the approver to have all of the info they need, right in the email, it will help to insert some additional fields. You could insert every field from your travel request if you wanted to, but for demo purposes, I only inserted the start and end dates of the trip. This is also where we are going to insert links to let the approver click to do the lazy approval. Type the words Approve via email, and Reject via email. We will create the hyperlinks next, but here’s the general idea:
- We will put all of the info that we need into a mailto URL. Here’s the mailto Link Syntax guide that I found. Select the word Approve, and click the hyperlink button (the little globe). Click the little ellipsis next to the Address box, to bring up the string builder. For now we’re going to keep this super simple, and only put the ID of the travel request in the email subject. We’ll get it running that way, and then we can get more advanced with various string actions. What email address did you create at step 1? We’ll use that here.
mailto:firstname.lastname@example.org?subject=[Current Item ID]&body=Approved
- Click Ok twice, and then select the Reject text, so that you can make this a hyperlink also. Repeat step 7, and the only difference is that instead of Approved, the mailto syntax will have &body=Rejected
Click Ok on all screens.
- This workflow is going to be pretty simplistic, and of course in the real world you will have other things going on in it. For example, I’m just going to log whether the travel was approved or not, but realistically you’d be using the Send an email action to notify people that something has been approved or not, etc. Add two more stages to the workflow, call them Approved and Rejected. Here’s the whole thing:
- Finish out the Create the Approve Travel workflow as above, and publish it. Make sure it’s set to run when a new item is created.
- Create a new SharePoint 2013 Site Workflow, and call it Wait for Email. The important thing to remember about this workflow is that it will be running and perpetually looping each time an email arrives in the Approval Email list (3), so each time you change it and publish a new version, you have to go terminate the currently running one, and start it all over again. This will mostly just happen during testing and the workflow creation process. Once it’s being used, it will just run and stay running.
- For the first action, add Wait for event in list item. If you are not using a SharePoint 2013 workflow, you will not have this action available. No, I’m not sure how you’d do this in 2010. I named this first stage Waiting. Click the blue this item event.
- Choose Event: When an item is added, and for the list choose Approval Email. Click OK. This means that when a new email arrives in the approval email list, this action will be triggered on the already running workflow, and will also give you this variable called related item, which is the GUID of the item that was just created. (note that GUIDs are new to 2013 workflows and are not the same as the ID of the item)
- For the next action, choose Log to History list. This step is not required for this workflow to function, but gives you some reference info when troubleshooting. Just log that the email arrived, and what the GUID is. On the string builder, click OK.
- The only data that we have to go by in this arriving email is the info in the subject and body. To start off, we need to be able to match the arriving email with which task it needs to complete. In this simple example so far, we have created the task and the email to both equal the ID of the travel item being approved. After logging which item arrived, create another stage called Complete Task. The Waiting stage will just go straight to the Complete Task stage for now. Here’s the whole thing, and I’ll show you what was done in each action. Note that the “contains” that I used is case sensitive.
- Here’s the Set Workflow Variable action (the 3rd one). Set an integer variable called TaskID to this, which is the ID of the task WHERE the title of the task is equal to the email subject of the email that just arrived. This TaskID can now be used in several other places in the workflow, to reference the task.
- Here’s the Approval Email: Body (the IF statements). Basically, get the Body of the email WHERE the GUID of the item in the approval email list matches the related item variable.
- The Update item in Workflow Tasks is the Update item action. Basically, set the status to completed and outcome to Approved for the task WHERE the ID of the task equals the TaskID workflow variable. Whew!
- For the Else if part of the workflow where the rejection is, you can just use copy and paste in your workflow to copy the IF statement and also the update list item action. Then, all you need to change is the word approved to the word Rejected.
- Notice that the last Transition to Stage is to go back to the beginning, to the Waiting stage. This way, the workflow will be waiting again for the next email to arrive. Once your whole workflow looks like step 15, Publish it. Go to your SharePoint site, and go to Site Contents. Click Site Workflows.
- Click the name of your Wait for email workflow, to kick it off. Then you will see it listed under My Running Workflows, in the Waiting status (because that’s what we called the first stage).
- Okay, time to try it out and see what it can do so far, BEFORE making it more complicated. Go to your travel request list and create a new request. I think I’ll go to Hawaii.
- Wait for the task assignment email to arrive. I simply assigned mine to myself for now. This could take 5 minutes or so, because these run based on a timer job on the server. Here’s the email
- Try the Approve hyperlink. See that it opens up a new email. Click Send, without changing anything. (This can also be verbiage that we can add to the task and the email, telling users not to change it just click Send.)
- Keep an eye on the Approval Email list on your site. The email will arrive here, which will trigger the workflow to complete the associated task (in Workflow Tasks), which will then display the word Approved next to my travel request for my trip to Hawaii (Travel Request list). You can change your view in the Approval Email list, to include extra columns, such as Body and E-mail Sender. The Title and Email Subject will have the same value.
You may want to try doing a couple of these. Also, take a look at the still running site workflow from step 20. Click on the Waiting status, to see the log of what’s happened so far. If your workflow says “Suspended”, that means that there’s a problem, so click End Workflow. Then once you fix/tweak and re-publish (like I have done many, many times in figuring this out), you just have to remember to do step 20 again (start it again).
- Okay, so now that you see that it works, you will probably want to make some tweaks, such as to have a better email subject, or to even make sure that the person sending the approval email is actually the same person that the task is assigned to. This is where it can get really tricky. In SharePoint Designer, open your Approve Travel workflow to edit it. Open your Assign a task action, so that you see the screenshot in step 4. Click the ellipsis next to the task title. I’m calling mine Travel Req: # Approval. Click OK. (I’m using the term “approval” as a generic term referring to the approval process. The actual outcome is approved or rejected, and it will be in the body.)
- Now the task will look nicer, but now we need to make the email subject still match the task name so that step 17 will work correctly. I also use the URLEncode URLDecode website to help me with my syntax. I’m also throwing in some info about who is going and where they are going.
With the above syntax, when the approver clicks the Approve hyperlink in the email, it will create this email, and they just need to click Send.
- If you want to check the name of the email responder to make sure it’s the same as the person who the task is assigned to, this adds more complexity, but can be done. Here’s the new, more complex workflow, with logging added as well:
- Here’s how to do the comparison between the person sending the lazy approval email and the person the task is assigned to. This is in the IF statement inside that first stage transition.
That’s it! There are many different ways you could slice this, but I tried to break it down to the simplest way. If you need to extract specific info from within the body or subject after the email arrives, there are several utility actions that can be used:
Also, there’s the possible complexity you may have when using the task process that involves more than one approver. All task names are the same for that one travel request when that happens. One thing you can possibly do, would be to run a workflow on the task list, so that when items are changed, and the status is equal to completed, it actually changes the task name. Another idea: When you send the lazy approval email, there is no task ID available to include in it, but there is a task URL, which will inherently contain the unique ID of the task. You could include that in the response email, and then use the utility actions to extract that ID, like extract substring from index of string. For example, my task url might be http://site.contoso.com/lists/tasks/dispform.aspx?ID=# so the index would be 54, which is where the ID is. As you can see, it could get much more complicated. For troubleshooting, don’t forget steps 21 and 25.
Again, here are the requirements to be able to do this:
- SharePoint 2013 on premises
- Incoming email is set up on the server
No, I don’t know how this could be done in Office 365, and yes, this type of solution is possible in SP 2010 I’ve heard, but there’s something you have to do on the server to make the arriving email actually trigger a workflow, since it won’t by default. I’ve never done it.