Nintex Workflow - Lazy Checkin Everything Workflow

Doing quite a bit of client-side JavaScript (AngularJS in fact) and checking in and out lots of files that sit within Style Library.  At the end of the day, I just want something that will go through everything and check them all in for me.

Nintex Workflow time

  • Query List of items still checked out to me
  • Loop through list
  • Check-in
  • Bonus: Run-As-John

Query List

Create a Site Workflow, add a Query List action then set the filter.  Collect "URL Path" and "Checked Out To" fields to separate collection variables.

Important: Make sure you tick Recursive

Hit Run Now.
I want to change this part of the Query to Current User.

<Eq>
<FieldRef Name="CheckoutUser" />
<Value Type="Integer"><UserID Type="Integer" /></Value>
</Eq>

Hit the Execute button - looking good. 

Return to Configure Action.  Make the same change to the CAML query.

Loop and Check-In

Wrap up the rest of the Workflow.  After the Query List, set up a For Each action and loop through each URL in the URL Collection.

For each URL, run the Check in item Action.  Set it to check in by URL.

Insert Witty Comment.  Log an entry to History list for testing.

Laziness Complete

And done.  Workflow runs, John's files are checked in.

Bonus: Run-As-John

Sometimes, you might want to let a colleague check in your files on your behalf.  Nintex let you set up workflow within an Action Set to run as the Workflow Owner.

Summary

  • Now Everyone can check in all John's Mess!
  • Put this on a weekly schedule.

 

Azure Logic Apps: Build SharePoint Workflows by clicking buttons: a picture guide

 

TOC: Azure Logic Apps

  • Build SharePoint Workflows by clicking buttons [This article]
    • Introduction
    • SharePoint Online
    • Office 365
    • Connect them all
  • Hybrid Workflows - SharePoint On-Premise
  • "Code", Template Language Expression
  • Observations
  • Social
  • XML

 

Introduction - What are Azure Logic Apps

 

Microsoft announced a series of Azure App Services today:

http://weblogs.asp.net/scottgu/announcing-the-new-azure-app-service

 

Specifically, I want to focus on Azure Logic Apps.

http://azure.microsoft.com/en-us/documentation/articles/app-service-logic-what-are-logic-apps/

In Microsoft's words.

Azure App Service is a fully managed Platform as a Service (PaaS) offering ... allow any technical user or developer to automate business process execution via an easy to use visual designer.

Best of all, Logic Apps can be combined with API apps and Connectors from our Marketplace to help solve even tricky integration scenarios with ease.

 

Microsoft has a tutorial on how to create Azure Logic Apps:

http://azure.microsoft.com/en-us/documentation/articles/app-service-logic-create-a-logic-app/

http://channel9.msdn.com/Shows/Azure-Friday/Azure-App-Service-Logic-Apps-with-Josh-Twist

You should go through these first.  There are a number of new Azure templates that are wordy to describe, but a video will show how it all works together fairly quickly.

So I only want to focus on the SharePoint Online Connectors.  They are easy to set up, but actually, tricky to find.

 

Create the Logic App

 

The Workflow:

  • Grab tweets from my twitter timeline and put them into my SharePoint Online List, then email me.

 

Once you watched the video and we start by creating our own Azure Logic App. 

image image

Once it's ready, head into Triggers and Actions - this is where the rules are defined.

image

On the right hand side you wouldn't have any API Apps in the resource group.  We'll configure them in a minute.  Click Visit the Marketplace

 

Configure the Office 365 Connector

 

image

There is a giant header at the top to add Office 365 Connector.  We should go ahead and add that. 

Note, in your happiness to add the Office 365 connector, you will, like me, completely fail to read "send and receive emails, calendar and contacts".  No files, or SharePoint sites.  Essentially, this connector is only for Exchange-related services.

Still useful for sending emails, so let's configure it.

image image image

 

Go back to Triggers and Actions on the Logic App

image

  • Sometimes - the API Apps are listed by their template name and not the API App Name that you've assigned.  This is actually very confusing, I'm sure it'll be fixed soon.
  • Adding either the Office 365 Connector or the SharePoint Online Connector will also add the HTTP and Recurrence API Apps automatically.

 

 

Configure the SharePoint Online Connector

http://azure.microsoft.com/en-us/documentation/articles/app-service-logic-connector-sharepoint/

So far so good.  Let's do the next one.  And I think you'll fall into another hole.

You look at this and you say, surely.  That one is for SharePoint, since the earlier Office 365 connector isn't.

image

 

image

Yes, I say.  That's exactly what I want.  Those are the right triggers and actions!

image

And here is the next hole I fell in.

