0

I need to create a JS-Library which can run workflow using new WebApi for Dynamics CRM 2016:

I need to start workflow from my Code. (workflow should be “real-time”) and not asynchronously . I will build my function-call into Ribbon on form. If anyone can help me I would be more then thankful, since I searched all internet and could not found how to solve this, except from above link where I found this method

but I'm not sure how to use this method? Once agin it has to be “real-time” I found solutions such as:

-https: //processjs.codeplex.com/

but this does not work for me since it run workflow asynchronously. It has to be using Web API from link provided above. I think that this Web API works only for Microsoft Dynamics 2016

Dan
  • 448
  • 10
  • 20
  • Could you please edit the question and add some extra context? I'm struggling to understand what do you want to accomplish executing a synchronic workflow using the webapi endpoint. – Federico Jousset Oct 14 '16 at 13:12
  • @Federico Jousset I realized that workflow has it own setup, to be "realtime" and its not on javascript to achieve. I used solution from processjscodeplex.com/ even though it says its async call I assume that they thought on ajax call, i will know in a few days is this kind of access ok, but since I didn't find anything other on internet or on that WebApi documentation I'm guessing it is. Currently I'm trying to read workflow based on its name:-http://columbuscrm.blogspot.rs/2016/04/get-workflow-guid-in-javascript-using.html but I encounter on some problems. In case of some progress/problems – Dan Oct 17 '16 at 00:56
  • Great Dan, I was asking mainly because the ExecuteWorkflowRequest is not currently available in the WebAPI endpoint. Just give a shout if you need something else. – Federico Jousset Oct 17 '16 at 08:44

3 Answers3

2

Now that we have actions there really isn't a need to start a workflow from javascript anymore. I used to do so using a javascript library that used the SOAP api but the web api actions are much easier to use. And an action is created in the same way as a workflow. To create an action go to create a workflow but instead of choosing workflow from the dropdown select action. You will end up with a form like this. enter image description here Remember the unique name and the entity which you will run it against. In this example I'll be using this workflow pictured which runs against a contact record. From javascript I can now issue a POST to

https://<your-crm-server>/api/data/v8.0/contacts(<contact-id>)/Microsoft.Dynamics.CRM.wa_GetContactSyncStatus

Again this is an action targeting contacts and running the wa_GetContactSyncStatus action, change the values to what you need them to be. Also as a side note this is against a 2016 server anything later will have a different api version for you to use. Consult the developer resources page in your crm instance to figure out what your url for the web api is.

The action will run asynchronously and as long as your javascript request is set to be synchronous as well your request will return when the action is complete.

As another side note if you have your action call another workflow that isn't synchronous it will quite probably return before your asynchronous background workflow does.

Reuben Swartz
  • 206
  • 1
  • 6
  • But in this case action will run asynchronously, right? Since condition for workflow is to be synchronously, why action should be async in that case? Also I need to change web api call every time new api version is used on server right? Thanks – Dan Oct 19 '16 at 08:50
  • @Dan the actions run synchronously. You should be good to use the 8.0 API as it will be backwards compatible for a while. – Reuben Swartz Oct 19 '16 at 12:20
  • @ReubenSwartz - does this still require the whole build up of the XML request? E.g. I see you gave a URL, but what would calling it look like? – Don Cheadle Oct 18 '17 at 14:23
  • @mmcrae Nope you don't need to build an XML request. You can use JSON to interact with the new web API. Here is Microsoft's documentation about calling them that would explain it a lot better then me. https://msdn.microsoft.com/en-us/library/mt607600.aspx – Reuben Swartz Oct 18 '17 at 20:20
1

I do this quite often: make the process an Action, they are designed specifically for this purpose (click a ribbon button and invoke what essentially is a workflow through WebAP; they also become custom messages for plugin registration, which is nice in some scenarios).

To have synchronous invocations all you need to do is to make the XmlHttpRequest synchronous by tweaking the open statement:

// 'xhr' is the XMLHttpRequest 
xhr.open(http_method, request_url, false); <-- third parameter 'false' means sync request

I never use libraries to invoke the webapi so unfortunately I can't suggest any library-specific piece of code, but I would assume any decent library allows you to make XHR requests synchronous.

(Mandatory warning: sync requests are suboptimal and browsers do complain about them, I expect Chrome in particular to start breaking sync code at some point in the future).

Alex
  • 23,004
  • 4
  • 39
  • 73
  • This looks like the same solution as Domenicos Zinzi 's answer above. – Don Cheadle Oct 18 '17 at 14:01
  • @mmcrae it isn't, that answer references the 2011 endpoint which is deprecated and pending removal from CRM https://msdn.microsoft.com/en-us/library/dn281891.aspx#Crm2011Endpoint – Alex Oct 19 '17 at 07:37
  • I ended up using a 3rd party library to call an Action from a ribbon button click - https://github.com/PaulNieuwelaar/processjs – Don Cheadle Oct 20 '17 at 14:58
1

Soap Request in JS :

function RunWorkflow(in_entitiId,in_workflowId,in_url) { 
    var _return = window.confirm('Do you want to execute workflow ?');
    if (_return) {
        var url = in_url;
        var entityId =in_entitiId ;
        var workflowId = in_workflowId;
        var OrgServicePath = "/XRMServices/2011/Organization.svc/web";
        url = url  + OrgServicePath;
        var request;
        request = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
                    "<s:Body>" +
                        "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">" +
                        "<request i:type=\"b:ExecuteWorkflowRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\" xmlns:b=\"http://schemas.microsoft.com/crm/2011/Contracts\">" +
                            "<a:Parameters xmlns:c=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">" +
                            "<a:KeyValuePairOfstringanyType>" +
                                "<c:key>EntityId</c:key>" +
                                "<c:value i:type=\"d:guid\" xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/\">" + entityId + "</c:value>" +
                            "</a:KeyValuePairOfstringanyType>" +
                            "<a:KeyValuePairOfstringanyType>" +
                                "<c:key>WorkflowId</c:key>" +
                                "<c:value i:type=\"d:guid\" xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/\">" + workflowId + "</c:value>" +
                            "</a:KeyValuePairOfstringanyType>" +
                            "</a:Parameters>" +
                            "<a:RequestId i:nil=\"true\" />" +
                            "<a:RequestName>ExecuteWorkflow</a:RequestName>" +
                        "</request>" +
                        "</Execute>" +
                    "</s:Body>" +
                    "</s:Envelope>";

        var req = new XMLHttpRequest();
        req.open("POST", url, true)
        // Responses will return XML. It isn't possible to return JSON.
        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
        req.onerror = displayError;
        req.onreadystatechange = function () { assignResponse(req); };
        req.send(request);
    }
    function displayError(e) {
    alert(this.status);
    }

}

function assignResponse(req) {
    if (req.readyState == 4) {
        if (req.status == 200) {
            alert('successfully executed the workflow');
        }
    }
}

Example:

RunWorkflow(Xrm.Page.data.entity.getId(),"21E95262-5A36-46CA-B5B5-3F5AA539A9AF","https://org.dynamics.com");
Domenico Zinzi
  • 954
  • 10
  • 18
  • 1
    SOAP endpoint is currently deprecated and is going to be removed in the near future https://msdn.microsoft.com/en-us/library/dn281891.aspx#Crm2011Endpoint – Alex Oct 19 '17 at 07:36