Use SharePoint Designer to Email Daily Task Reminders

Introduction

It never fails to happen.  Your company invests in SharePoint, takes time to define business processes and automate them using workflow (with a dash of InfoPath, perhaps), tests the solution to within an inch of its life and finally launches in production.  Two days later, it comes to a screeching halt because the user community isn’t completing system-assigned tasks.  Business processes don’t run to completion, KPIs are flashing amber and red.  Someone has just got around to blaming the problem on global warming …

Of course, failing to complete tasks won’t normally cause that much trouble.  It’s just plain inefficient, even in a simple scenario where a department manager manually creates tasks in a WSS task list.  The manager shouldn’t have to remember to look at an “incomplete tasks view” to find out which department members have overdue tasks.

Users always have plenty of excuses:

  • “I can’t find the task.”
  • “I didn’t know I was assigned a task.”
  • “The dog ate my task.”

This a common business problem and we can solve it.

Companies often turn to some kind of automated reminder system to prod End Users into marking their tasks complete, thereby allowing those beautifuly orchestrated business processes to proceed as designed.  This article describes how “Power” End Users and Developers alike can use SharePoint Designer to create an automated task reminder system based on SharePoint’s core workflow capability.  This solution applies equally well to Windows SharePoint Services 3.0 (WSS) and Microsoft Office SharePoint Server (MOSS).  The article starts off with a little theory and then moves into a painstakingly detailed and lovingly created walk-through describing exactly how to create this workflow solution.   After the walk-through, it describes some important limitations, some technical implications and finally, suggests some useful extensions.

First, the business requirement:

  • A task has been assigned to a user.
  • The system should send an email to the user every 24 hours until the user has completed the task.

It doesn’t get much more straight-forward than that.

We will use SharePoint Designer to create a workflow solution that meets that requirement.  The solution leverages several SharePoint features:

  • Windows Workflow Foundation.
  • SharePoint Designer (of course).
  • SharePoint workflow’s remorseless nature.

“Remorseless nature” means that a functioning SharePoint environment continues running a given workflow forever unless one of two things happens:

  1. The task is deleted.
  2. The workflow decides on its own to quit.

Before we fire up SharePoint Designer, we need to consider the workflow’s design:

This looping workflow has one choice to make among three options each time iterates:

  1. Is the task complete? If yes, quit. Yeah, we’re done!
  2. Is this the first time I’m sending a reminder? If yes, send a reminder and pause one day. Set a flag to indicate that the first reminder has been sent.
  3. Is the second or more time I’m sending a reminder? If yes, send it and pause one day. Increment a counter to indicate how many reminders have been sent.

(Developer readers here may be thinking to themselves that these seem a lot like states and/or state transitions.  You’d be correct to think that.)

Pre-Configuration

To support a design like this, we need to add two columns to our task:

  1. FirstEmailReminderSent
  2. EmailReminderCount

The workflow uses these fields to maintain some information about the task (e.g. was an email reminder sent) as well as to trigger the workflow to run again for subsequent reminders.

These two columns, added via the task list’s settings, look like this:

FirstEmailReminderSent

It’s important to set the default value of FirstEmailReminderSent to “No”.

EmailReminderCount task column.

EmailReminderCount is simply an number with default value of zero.

Walk-through

With this configuration work complete, let’s see all of this in action by creating a workflow.  Firing up SharePoint Designer, we create the workflow in the normal way (i.e. open up the site with the task list, create new SharePoint content, create a workflow).  It looks like this:

Creating a new workflow.  Make sure it\'s set to run on Create and Update.

The workflow has been named “Daily Reminder,” it’s associated with a list called “Tasks” (i.e. the task list) and here is the key: It’s set to run both when the task is created and when it’s changed.  The “whenever an item is changed” bit is very important, as we’ll see later.  This setting enable us to leverage SharePoint’s remorseless nature to our benefit.

The first step of the workflow is easy: Stop running if the task has been completed:

Stop processing if the task has been completed.

The second step is more interesting.  This step, labeled “Send Initial Email,” obviously sends the first email.  However, it also sets up the subsequent reminder.  Let’s see how that works:

Send the initial email.