Chances are, you got all the way to the end and thought why do I need a service bus for Azure Logic App to talk to Office 365.  Something don't smell right.

I have failed to read the text again - this one is for On-Premises SharePoint, and you will need to install a listener proxy that will talk to Azure Logic Apps via an Azure Service Bus.

We'll cover that later when we talk about Hybrids.

For now, go back to the Marketplace.

image

Use the search filter.  There are 2 SharePoint connectors.  The SharePoint Online Connector isn't shown in the default view.

 

image

Create -> Package Settings -> OK <- Create

 

TIP: Unpin

 

image

While you wait for the API App to be created, your Startboard is currently looking like a mess.  Right click on the other connectors and unpin from Startboard.

 

Add the Twitter Connector

This is in the video above.  So I'll jump through this one really quick.

image

More spinning.  All done!  OK now we have all our connectors.  Let's look at them.

 

Triggers

 

I want to show the various different triggers from different connectors.  But I won't actually use these in the later example.

image image image image
Office 365 Trigger looks like this. SharePoint Online Trigger looks like this Twitter Trigger looks like this The trigger I want to use is a simple Recurrence timer.  It will run every hour.

 

Activities

 

image

Next, pull down some tweets.

Add Twitter Connector and Authorize

image image

Twitter Authorize, and set up to grab my timeline.

I want to put them into SharePoint Online.

image image

Click Authorize - you'll see a pop up

  • I want this to talk to my Office 365 Work Account - so pick the top one. 
  • Note - sometimes, it doesn't seem to work, I would close the pop up and try Authorize again.  I consider this another Preview Bug

image image

You should see these actions to perform on the connector.  Notice it connects to two lists specified during the setup, and there doesn't seem to be a way to change that afterwards.

Pick Insert Into tasks

 

We'll need to loop through the tweets and insert each one.

image  imageimage

We need to change the TweetText reference from the First tweet to Each Repeating Item tweet.

Change it from:

  • @first(body('twitterconnector')).TweetText

to

  • @repeatItem().TweetText

 

 

Last action is an email.  Add the Connector.

image image

The Office365 Connector (Exchange) is the same as Office 365.

I set the body to the created date of the first tweet (in descending order, so actually the latest tweet).

  • @first(body('twitterconnector')).Created_at

 

The big picture:

image

 

Save

image

:-)

You save and close the Triggers and Actions editor.

image

