Any suggestion how to trigger SharePoint online site workflow using REST APIs I'm trying to use:

/_api/SP.WorkflowServices.WorkflowSubscriptionService.Current/EnumerateSubscriptions()?Select=Id

to get the workflow subscription Id, then I'm using:

/_api/SP.WorkflowServices.WorkflowInstanceService.Current/StartWorkflow(Subscription=)

the first API call going well with OK response and I'm able to grab the Id, but the second call doesn't start the workflow and returns BadRequest !

I've written a function that lets you fire off workflows using JavaScript.

https://gist.github.com/iOnline247/1b3c26f7175296a44274

I've copied the code here, but it may change over time, so refer to the Github link for the most up to date code.

Use this to fire list workflows by name or subscriptionId.
Raw  $sp.wf.js
/*!
 * Created by Matthew Bramer - @iOnline247
 * Released under the MIT license
 * Date: 2015-04-18
 * Props to: http://plumsail.com/blog/2015/02/start-sharepoint-2013-workflows-selected-items/
 * Tested using SharePoint Online.
 * On-Prem still needs testing.
 */

window.$sp = window.$sp || {};
window.$sp.wf = (function( $, undefined ) {
    "use strict";
    var ctx,
        web,
        wfManager,
        JS_SUFFIX = ".js",
        SP_WORKFLOW_SERVICES = "SP.WorkflowServices",
        SP_WORKFLOW_SERVICES_SCRIPT_NAME = SP_WORKFLOW_SERVICES + JS_SUFFIX,
        risGuid = /[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i,
        oDataHeader = "application/json;odata=verbose",
        initializeVariables = function() {
            ctx = SP.ClientContext.get_current();
            web = ctx.get_web();
            wfManager = SP.WorkflowServices.WorkflowServicesManager.newObject( ctx, web );
        },
        registerWFscripts = function() {
            SP.SOD.registerSod(
                SP_WORKFLOW_SERVICES_SCRIPT_NAME,
                SP.Utilities.Utility.getLayoutsPageUrl( SP_WORKFLOW_SERVICES + JS_SUFFIX )
            );
            SP.SOD.executeFunc(
                SP_WORKFLOW_SERVICES_SCRIPT_NAME,
                SP_WORKFLOW_SERVICES + ".WorkflowServicesManager",
                initializeVariables
            );
        },
        init = function() {
            SP.SOD.executeFunc(
                "sp" + JS_SUFFIX,
                "SP.ClientContext",
                registerWFscripts
            );
        },
        set_errorHandler = function( func ) {
            errorHandler = func;
        },
        errorHandler = function( sender, args ) {
            var message = this,
                spError = args && args.get_message,
                restAPIError = sender && sender.responseText

            ;

            if( this.id ) {
                message += " on item with ID: " + this.id;
            }

            SP.UI.Notify.addNotification( message, false );
            console.log( message );

            if( spError ) {
                console.log( "Error:", args.get_message(), "\nStackTrace:", args.get_stackTrace() );
            }

            if( restAPIError ) {
                console.log( restAPIError );
            }
        },
        set_successHandler = function( func ) {
            successHandler = func;
        },
        successHandler = function( sender, args ) {
            var wfName = this.name || this.subscription && this.subscription.get_name(),
                message = "Workflow " + wfName + " has started."

            ;

            if( this.id ) {
                message = message.replace(".", "");
                message += " on this item. ID: " + this.id;
            }

            SP.UI.Notify.addNotification( message, false );
        },
        fireWfByName = function( sender, args ) {
            var subscription = this.subscription,
                id = this.id,
                initiationParams = this.initiationParams || {},
                workflows = subscription.getEnumerator(),
                workflow,
                foundWrkFlow = false

            ;

            while( workflows.moveNext() ) {
                workflow = workflows.get_current();

                if( workflow.get_name() === this.name ) {
                    startWorkflow({
                        subscriptionId: workflow.get_id(),
                        id: id,
                        initiationParams: initiationParams
                    });

                    foundWrkFlow = true;
                    break;
                }
            }

            if( !foundWrkFlow ) {
                errorHandler.call( "Could not find workflow named: " + this.name );
            }
        },
        fireWfBySubscription = function( sender, args ) {
            var subscription = this.subscription,
                id = this.id,
                initiationParams = this.initiationParams || {},
                wfInstance = wfManager.getWorkflowInstanceService()

            ;

            // https://msdn.microsoft.com/en-us/library/office/microsoft.sharepoint.client.workflowservices.workflowinstanceservice_methods.aspx

            if( id ) {
                wfInstance.startWorkflowOnListItem( subscription, id, initiationParams );
            } else {
                wfInstance.startWorkflow( subscription, initiationParams );
            }

            ctx.executeQueryAsync(
                successHandler.bind( this ),
                errorHandler.bind( "Could not fire workflow. SubscriptionId: " + this.subscriptionId )
            );
        },
        startWorkflow = function( opt ) {
            var subscriptionService = wfManager.getWorkflowSubscriptionService(),
                success,
                error

            ;

            // different methods to fire workflows with 2013.
            // https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.workflowservices.workflowsubscriptionservice_members.aspx
            if( opt.subscriptionId ) {
                opt.subscription = subscriptionService.getSubscription( opt.subscriptionId );
                ctx.load( opt.subscription );
                success = fireWfBySubscription.bind( opt );
                error = errorHandler.bind( "Failed to load subscription: " + opt.subscriptionId );
            } else {
                opt.subscription = subscriptionService.enumerateSubscriptions();
                ctx.load( opt.subscription );
                success = fireWfByName.bind( opt );
                error = errorHandler.bind( "Failed to load workflow subscriptions." );
            }

            ctx.executeQueryAsync(
                success,
                error
            );
        },
        removeDemCurlies = function( v ) {
            return v.replace( /{|}/g, "" );
        },
        getListItemDeets = function( listUrl ) {
            return $.ajax({
                type: "GET",
                url: listUrl,
                dataType: "json",
                headers: {
                    "Accept": oDataHeader,
                    "Content-Type": oDataHeader
                }
            });
        },
        fire2010Workflow = function( data ) {
            var success,
                listGuid = data.d.__metadata.uri.match( risGuid )[ 0 ],
                itemId = data.d.GUID
            ;

            this.result = this.subscriptionService.startWorkflow( this.name, null, listGuid, itemId, this.initiationParams );
            success = successHandler.bind( this );

            ctx.executeQueryAsync(
                success,
                this.error
            );
        },
        start2010Workflow = function( opt ) {
            var subscriptionService = wfManager.getWorkflowInteropService(),
                wfName = opt.name,
                id = opt.id,
                itemGuid,
                initiationParams = opt.initiationParams,
                queryPrefix = "/_api/web/lists",
                querySuffix = "/items(" + id + ")?$select=GUID",
                // May need to do this later when ctx is dynamic.
                // listUrl = web.get_url(),
                listUrl = _spPageContextInfo.webAbsoluteUrl + queryPrefix,
                listGuid,
                errorMessage = "Failed to fire 2010 {0} Workflow.",
                success,
                error

            ;

            // Fire 2010 workflows!
            // https://msdn.microsoft.com/en-us/library/office/microsoft.sharepoint.client.workflowservices.interopservice.startworkflow.aspx

            // Not sure if opt.result is going to be helpful, but leaving it here for the meantime.
            // If it is useful, then I'll bind it to the both handlers.
            // If not, I'll drop it altogether.
            if( id ) {
                listGuid = opt.list.match( risGuid );
                if( listGuid ) {
                    listGuid = removeDemCurlies( listGuid[ 0 ] );
                    listUrl += "(guid'" + listGuid + "')";
                } else {
                    listUrl += "/GetByTitle('" + opt.list + "')";
                }

                listUrl += querySuffix;

                // converts numbers to strings.
                id = id + "";
                itemGuid = id.match( risGuid );

                if( listGuid && itemGuid ) {
                    // List GUID and item GUID were provided, no need for API call.
                    opt.result = subscriptionService.startWorkflow( wfName, null, listGuid, itemGuid[ 0 ], initiationParams );
                    success = successHandler.bind( opt );
                    error = errorHandler.bind( errorMessage.replace("{0}", "Site") );
                } else {
                    // Need to resolve List GUID and get the item GUID.
                    opt.subscriptionService = subscriptionService;
                    opt.error = errorHandler.bind( errorMessage.replace("{0}", "List") );

                    return getListItemDeets.bind( opt )( listUrl )
                        .then( fire2010Workflow.bind( opt ), opt.error );
                }
            } else {
                // Site WF
                opt.result = subscriptionService.startWorkflow( wfName, null, null, null, initiationParams );
                success = successHandler.bind( opt );
                error = errorHandler.bind( errorMessage.replace("{0}", "Site") );
            }

            ctx.executeQueryAsync(
                success,
                error
            );
        }

    ;


    init();

    // TODO:
    // On-Prem testing.
    // Look at custom events.
    // https://msdn.microsoft.com/en-us/library/office/dn481315.aspx
    // 2010 custom events.
    // https://msdn.microsoft.com/en-us/library/office/microsoft.sharepoint.client.workflowservices.interopservice.startworkflow.aspx
    // Add promises.
    return {
        set_errorHandler: set_errorHandler,
        set_successHandler: set_successHandler,
        startWorkflow: startWorkflow,
        start2010Workflow: start2010Workflow
    };
}( window.jQuery ));


/*
 * Usage
 * via subscriptionId or Workflow Name. Preferably the latter.
*/

// List bound WF fired by Workflow Name, Muy bien!
$sp.wf.startWorkflow({
    name: "Send Email",
    id: 1,
    initiationParams: {
        EasyText: "What's up?",
        // `Here I Am` is the real initation parameter name. Note the spaces.
        HereIam: "<p><b>heyo!</b></p><p>otra ves</p>"
    }
});

// Site workflows! YaY!
$sp.wf.startWorkflow({
    name: "Site WF",
    initiationParams: {
        WooP: "<b>That's what's up!</b>"
    }
});

// 2010 Site WF!
$sp.wf.start2010Workflow({
    name: "Site WF - 2010",
    initiationParams: {
        // `Something with Spaces` is the real initation parameter name. Note the spaces and casing.
        SomethingwithSpaces: "<b>That's what's up!</b>"
    }
});

// 2010 List Bound WF.
$sp.wf.start2010Workflow({
    name: "SendEmail2010",
    list: "Test",
    id: 1,
    initiationParams: {
        "ThingsChangePeopleChange": "<b>Used list display name and item id.</b>"
    }
});

$sp.wf.start2010Workflow({
    name: "SendEmail2010",
    list: "{FD21AC5B-15D9-443A-B7A5-1FB6A2AF667D}",
    id: 1,
    initiationParams: {
        "ThingsChangePeopleChange": "<b>Used list GUID and item id.</b>"
    }
});

$sp.wf.start2010Workflow({
    name: "SendEmail2010",
    list: "{FD21AC5B-15D9-443A-B7A5-1FB6A2AF667D}",
    id: "{211ffdfc-69c5-4206-917d-befe62a6ffb4}",
    initiationParams: {
        "ThingsChangePeopleChange": "<b>Used list GUID and item GUID. Prevents a call to SP's REST API.</b>"
    }
});

// The ugly duckling...  Don't use this, please. :)
// Via Subscription ID, YUCK!
$sp.wf.startWorkflow({
    subscriptionId: "{CE3890BC-3361-4F1C-9036-40A07E0EC449}",
    id: 1
});
  • Not using REST, but it'll get you there. – iOnline247 Feb 4 '16 at 20:52

Judging from the documentation, I don't know if you can call another SITE workflow using REST at least with the documentation I can find.

Look at the parameters for:

StartWorkflowOnListItemBySubscriptionId -

https://msdn.microsoft.com/en-us/library/dn683475(v=office.12).aspx

Then look at the parameters for:

StartWorkflow -

https://msdn.microsoft.com/en-us/library/hh657534(v=office.12).aspx

One is looking for a subscription ID the other is looking for a Microsoft.SharePoint.Client.WorkflowServices.WorkflowSubscription

That lines up with my testing where trying to use an ID in the place there returns:

'The method StartWorkflow cannot be invoked as its parameter subscription is not supported'

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.