Note that this task only runs if our task column, “FirstEmailReminderSent” is equal to No.  Since we were careful to specify “no” as this column’s default value, we know this step will run (provided that we got past the first step above).

First, we send the reminder email.

Then, we set FirstEmailReminderSent to Yes.  This ensures that this particular step never runs again.

Next, we pause for one day.

Once our pause completes, we want to start looping.  We do this by “poking” the task by changing any field of the current item.  When we do this, from SharePoint workflow’s  perspective, the item has been changed.  Since we checked “Automatically start this workflow when an item is changed,” it starts the workflow all over again.   We could pick any field but since we need to “poke” the current item, we may as well derive some business value at the same time.  We’ll use the EmailReminderCount field.  This way, we can poke it and know how many times the reminder has been sent, killing two birds with one stone.  The next series of screen shots show how to increment that counter.

First, we create a workflow variable as shown:

Insert the TemporaryCounter variable.

Copy the current value of EmailReminderCount to our TemporaryCounter variable using the “Set Workflow Variable” action:

Set the TemporaryCounter variable so that we can increment it later.

Use the “Do Calculation” action to increment this by one.

Use the \

Finally, update the Task’s EmailReminderCount using the “Update Field in Current Item” action.

The third and final step looks very similar to the previous:

Send subsequent emails (any email after the initial email).

This step only runs if the task was not marked as completed and if the first email reminder has already been sent.

Workflow pauses for a day and then increments the EmailReminderCount by one.  Performing this update causes the workflow to start over again.  Assuming the user never marked the task as complete, SharePoint workflow skips the first steps (since task is not completed) and the second step (since FirstEmailReminderSent is still Yes), landing back here on the third step.  It sends the email and pauses 24 hours, pokes itself and keeps looping like this, forever, until the task is completed or it’s deleted.

The following series of screenshots capture a test environment where the pause has been set to a short time interval:

At runtime, we see that the email\'s sent counter is incrementing over time.  This could feed a KPI for better visibility.

In the above screen shot, the system has sent three reminders and is still waiting for the workflow to be completed.

Here is the initial workflow history:

Workflow history.  The email reminder loop is still running at this time.

Here is how the task is marked complete:

Complete the task to stop the worfklow from looping any more.

Here is the final workflow history:

Final workflow history after the task has been completed.

Limitations

SharePoint Designer workflow is … limited.  There are several important limitations, but one of the most important for most users to understand is that these workflow solutions cannot be easily ported from one environment to another.  In fact, they cannot be easily ported anywhere, period.  There are clever workarounds to this problem, but that’s for a future article. (Hint -edit the XOML file directly, replacing task, list and other GUIDs manually).

Second, the workflow history is a bit garbled.  Conceptually, this is just one happy workflow.  However, at a machine/SharePoint level, we really have multiple instances of the same workflow.  This isn’t a problem for SharePoint, but it does sew confusion in a reporting sense.  As the final workflow history screen shows, even though we humans think just one workflow actually ran for this task (the Daily Reminder workflow), SharePoint shows five separate histories.  In our reminder scenario, this really isn’t a problem.  Each workflow history represents one email reminder.  However, if we had extensive logging and other complicated activities taking place, it would be hard to decipher the history and required a lot of clicking.  There is a clever solution to this problem as well, again for a future article.  (Hint – create entries in a custom list using a common key field to group them together).

Finally, it is important to realize that WSS and MOSS service pack 1 introduced a security feature that prevents a system administration account from starting any workflow automatically (though this was recently amended with the 07/15/08 infrastructure update).  If you’re testing this out in your environment and nothing seems to be happening, log in to the system as a non-admin account:

Signing in as a different user.  Do this to avoid testing as a system administrator.  That way lies madness.

State Machines in SharePoint Designer?  Looping?  Preposterous!

As hinted at early on, this solution actually defines a state machine.  It uses the task itself as a persistent store for state data.  This workflow defines the following states:

  • Starting state: Sending a first reminder.
  • Reminder state: Sending a subsequent reminder.
  • End state: Marking the task as complete.

It’s not hard to imagine creating other kinds of state machines using this approach.

