Below is some sample code to provision a workflow on the host web from your app web. This sample code is in one block for demo purposes. It makes 4 asynchronous calls to SharePoint to complete successfully.

In the event you’d want to define in your App a workflow that would run on a list in the host web this is the code you would use to deploy (move it from App to Host) and attach it to a list in the host web.

NOTE: you must include a reference to “/_layouts/15/SP.WorkflowServices.js”

   var attachWorkflow = function(workflowName, workflowListName, workflowHistoryListName, workflowTasksListName) {

        //Using the App Web as the client context
		clientContext = new SP.ClientContext.get_current();
   
		//Get the host web URL from the query string params
		//I have a function getHostWebUrl() - which is not included.
		//http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript
		var hostWebUrl = getHostWebUrl();
		
		//Using the hostWebContext as an AppContextSite
        hostWebContext = new SP.AppContextSite(clientContext, hostWebUrl);
        
		//Get the Workflow Services Manager for the Host web, NOTE: you initialize it with the clientContext & the hostWebContext Web)
        var hostWebWorkflowServicesManager = new SP.WorkflowServices.WorkflowServicesManager.newObject(clientContext, hostWebContext.get_web());
        var hostWebWorkflowDeploymentService = hostWebWorkflowServicesManager.getWorkflowDeploymentService();
        var hostWebSubscriptionService = hostWebWorkflowServicesManager.getWorkflowSubscriptionService();

		//Get the Workflow Services Manager for the App web 
        var workflowServicesManager = new SP.WorkflowServices.WorkflowServicesManager(clientContext, clientContext.get_web());
        var workflowDeploymentService = workflowServicesManager.getWorkflowDeploymentService();
        var workflowDeploymentServiceDefinitions = workflowDeploymentService.enumerateDefinitions(false);

		//Load all the Workflow Definitions from the App web
        clientContext.load(workflowDeploymentServiceDefinitions);
        clientContext.executeQueryAsync(function () {

			//Get the enumerator for all the workflow definitions in the App web
            var workflowDefinitions = workflowDeploymentServiceDefinitions.getEnumerator();
            while (workflowDefinitions.moveNext()) {

				//set the current definition to a variable
                var workflowDefinition = workflowDefinitions.get_current();
				//test, trying to locate your workflow in the App web
                if (workflowDefinition.get_displayName() === workflowName) {

					//now grab the xaml definition of the selected workflow
                    var workflowXaml = workflowDefinition.get_xaml();

					//define a new workflow and assign it xaml & name
                    var newWorkflow = new SP.WorkflowServices.WorkflowDefinition.newObject(clientContext, hostWebContext.get_web());
                    newWorkflow.set_xaml(workflowXaml);
                    newWorkflow.set_displayName(workflowName);
					
					//using the host webs Workflow Deployment Service, save the workflow.
                    hostWebWorkflowDeploymentService.saveDefinition(newWorkflow);
                    
					//load the new workflow and initialize the Id
					clientContext.load(newWorkflow, "Id");
					//this query will save your workflow to the host web
                    clientContext.executeQueryAsync(function() {

						//publish the workflow on the host web
                        hostWebWorkflowDeploymentService.publishDefinition(newWorkflow.get_id());
						
						//getting all the lists that the workflow will attach to
						//these lists already created on the host web
                        var targetList = hostWebContext.get_web().get_lists().getByTitle(workflowListName);
                        var historyList = hostWebContext.get_web().get_lists().getByTitle(workflowHistoryListName);
                        var tasksList = hostWebContext.get_web().get_lists().getByTitle(workflowTasksListName);

						//loading the lists & initialize the Id
                        clientContext.load(targetList, "Id");
                        clientContext.load(historyList, "Id");
                        clientContext.load(tasksList, "Id");

						//this query will publish the workflow and get the required list id's for the next step
                        clientContext.executeQueryAsync(function() {

								//creating a new workflow subscription
                                var subscription = new SP.WorkflowServices.WorkflowSubscription(clientContext, hostWebContext.get_web());

								//setting some properties of the subscription
                                subscription.set_name(workflowName + "-ItemAdded");
                                subscription.set_enabled(true);
                                subscription.set_definitionId(newWorkflow.get_id().toString());
                                subscription.set_eventSourceId(targetList.get_id());
                                subscription.set_eventTypes(["ItemAdded"]);

								subscription.setProperty("TaskListId", tasksList.get_id().toString());
                                subscription.setProperty("HistoryListId", historyList.get_id().toString());
                                subscription.setProperty("FormData", "");

								//attaching the subscription to the target list 
                                hostWebSubscriptionService.publishSubscriptionForList(subscription, targetList.get_id());

								//this query will execute the creation of the new subscription and adding attaching the subscription to the target list on the host web
                                clientContext.executeQueryAsync(function() {
                                    console.log("Workflow : \"" + workflowName + "\" successfully added to list : \"" + workflowListName + "\"");
                                }, function(sender, args) {
                                    console.log("Workflow : " + workflowName + " not successfully added to list : " + workflowListName);
                                    console.log("Reason : " + args.get_message() + "");
                                });
                            },
                            function(sender, args) {
                                console.log("Failed to get workflow list IDs");
                                console.log("Reason : " + args.get_message() + "");
                            });

                    }, function(sender, args) {
                        console.log("Failed to create the workflow definition");
                        console.log("Reason : " + args.get_message() + "");
                    });
                }
            }
        }, function (sender, args) {
            console.log("Could not find workflow : " + workflowName);
            console.log("Reason : " + args.get_message() + "");
        });
    };
About the Author

Developer, Designer, Thinker, Problem Solver, Office Servers and Services MVP, & Collaboration Director @ SoHo Dragon.

View Articles