Crossing the river with Nintex Workflow Cloud

Here is a question for you: “How complex a business process can be solved by Nintex Workflow Cloud?“, well I think I do have an interesting answer for that, it solves business processes that is as complicated as the famous Farmer-Wolf-Goat-Cabbage cross a river puzzle. 

There are many programming languages out there, everyone will have its own strengths and focuses. You might find it easy to solve the old classic puzzle such as the “Farmer-Wolf-Goat-Cabbage cross a river” with much lesser code in Prolog or Lisp that is associated with Artificial Intelligence than a Java program. It will be interesting to find out solving the same puzzle without even writing a piece of code with Nintex Workflow Cloud.

For those who have not came across the “Farmer-Wolf-Goat-Cabbage cross a river” puzzle, you could simply do a search on the web to find enough article and solution for it. This is just a perfect puzzle trying to understand a real world business process is, it has: 

Objective:

  • To move all the objects (Wolf, Goat, and Cabbage) across a river

Rules: 

  • Wolf and Goat are not to be left alone
  • Goat and Cabbage are not to be left alone
  • Only farmer roars the boat
  • Farmer can only bring one object at a time

Let us define the required terminology or object(s) we can apply to our workflow design,

TerminologyDescription
fromBankThe river bank where all the objects of Farmer, Wolf, Goat, and Cabbage are
toBankThe destination river bank where all the objects to be moved to
F, W, G, CThe acronyms representing Farmer, Wolf, Goat, and Cabbage
fromBank=[“F”,”W”,”G”,”C”]The initial state represents all the objects are at the fromBank river bank
riskState=[“WGC”,”GC”,”CG”,”WG”,”GW”]Sets of states both fromBank and toBank is at risk
toBank=[]The initial state represents none of the objects are on the toBank river bank
Embarkation, Disembarkation, ReturnTripRepresent three movement stages of forward movement from fromBank to toBank, disembarking of object to the toBank, and return trip with object to be brought back to the fromBank.

Algorithm:

  1. Initialize objects for:
    • fromBank=[F,W,G,C],
    • toBank=[],
    • embark farmer to boat (i.e. fromBank=[W,G,C]),
    • riskState,
    • etc.
  2. Start a loop until toBank=[F,W,G,C], 
    1. Embarkation Branch (i.e. always assuming to start with embarking an object to the boat)
      1. Check if we suppose to embark an object or return an object, if return object, change to ReturnTrip Branch. else continue
      2. try to embark the first Item from fromBank collection
      3. Verify if fromBank is “at risk” state by checking against the riskState collection
      4. If “at Risk” is true, revert the embarked item back to the fromBank collection’s back of the queue, exit branch
      5. if “at Risk” is false, remove the Item from the fromBank, switch to Disembarkation branch
    2. Disembarkation Branch (i.e. this stage is always followed from Embarkation branch)
      1. Try to disembark the object to toBank
      2. If toBank items count is equal to the total object, the goal has achieved
      3. if toBank items count is less than 2, toBank is at Safe state, farmer go back alone to Embarkation stage (i.e. set variable returnTrip=false)
      4. if toBank is “at Risk” state, farmer need to go back bringing one item to avoid “at Risk” state of toBank (i.e. set variable returnTrip=True)
    3. ReturnTrip Branch
      1. Disembarkation was always done at the Disembarkation Branch by disembarking item to the back of the toBank collection queue
      2. We will try to return the first item from the toBank, and verify if the remaining left alone safe?
      3. Loop through to get an item to be returned avoiding the conflicts at toBank
  3. Exit of loop (i.e. mission completed), sending the log of the movement result.

You may see the demo by submitting the Public Form at the following URL FWGC Cross the river puzzle form , which you will need to supply an email to receive the result, and the object sequence in the format of e.g. “F,W,G,C”, “W,F,C,G”, etc. to get different movement results. Here is the example of the form:

Note: Nintex Workflow Cloud do not currently support validation of the public form, you will need to fill in a valid email to receive the response, and right syntax for the FWGC Sequence field.

Here is a sample email content you will be getting from the submission of the above form:

Please find below the movement required to move all the objects from fromBank to toBank (i.e. each –> denotes the beginning of a line)—>Initialized: fromBank = [“F”, “W”, “G”, “C”], ristState = [“WGC”, “GC”, “WG”, “CG”, “GW”], toBank = [], initStateCount = 4, —>Embark W: fromBank = [“G”, “C”], toBank = [], atRisk = true, —>Revert W: fromBank= [“G”, “C”, “W”], toBank=[], —>Embark G: fromBank = [“C”, “W”], toBank = [], atRisk = false, —>Disembark G: fromBank = [“C”, “W”], toBank = [“G”], embark option in return trip= false, —>Embark C: fromBank = [“W”], toBank = [“G”], atRisk = false, —>Disembark C: fromBank = [“W”], toBank = [“G”, “C”], embark option in return trip= true, —>Return trip with G: fromBank = [“W”, “G”], toBank = [“C”], —>Embark W: fromBank = [“G”], toBank = [“C”], atRisk = false, —>Disembark W: fromBank = [“G”], toBank = [“C”, “W”], embark option in return trip= false, —>Embark G: fromBank = [], toBank = [“C”, “W”], atRisk = false, —>Disembark G: fromBank = [], toBank = [“C”, “W”, “G”], embark option in return trip= falseCompleted State:fromBank = []toBank = [“C”, “W”, “G”]

This exercise helps me with list of Asks on features and enhancements that I am looking forward to, I have most of them logged to the uservoice, here are some of them:

1. There is currently no way to construct a rich text variable with formatting I want, so I could compose the “Send email” action’s body by inserting a formatted string/rich text variable at the final stage. (i.e. the email content in the above example will be more readable if I could insert a formatted text of the below example:

—>Initialized:           fromBank = [“F”, “W”, “G”, “C”], ristState = [“WGC”, “GC”, “WG”, “CG”, “GW”], toBank = []

—>Embark W:        fromBank = [“G”, “C”], toBank = [], atRisk = true,

—>Revert W:          fromBank= [“G”, “C”, “W”], toBank=[],

—>Embark G:         fromBank = [“C”, “W”], toBank = [], atRisk = false,

—>Disembark G:    fromBank = [“C”, “W”], toBank = [“G”], embark option in return trip= false,

—>Embark C:         fromBank = [“W”], toBank = [“G”], atRisk = false,

—>Disembark C:    fromBank = [“W”], toBank = [“G”, “C”], embark option in return trip= true,

—>Return trip with G: fromBank = [“W”, “G”], toBank = [“C”],

—>Embark W:         fromBank = [“G”], toBank = [“C”], atRisk = false,

—>Disembark W:    fromBank = [“G”], toBank = [“C”, “W”], embark option in return trip= false,

—>Embark G:         fromBank = [], toBank = [“C”, “W”], atRisk = false,

—>Disembark G:    fromBank = [], toBank = [“C”, “W”, “G”], embark option in return trip= false

2. Import / Export of workflow design. I will be able to share my workflow design once the feature is available for me to export my workflow and attach it to this blog for sharing..

3. Print workflow design, and Save as.. to export workflow design as JPG, PNG, etc.

4. As I am using a lot of Collection operation for the exercise, there is a long list of collection operations I am looking for that is missing for the time being, the challenge results a workflow with additional actions to solve simple issue, here are some of the features that I think is missing:

  • Copy a collection from one to the other
  • Store Item for “Remove Item from Collection” action
  • Compare if two collections are equivalent
  • Dictionary variable
  • Concatenate collection items into string

5. Other features such as Log history action, Workflow constant, Go-to node action, sub workflow and/or grouping of actions.

Until my workflow could be exported for sharing, the best I could do for the time being is the captured design of the workflow solving the Farmer-Wolf-Goat-Cabbage puzzle.

Stronger Together – Nintex Workflow Cloud & Office 365

Stronger Together – Nintex Workflow Cloud and Nintex Workflow for Office 365. Many of us have been asking for feature such as scheduled workflow in Sharepoint for Office 365, that has not made available by Nintex Workflow for Office 365 today. Well, a scheduled workflow is pretty straight forward and easy to setup in Nintex Workflow Cloud, we can create a scheduled workflow in Nintex Workflow Cloud to trigger a workflow in Sharepoint for Office 365. That gives us the solution of scheduling a workflow in Sharepoint for Office 365.

To demonstrate how that works,

Nintex Workflow for Office 365 – Site Workflow

1. I have created a Site Workflow in Sharepoint for Office 365 environment. Here is how “MySiteWorkflow” looks like in Nintex workflow for Office 365 environment:

2. The “MySiteWorkflow” takes one Initiation Variable as defined below, when the workflow started manually, it will prompt users with the initiation form for users to provide input for the “listname” initiation variable. 

3. I have made the Site Workflow as simple as possible, with only only one “Log to History List” action. When triggered, it will simply write the provided “listname” variable value to the workflow history.

Nintex Workflow Cloud

While waiting for the Sharepoint Connectors to be released in Nintex Workflow Cloud, I have workaround with Azure AD App for Nintex Workflow Cloud to access the Sharepoint for Office 365 environment via the OAuth 2.0 authentication. For those who have not followed my blog on that, here is the link you could refer to on Add Azure AD App from Azure Portal section of the blog post. (Please take note that, instead of using https%3A%2F%2Fgraph.microsoft.com%2F as the value for the resource parameter, I have this time to use <site_host>@<site_reaml instead, as such my example i was using resource=https%3A%2F%2Fntxte07.sharepoint.com@<site_rearm> instead.)

1. Instead of creating a Scheduled Workflow, let us try to call the Sharepoint site workflow from Nintex Workflow Cloud using a Public Web Form start event to start the workflow in Nintex Workflow Cloud, the start event is configured as below to capture the input to be used as “listname”.

2. Before we proceed to define other actions, lets look at the list of workflow variable we will need to create for the workflow to work.

3.  Using “Set a variable value” action to assign the Access Token we obtained to the “accessToken” variable as shown below.

4. With the “accessToken” assigned, we going to add a “Branch by Stage” with two branches, one being the normal path to follow, the other to handle if the Access Token is expired, to renew the Access Token. I have named it as “Branch 1” and “Branch 2” as shown below

5. We set the branch to always start from “Branch 1” assuming the token is valid, by calling a “Call a web service” action to call Sharepoint online’s REST API. To start a workflow in Sharepoint online, we will need to, first, get the workflow’s subscription ID, followed by initiate the workflow to start. Define the “Call a web service” with the following values:

FieldValue
URLhttps://<YourTenantName>.sharepoint.com/_vti_bin/client.svc/ProcessQuery
Request TypeHTTP Post
Request HeadersAuthorization: Bearer accessTokenX-Requested-With: XMLHttpRequest
Request ContentRequest Content example:<Request xmlns=”http://schemas.microsoft.com/sharepoint/clientquery/2009” SchemaVersion=”15.0.0.0″ LibraryVersion=”16.0.0.0″ ApplicationName=”Javascript Library”><Actions><ObjectPath Id=”1″ ObjectPathId=”0″ />
<ObjectPath Id=”3″ ObjectPathId=”2″ />
<ObjectPath Id=”5″ ObjectPathId=”4″ />
<ObjectPath Id=”7″ ObjectPathId=”6″ />
<ObjectPath Id=”9″ ObjectPathId=”8″ />
<Query Id=”10″ ObjectPathId=”8″><Query SelectAllProperties=”false”><Properties><Property Name=”PropertyDefinitions” SelectAll=”true” /></Properties></Query></Query></Actions>
<ObjectPaths><StaticProperty Id=”0″ TypeId=”{3747adcd-a3c3-41b9-bfab-4a64dd2f1e0a}” Name=”Current” /><Property Id=”2″ ParentId=”0″ Name=”Web” />
<Constructor Id=”4″ TypeId=”{4ccc7f0e-bf7e-4477-999c-6458a73d0039}”><Parameters><Parameter ObjectPathId=”2″ /></Parameters></Constructor>
<Method Id=”6″ ParentId=”4″ Name=”GetWorkflowSubscriptionService” />
<Method Id=”8″ ParentId=”6″ Name=”GetSubscription”><Parameters><Parameter Type=”String”>[Workflow Template ID]</Parameter></Parameters></Method></ObjectPaths></Request>
Response ContentresContent
Response HeadersresHeader
Response Status CoderesCode
[Workflow Template ID] = e.g. {9CE443B7-3583-46C2-AA07-415F5E00C25B}, could be found from the site workflow start page’s workflow link as shown

6. Verify if the “Call a web service” is successful by using the “Branch by condition” to check the “resCode” equals to 401, if yes we will change the stage to “Branch 2” for getting new Access Token with the “Refresh Token” obtained during the steps setting up the “Azure AD App”. We will follow the “No” path if the resCode returns status code other than 401 (i.e. with the assumption the call to get the workflow subscription is successful).

7. The “Query JSON” followed by the “No” path is basically to get the returned the “_ObjectIdentity_” value with XPath search of “$.._ObjectIdentity_” from the resContent JSON object. The “_ObjectIdentity_” to be used in the following “Call a web service” action.

8. “Call a web service” with the following details to initiate the site workflow

FieldValue
URLhttps://ntxte07.sharepoint.com/_vti_bin/client.svc/ProcessQuery
Request typeHTTP Post
Request headersAuthorization: Bearer accessTokenX-Requested-With: XMLHttpRequest
Request contentMy “Request content” example: (I would advise to use fiddler to capture a manual trigger of your site workflow in Sharepoint online, and capture the two HTTP POST to https://<your site host>/_vti_bin/client.svc/ProcessQuery  for the XML request body to be used as your Request content here).<Request xmlns=”http://schemas.microsoft.com/sharepoint/clientquery/2009” SchemaVersion=”15.0.0.0″ LibraryVersion=”16.0.0.0″ ApplicationName=”Javascript Library”><Actions><Method Name=”GetExternalVariable” Id=”12″ ObjectPathId=”8″><Parameters><Parameter Type=”String”>listname</Parameter></Parameters></Method>
<ObjectPath Id=”14″ ObjectPathId=”13″ />
<Method Name=”StartWorkflow” Id=”15″ ObjectPathId=”13″><Parameters><Parameter ObjectPathId=”8″ />
<Parameter Type=”Dictionary”><Property Name=”listname” Type=”String”>List Name</Property>
<Property Name=”Microsoft.SharePoint.ExternalVariable.listname” Type=”String”>List Name</Property></Parameter></Parameters></Method></Actions>
<ObjectPaths><Identity Id=”8″ Name=”subscriptionID” />
<Method Id=”13″ ParentId=”4″ Name=”GetWorkflowInstanceService” />
<Constructor Id=”4″ TypeId=”{4ccc7f0e-bf7e-4477-999c-6458a73d0039}”><Parameters><Parameter ObjectPathId=”2″ /></Parameters></Constructor>
<Property Id=”2″ ParentId=”0″ Name=”Web” />
<StaticProperty Id=”0″ TypeId=”{3747adcd-a3c3-41b9-bfab-4a64dd2f1e0a}” Name=”Current” /></ObjectPaths></Request>
Response contentresContent
Response headersresHeader
Response status coderesCode

That shows the second web service call to trigger the site workflow to start.

9. Continued from step 4 above branching to “Branch 2” is the same steps in my blog post on the “Azure AD App” setup on how to refresh the access token by calling the REST end point at “https://login.microsoftonline.com/common/oauth2/token” as shown below.

10. The “Query JSON” is to use XPath to search to the access token from the resContent returned from the above action call, and assign the new access token to the accessToken workflow variable.

The above steps demonstrate both the site workflow in Sharepoint for office 365 and the Nintex Workflow Cloud to manually trigger the site workflow in Office 365 to run. With that testing successful, we know we could now schedule a site workflow in Sharepoint for Office 365. To do that, we just need to schedule the Nintex Workflow Cloud using the Nintex connector with start Event of “Scheduled Start” as shown in the screen captured below as an example.