There is a real risk of pushing beyond reasonable business scenarios for which SharePoint Designer was designed (and some might argue that we already have).  Keep that in mind.  A complicated state machine workflow should be developed using visual studio with its close-to-the-metal workflow building tool set.

Extending the Solution

Several common sense extensions come to mind:

  • Weekends: Incorporate some logic to determine whether the current date is a non-business day. If it is, simply pause for 24 hours before running again.
  • KPIs: Integrate this solution with a KPI. If the user requires many reminders, turn amber and eventually red to indicate a seriously overdue task.
  • Escalation: if a given task requires too many reminders, fire off an email to a manager.
  • Due Date Aware: Don’t send an email reminder for task unless it has passed its due date.

Conclusion

This article describes a fully functional email reminder system.  The solution leverages core WSS workflow technology and uses a relatively friendly tool, SharePoint Designer, to do it.  This means it does not require MOSS but works in MOSS (since MOSS extends WSS).

Although the business example focuses on tasks, it should be clear that the pattern described here can fit into many different business scenarios that require repetitive (looping) actions over a period of time.  Simply define how the loop should end, what it should do in the first iteration and what it should do for subsequent iterations.

Too often, we hear that SharePoint Designer workflow can’t loop, can’t create state machines, is terribly limited and crippled, etc.  With a little imagination, we can prove the critics wrong and build simple yet powerful workflow solutions using this tool.

