Tag : not started

Workflow – Useful REST calls – Start a workflow

In SharePoint 2013 Microsoft modified the triggers on list items so that inserts or modifications to list items do not trigger the Workflows that are set to start based on those conditions. This was done in an effort to prevent recursive calls to the workflow initiation.

In summary then, even if you have set the workflow start options to ‘Start workflow automatically when an item is created’ or ‘Start workflow automatically when an item is changed’, this will not happen if an item is added or changed from WITHIN a workflow

206-1

However, even though it takes quite a few workflow statements, it is still possible to start the workflow manually from within the calling workflow. Most of the next steps that are performed in Workflow Designer are well documented in other online articles

Define the list and item that you want to start the workflow on

The first step is to specify the list and ID within that list that you want the workflow to run on

206-2

In this example, I set ‘String01’ to the name of the list that I wish to run the workflow on (‘Item List’) and ‘ID’ to the ID of the item within this list. In this particular case, I want to run another workflow on my current item, but in most cases you would use the ID from another list

Prepare the dictionary for the call

Insert a ‘Build Dictionary’ action and add the names ‘Accept’ and ‘Content-Type’, both with the value ‘application/json;odata=verbose

202-2

202-3

Instead of using the defaulted name of ‘dictionary’ in the ‘Output to’ command, I use my own name of ‘Header’. This change of name is optional. At any rate, after the dictionary changes have been made, the command looks similar to the following:

206-3

Make the HTTP Web Service call

In the next line, insert a ‘Call HTTP Web Service’ action. This action is part of the process to get the GUID of the list on which the workflow will run. This will place something similar to the following in your workflow:

206-4

Click on ‘this’ and set the ‘HTTP web service URL’ to the following

206-5
[%Workflow Context:Current Site URL%]/_api/web/lists/GetByTitle(‘[%Variable: String01%]’)

Note that ‘[%Workflow Context:Current Site URL%]’ and ‘[%Variable: String01%]’ are inserted through the ‘Add or Change Lookup’ button. Also note that single quotation marks are required in the ‘GetByTitle’ value (Check that the single quotation marks are correct as these can sometimes be transformed in the cut-and-paste). The ‘HTTP method’ should be set to ‘HTTP GET’

Set the HTTP Call to use the Header dictionary that you defined earlier (the one with the ‘Accept’ and ‘Content‑Type’ values). Right mouse click on the call, and select the ‘Properties …’ option as shown below. Set the ‘RequestHeaders’ to the Workflow variable ‘Header’

204-1

Note: This ‘Header’ definition should be on every HTTP Call statement (even though I may not mention it again). Failing to have this value will result in 0 records being returned by the call

Change the Call’s defaulted names of ‘request’ to ‘Request’, ‘response’ to ‘Response9’, ‘responseHeaders’ to ‘ResponseHeaders’ and ‘responseCode1’ to ‘ResponseCode’. This is probably not necessary in your situation, provided you make the necessary substitutions when examining the code in this document. Once everything is complete, I have a statement that looks as follows:

206-6

This statement should execute without error, but if you have a problem, you can use a ‘Log’ action to display the value of ‘ResponseCode’ which should always be ‘OK’. Any other value denotes an issue (See my workflow posts about troubleshooting REST errors)

Get the GUID of the list

The previous statement makes a call to the SharePoint site and returns information into the dictionary we defined. We now need to interrogate the dictionary to get the GUID of the list. This is done with a ‘Get an item from a dictionary’ action

206-7

Click on the ‘item by name or path’ and type ‘d/Id’ in the fill-in. Then click on ‘dictionary’ and select the ‘ResponseContent to’ variable – in my case this is Response9. At the end of these two changes, your statement should look as follows:

206-8

This statement gets the GUID of the list (in my case the Current Item) and places it in the Workflow GUID variable ‘create’

Get the workflows for the list

Now we need to get a listing of all the workflows related to this list item. To do this, insert another ‘Call HTTP Web Service’ action and set the HTTP web service URL to the following206-9

[%Workflow Context:Current Site URL%]/_api/SP.WorkflowServices.WorkflowSubscriptionService.Current/EnumerateSubscriptionsByList(guid’[%Variable: create%]‘)?select=Id,Name

This call will return a listing of all workflows related to the list (the GUID and Name are returned). Set the HTTP method to ‘HTTP POST’. I then reuse some of the variables that I defined before so that the final statement looks as follows (Remember to use the properties to set the HTTP Call to use the Header dictionary)206-10

Prepare to loop thorough the Workflows

In some situations, as is the case with mine, there will be more than one workflow associated with a list item, so I need to loop through all of them to get the one I want. To perform this looping I use two variables ‘ContinueLoop’ (Boolean) and ‘calc’ (Number)

206-11

Use the Loop function from SharePoint designer to design a loop that continues until the returned workflow returns the name of the workflow I want. This assumes that the name I use for the Workflow (ItemWF02) actually exists otherwise your workflow will suspend itself

206-12

Read the data in the loop

The first statement within the body of the loop is a ‘Get an item from a dictionary’ action. Set the ‘item by name or path’ to type ‘d/results([%Variable: calc%])’ in the fill-in. Then click on ‘dictionary’ and select the ‘ResponseContent to’ a workflow variable ‘Response9’. At the end of these two changes, your statement should look as follows

206-13
This will return the details of the current entry (initially it will be the first entry as calc=0)

Using two more ‘Get an item from a dictionary’ actions, get the GUID and name of the Workflow as follows:

206-14

Now we have the name of the workflow. Is it the one we need? If so, set the value ‘ContinueLoop’ to ‘No’ so that we do not read any more values. If this is not the value we need, increment the counter (calc) by one so that the system will read the next workflow for the list, as shown below

206-15

Start the workflow

In the documentation I read online, the next statement that executes in the workflow will start the workflow on the list item. My experience is that on occasion, the system will NOT start the workflow on the first attempt, returning an error in the ResponseCode instead. The error appears to be random and may be due to demand on the servers processing the request. No matter, I cannot let this happen, so I create a loop to execute the workflow, pausing for a number of minutes between attempts. This has always worked for me, but you may see some of this code as unnecessary. I show the section of code in its entirety below, followed by a more detailed explanation of the key steps

206-16

Initialize the Workflow variables for the loop. Here we use the Counter ‘Count2’ (Number) and the Boolean ‘ContinueLoop’ defining them as follows:

206-17

Actual Workflow Start syntax

In the first part of the loop we increment the counter so that we are aware of which iteration we are within the loop, but the key statement is the second one. Here we add another ‘Call HTTP Web Service’ action and set the HTTP web service URL to the following

206-17

[%Workflow Context:Current Site URL%]_api/SP.WorkflowServices.WorkflowInstanceService.Current/StartWorkflowOnListItemBySubscriptionId(subscriptionId=’[%Variable: create%]’),itemId=’[%Variable: ID%]’

This is telling SharePoint that the system must start the workflow with the GUID = Variable:create on the item with ID = Variable:ID. Set the HTTP method to ‘HTTP POST’. I once again change the dictionary variables I use with this statement, but the final one looks like the following (Remember to use the properties to set the HTTP Call to use the Header dictionary)

206-18

If you do not believe me that the workflows do not always start, then ignore the entire loop and execute the statement above after you have the Workflow GUID

The code that follows this statement contain no magic and simply checks the ‘ResponseCode’ returned by the HTTP Call. Since I assume that the reason why the workflows do not execute is due to server load, I pause for a number of minutes before attempting the call again. If after 3 attempts the workflow has not started, I email the administrator that there is a problem

206-19

That is how to initiate a workflow from within another workflow