:-(

Thanks.  I think you forgot I had just saved...  (another preview bug)

 

Back on the Logic App screen, I see this:

image image

With a Recurrence trigger I find it always run first time I save.  But if it doesn't, you can manually Run Now

 

And the results

 

Here we have it.

The list, in my Tasks list on my SharePoint Online.

image

 

Email

 

The email I received.

image

  • I don't know why the email is default to send with low importance.  You can change this.

 

image image

Click the Pencil - I find that it is not intuitive that's clickable.  I think it should be next to the cog wheel.

 

And that's quite possibly the easiest Tweets to SharePoint Online List example (including set up the infrastructure) that I have ever done.

Summary

 

  • Created Office 365, SharePoint Online, Twitter connectors.
  • Created Azure Logic App on recurrence schedule
  • Write tweets to SharePoint List
  • Next episode, we'll look at Hybrid.  Going Cloud to/from On-Premises. 

Working with XML in Nintex Workflows (simplified)

 

Problem:

You call an XML web service with Nintex Web Service or Web Request actions.  You get back a lot of XML, and it is very difficult to work with the namespaces getting in your way.

 

Solution:

 

1. Do a quick XSLT post processing in the action, remove all the namespaces with XSLT transform.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">    
<xsl:template match="*">        
    <xsl:element name="{local-name()}">            
    <xsl:apply-templates select="@* | node()" />        
    </xsl:element>
</xsl:template>    
<xsl:template match="@*">        
    <xsl:attribute name="{local-name()}">            
    <xsl:value-of select="." />        
    </xsl:attribute>    
</xsl:template>    
<xsl:template match="text() | comment() | processing-instruction()">
    <xsl:copy />    
</xsl:template>
</xsl:stylesheet>

 

2. Force top level XML node.

This ensures if your service returns multiple top level elements they get wrapped together.

 

3. Use XPath in Query XML Action like this:

/xml/Results/Result/Title

 

Sometimes, after you've wasted half a day working with XML, you just want the simple, no frills, just make it work version.

This will hopefully help you too.

 

Big thanks to Jumpei Yamauchi for helping me with this one.

Feb 2015 CU SP2013: Workflow CurrentSiteUrl is fixed

 

http://support.microsoft.com/KB/2920804

Assume that you create a SharePoint 2013 workflow by using SharePoint Designer 2013, and that the workflow contains an action that retrieves data from the "Current Site URL" field in the "Workflow Context" data source. When you run the workflow, the value retrieved from the "Current Site URL" field is missing a forward slash ("/") at the end of the URL.

 

A few months ago, Microsoft released an update to SharePoint 2013, and it broke many SharePoint Designer Workflows.

If you use the new capabilities in SharePoint 2013 to call REST services, it is very common to concatenate the URL using a combination of the Current Site Url as well as the api/ path.

"http://server/site/" + "_api/web/lists/getbytitle('Announcements')"

The problem is that Microsoft removed the trailing / in the Current Site Url.  This broke many REST calls.

"http://server/site" + "_api/web/lists/getbytitle('Announcements')"

Is no longer valid.  The fix is to reopen all your workflows that are showing this problem, and add a preceding / before _api.  Like this:

"http://server/site" + "/_api/web/lists/getbytitle('Announcements')"

 

Now, with the February 2015 patch, Microsoft is fixing the workflow action again.  Guess what.

"http://server/site/" + "/_api/web/lists/getbytitle('Announcements')"

 

I think this looks dirty

 

Technically, your workflow probably won't break over this.

"http://server/site//_api/web/lists/getbytitle('Announcements')"

Should return you the same values as

"http://server/site/_api/web/lists/getbytitle('Announcements')"

 

But it looks terrible.

SPD2013 Workflow - how to check user is member of group

 

I want to describe a method that I use to check if a user is a member of a group.

 

Steps

  • Call a REST webservice
    • Reference MSDN for the correct API
    • Build a RequestURL and a basic RequestHeader
    • Figure out what the results mean
  • Wrap it up in a Workflow Custom Activity

 

API

MSDN (http://msdn.microsoft.com/en-us/library/office/dn268594(v=office.15).aspx - this needs to be a SharePoint Developer's home page) documents a few REST end points that I use for this.

http://msdn.microsoft.com/en-us/library/office/dn531432(v=office.15).aspx#bk_Group

Says you can get to a sharepoint group via:

  • http://<site url>/_api/web/sitegroups(<group id>)
  • http://<site url>/_api/web/sitegroups(<group name>)

The group also has a Users property that points to a Users Collection.

http://msdn.microsoft.com/en-us/library/office/dn531432(v=office.15).aspx#bk_UserCollection

This expands our example to:

  • http://<site url>/_api/web/sitegroups(<group id>)/users

For example:

 

The Users Collection does not have a method for testing if a user exists.  So I've taken the shortcut and basically brute force the service and just try to retrieve a user.  If you try to request a user that doesn't exist in the collection, it will just error, and I just catch that error.

 

SharePoint Designer workflow

 

image

 

Build Request Header

image

Both Accept and Content-Type needs to be "application/json;odata=verbose"

 

Build Request URL

image

Concatenate Current Site URL (which ends without a trailing /) and the earlier API.

Note my group name is 'john Members'

 

Call Web Service

image

 

Catch and process the result value.

image

 

The ResponseCode could be either OK or InternalServerError

Get a property from the returned Response variable "d/Title" would correspond to the Display Name of the user returned.  If the ResponseCode was Error, then there would be no value in the Response object.

 

 

Sandbox Custom Workflow Activity

 

In Visual Studio, these activities can be bundled into one single Activity that can be reused in SharePoint Designer.  I'll update this in a future blog post on Visual Studio.

 

 

Thoughts on checking nested group or AD group memberships

  • There are no way to check member with nested groups.  One possibility is to not think of it as membership, but think of it as whether the person has a certain permission.

    Does the current user have permission to do Contribute on the current Site. 
  • A more complicated thinking could be to create a list, kick out everyone except the group you are interested in, and check if the current user has permission to that list.

 

 

This Example in JavaScript

 

The more I work with SharePoint 2013 Workflows the closer parallels I see relating to a traditional programming language.  Here's the same function call in Javascript.

var promise = $.ajax({
        type: "GET",
        url: _spPageContextInfo.siteServerRelativeUrl + "/_api/web/sitegroups/getbyname('john Owners')/users/getbyid(" + _spPageContextInfo.userId + ")",
        headers: {
                "accept": "application/json;odata=verbose"
        },
        contentType: "application/json;odata=verbose",
        dataType: "json",
        cache: false,
        processData: true
});

promise.then(
        function (data, status) {

                if (status == "success" && data && data.d) {
                        var title = d.Title;

                }
                else {
                    // success, but no records - this can't really happen.
                }
        },
        function () {
                // not successful - usually not a member of that group
        }
);