Twitter Digg Delicious Stumbleupon Technorati Facebook Email
  • Great article Paul. clean, consice, and enjoy your use of screenshots. well done.
  • Hello,

    While it is fully possible to use SPD for this purpose I hesitate to do so. Not just because I am a developer, but because I prefer the right tool for the right job. I don't use a hammer to get a wingnut in place, even if it would be possible.

    However, I really love your way of inspiring creativity. People seriously underestimate what is possible with SPD. I've previously used SPD to mimic a ticket handler functionality using simple intelligence to determine if an incoming email to support@example.com should be routed to helpdesk, how important it is, and to handle automatic escalation. I wouldn't put it into production, it was used primarily to demonstrate what you are doing here, that SPD can be very flexible if you need it to be.

    What I really miss is more focus on combining 'regular' development with SPD, specifically creating custom activities. Quite often semi-power users need to do more advanced tasks or end up creating the same, repeating set of tasks multiple times. Being creative may solve the problem of creating advanced tasks, but if ten people want to accomplish more or less they same they tend to end up creating ten different solutions, taking ten times as long and frustrating IT ten times as much. These power users should learn when it is not efficient to create new solutions and either create or have someone create a more versatile custom activity.

    Again, SPD out-of-the-box is not always the best or even a good solution, but combine it with some custom development and it can become truly amazing in a lot more cases.

    .b
  • I see an article in that comment :P

    Paul?
  • slashd
    'I'm curious, would Nintex Workflow be able to do this workflow? As far as I know Nintex is easier and more powerful than Sharepoint Designer in workflows (but less than Visual Studio off course).
  • pagalvin
    (Very late response :)

    I think that K2, Nintext and maybe some other 3rd party tools would be more than adequate to do this. However, many people are not going to get access to a product like that and that's why I wrote about this subject.
  • Juampi
    Excelent workaround. Thanks!
    But I have a problem, my list has several content types. Is it possible tu attach this workflow to all content types with sharepoint designer??
  • pagalvin
    (Very late response, sorry!)

    You can't attach a sharepoint designer workflow to a content type, at least not in any normal sense of it. If it's possible at all, it would require coding.
  • tatchison
    Can't you just check the content type field of the item to determine what the content type is, and then either process or not?
  • This is a great way to show the capability of the SharePoint Designer platform. My concern is of a related note to another commenter. By creating a chain of several workflows which are executing, you will quickly choke the WorkflowTasks (not in this workflow, but perhaps in other scenarios inspired by this) and WorkflowHistory lists and will cause them to hit the 2000 item limit sooner than with a VS.NET workflow. I hesitate to spam these lists whenever possible, as it may make auditing of naughty actions much harder to find in the haystack.
  • Anff
    Whats the 2000 item limit., I know of suggested "limits" related to performance and list sizes but is there anything that won't function after item 2000? (Such as history entries?)

    Thanks
  • pagalvin
    It won't outright stop, but 2000 items is a strong recommendation in terms of max items in a list.

    Some people say the practicle limit is even smaller.
  • John
    good post!
  • bennie
    Maybe I didn't get the whole idea, I am still learning sharepoint. But it seems to me the "ReminderEmailSent" field is not necessary?
    If the "ReminderEmailCounter" equal 0, that means no email has been sent. There is no need another field to flag this.
    Also, what is the purpose of knowing whether email has been sent or not? Can we pause 24 hours when the workflow start and then check that task status,if it is not "complete", just send out the emails and set the counter.

    Will it work?

    Thanks.
  • pagalvin
    You're right, I think. I added that mainly as a colum of info to show. I like my systems to actively tell me stuff rather than try and infer it indirectly.
  • test
    can't post comments?
  • Nicely laid out article - Yes you can do this but its a lot of work and has some problems that other posters have commented on.

    There are some 3rd party tools that do this a little easier (shameless plug, first one is my own!)

    http://www.pentalogic.net/sharepoint-reminder.aspx
    http://www.bamboosolutions.com/
    http://www.sharepointboost.com/alertreminderboo...
  • daanvloedgraven
    Is it not dangerous to use a column for the 'email reminder sent'? The user who has to complete the task can edit this field (and influence the workflow)?! Or am I missing something?
  • pagalvin
    I think you're right, it is dangerous. One way to solve that is to "hide" the field in the content type that gets generated by SPD. Once it's hidden, it can't be edited but it can still shown in a list view.
  • gly
    This is not a good technique because workflow recursion is actually a well-known bug in SPD. So this article leverages a bug, not a feature.

    This means that when MSFT releases a fix for this bug and you install it, this workflow will no longer work.
  • pagalvin
    Where is it documented that it's a bug?

    MSFT already released many months of patches, SP1 and the infrastructure update so it seems like it's very low priority, if it is actually a bug they plan to fix.
  • Eric
    Sorry Gly, but there's a difference between recursion and intentional repetition. There are conditions specified for each iteration of the loop in Paul's solution, therefore the behavior described is not recursive.
  • Alan
    I used your example and it works great. One problem though, an Item has been changed email gets sent out after the counter gets updated. Is there anyway to get SP to not send the item has been changed email for the counter column.
  • john
    Thanks much pagalvin, very instructive! Now I don't want to go diverging off the topic of your post, but could this be adapted for use on a issues list, where an email is sent periodically when it's status isn't completed? The rub I see in adapting this is that you have to check the "Automatically start this workflow whenever this item is changed", and hence any dicsussion on an issue starts the workflow email again. But for Tasks, it was very helpful, you taught me a lot!!
  • Paddy
    Great Article Paul. I want to send an email alert every monday. How can i do that. Which step in the workflow tells it that the email alert has to be sent after every 24 hours. Am i missing something
  • bob
    Nice work pagalvin...
  • Jesse
    This is a great article.

    However, I was just doing some developing and I was testing a workflow and did not want to wait 24 hours so I set it to 5 minutes. It never sent me the email and it only looped 4 or 5 times before finally deciding to be Complete instead of In Progress. The workflow should remain In Progress right? I didn't know if this was a glich or something. Maybe not enough time has been given for the service to run correctly.
  • jae
    I'm getting the same behavior. First test looped 4 times, second test 2 times, third test only interated once. No error message. Every stepped is logged properly. It seems to stop for no reason.
  • PatLV23
    Same here. I've tried 5 minute to 4 hour intervals. I've even tried using "pause until date" instead of "pause for duration". I would get between 1 and 8 reminders before it stopped and marked the workflow as completed.
  • howeg73
    Has anyone found a solution to the variability in the iteration? I am also finding that my workflow is actually updating a value in the Current Item, but it never restarts. As a result, I may get 1 iteration in my test or 10. There doesn't seem to be any consistency.
  • Netta
    having the same problem. it doenst metter if it's 24 hours or one. it works once/twice then i get "completed" and it doenst work anymore....
  • Wim
    having the exact same problem. I have updates WSS to sp1, and the .net to the latest service pack as well, and nothing seems to solve it. It appears that after a reboot of the actual server, things seem to work for a little longer, but then - after a random number of iterations - the flowchart gets marked completed. There has to be a reason for this. Can anybody help?
  • jeiku
    hi paul,
    i tried adding Log message to workflow history list option but whenever I am viewing the workflow history of a specific record, the old message is still the one displayed.
    any thougths on this?

    thanks!
  • jeiku
    hi paul,
    i tried using the Log message to workflow history but whenever I am vieewing it, the old message still appears..

    any thoughts on how to fix this?

    thanks!
  • Sphix75
    Great example, I have followed this example step by step, but for some reason in the "send initial email" step, nothing after the Pausing statement gets processed, I get the email, and the "FirstEmailReminderSent" is set to YES, in the description the pausing is set to the right time, but the EmailReminderCount is still set to 0. I tried a different workflow example and i have the same problem nothing gets processed after the pausing statement. ANY help would be much appreciated. Thanks
  • scott
    I really hope this capability is built into the next version of sharepoint this request happens all the time. I have written console apps and ran them as scheduled tasks to perform operations that you think would just be built in.

    I have tried various techniques like this including using one list to loop through another, but they seem problematic. I’m glad that some people were successful following your well detailed instructions. But I was not one of them. I only get one instance of the workflow to run. i.e. changing the emailremindercount does not fire off a new instance of the workflow.
  • Chris
    Is there anyway to work around timezone issues.

    For example I have users in Hong Kong, London and New York.

    If I create a task so that it has a due date of 25th December in Hong Kong when users open it in London or New York the due date appears as the 24th not the 25th.

    Any help would be greatly appreciated. Is there anyway of assigning an all day flag to a task due date in the same way as the calendar does for example.
  • Bernardo
    Sorry by my poor english

    Great article, we have a problem with alerts and this article is a solution, and have a question.
    One question : is posible to use a group of sharepoint or shareponit's group for to be a destinatary of mail?

    One question : it is possible that I can use your articles translated into Spanish in a site sharepoint?

    Thanks Pagalvin for your article
  • Netta
    i just can't get it to work.
    everything works fine. the "poked" filed updates itself but the update doesnt trigger the workflow to start again.
    I set it to everytime an item changes, menual change triggers it but not the "scripted one" from the workflow.
    I'm clueless....
  • Dan S
    Actually, I accomplished this slightly differently and without looping or creating placeholder columns. I used your article as a good conceptual guide. Hope this helps.. It is working well for me. My actual workflow is more detailed and tailored to my environment, but here is the gist..

    All done in Sharepoint Designer. You should consider adding Log messages to the instructions below. By the way, when testing, dont set the counter to 5 minutes.. it wont always work. Plan the testing over a few days.. make it realistic and be patient! I read there are some bugs when setting the time triggers too low..

    Create some Workflow steps. Each step is separated with commented ### marks:

    Make certain the workflow starts when a new item is created or modified.

    ### Check if task is set to Completed when created/updated ####

    If Status equals Completed
    Stop Workflow

    ### Create a "date" variable named strReminderDate for a 2 day warning that task will be due ####

    If Status does not equal completed
    Add -2 days to Due Date and output to strReminderDate
    Then pause until strReminderDate

    Else If Status equals Completed
    Stop Workflow

    ### Email 2 Day Warning to Assignee unless uncompleted task was created within 2 days of Today and Pause until Due Date ###

    If Status does not equal Completed and Due Date is greater than Today
    Email Assigned To:
    Pause until Due Date

    Else If Status equals Completed
    Stop Workflow

    ### Email Assignee and pause for 3 days to be escalated if task not complete ###

    If Status does not equal Complete
    Email Assigned To:
    Pause for 3 days

    Else If Status equals Completed
    Stop Workflow

    ### Escalate uncompleted task to Manager ###

    If Status does not equal Completed
    Email Manager
    Stop Workflow

    Else If Status equals Completed
    Stop Workflow

    ##############
  • Eric
    Dan;

    The problem with your method (and the reason that Paul's requires a "poke" column) is the Pause until strReminderDate or Due Date action. This pauses the workflow and causes it to stop "listening" to list updates so that if the due date is changed the workflow will not detect the change and update.

    If you're going to use an SPD workflow for this application then you need to use a method like Paul's to loop the workflow with a frequency (daily, weekly, whatever) that is acceptable to your end user.
  • Andy
    Is there a way to trigger a workflow based on a field(date)?
    List has two columns: Due Date (manually entered by user) and "One week Reminder" (calculated date based on "Due Date")

    i.e User create the doc Today(2-6-2009) and enter "Bill Due Date"=3-8-2009 so "One Week Reminder" will be 3-1-2009

    How can workflow send out email on 3-1-2009?

    Once the user gets the email, he/she will update the "Bill Due Date" to some future date and again one week before that date, workflow should sent out remonder.

    Thanks
  • crazy man
    Good article,great thought. No matter how many limitations is has, I wold say it solved put Sharepoint Reminder in new high.
    Right new I am using Sharepoint Alert Reminder Boost (http://www.sharepointboost.com/alertreminderboo...) which serves me well. I think the difference between your solution and the third party tools is that for some tech savvy your solution is great, brings some sort of accomplishment while third party tool is more reliable and easy to use.

    Nevertheless, your blog gives me fresh knowledge. Thanks!
  • Rohit
    Hi

    Does anyone know if there is a way of scheduling tasks in a Sharepoint list automatically?
  • Michael
    For the e-mail to field I put in "Task: Assigned To" and it works just fine. This is very helpful if you are making your own ticketing/tracking system which I'm currently working on for the company I'm with.
  • dfwilcox
    What a well-though-out article, Paul! Thank you for taking the time to post your excellent instructions and helpful screen shots!
  • Rodrigo
    Hi Pagalvin

    Very useful your post...I was just looking for the way to do that.
    Regarding hide fields used as counters and flags, it is a very good link of a tool that you just have to run in your server:

    http://spstipsutilitypack.codeplex.com/Release/...
  • he_pennypacker
    I was tearing my hair out wondering why my workflow only ran through once, until I found this page;

    http://blogs.msdn.com/sharepointdesigner/archiv...

    Apparently, these instructions won't work post-SP2. Hope this helps someone else as it was driving me crazy.

    Of course, the SP2 "fix" is not documented anywhere on the official list of SP2 changes.
  • rbarath23
    I just found a way to get around this.

    The problem occurs to all who has made DECEMBER CUM UPDATES and then SP2 etc..
    The easiest way to get around this is create an event receiver for the list which cancels Workflow associations everytime the item is changed. And then create the workflow with changed and new item creation.

    Have it in 2 steps. But the problem is History Cannot be logged but who cares because my Users have no persmission to see all those.

    Hope this technique helps
  • rbarath23
    And also i had the same problem that my work flow works for only 2 mails and then when i change the status to completed my workflow didnt respond to the changes.

    The changes work only when the pausing completes and it doesnt respond whatsoever for any change in any field unless i manually terminate the workflow.

    This method worked fine before December and its not working with anybody after that..

    Just let me know if am right or wrong.
  • Bhadram
    Hey there's a problem at stet 3. Its should be If FirstEmailReminderSent equals Yes (and) Status not equals Completed should be used as condition. If this is not used even though the task has been completed we get email after that. So i think u should update that.For rest its the best i have seen ever.

    Thanks.
  • JohnXO
    I would like to make a slight correction.
    On the workflow step "Send Initial Email", you stated that you 1) send the reminder email, then 2) set FirstEmailReminderSent to Yes. Next, 3) you pause for one day, and then prepare to loop by 4) “poking” the task by changing any field.
    Well I think you already made your "poking" in step 2 by setting FirstEmailReminderSent to Yes. I'm not sure what the impact on the workflow logic is, but I thought I'd let you know for accuracy.

    JohnXO
  • Debra Talley
    Paul, I'm a newby and I'm attempting to create an auto-increment workflow to a custom list that contains unique log numbers. I found a site from some time ago that maps out the steps but I know I'm missing something. When I test the workflow, the list says that there is an error in the workflow. Can you give me more information. Here is the url to the item I am attempting to use. http://splittingshares.wordpress.com/2008/04/11...
blog comments powered by Disqus