Incoming Webhooks

Overview
Configuration
Creating an incoming webhook application
Sending data in JSON
System access users
Incoming webhook operations
Delegation mode
clientMutationId
Known limitations
Performance optimization

Overview

WorkflowGen features an incoming webhook application that allows users to interact with WorkflowGen from external sources by exchanging JSON payloads using HTTP POST requests. The application supports multiple types of operations:

  • Create a new request

  • Cancel a request

  • Complete an action

  • Cancel an action

  • Assign an action

  • Cancel an action assignment

  • Update a request dataset

  • Create a favorite

  • Update a favorite

  • Delete a favorite

  • Add a comment

  • Remove a comment

  • Cancel a request's actions by name

Configuration

Maximum query content length

The maximum query content length for incoming webhooks can be set by configuring the maxAllowedContentLength property in the WorkflowGen web.config file. The following example shows how to configure this property as 1 MB (note that the value should always be specified in bytes, so the value in the example is 1,024,000 bytes). The default value is 30,000,000 bytes.

<system.webServer> 
    <security> 
        <requestFiltering> 
            <requestLimits maxAllowedContentLength="1024000" /> 
        </requestFiltering> 
    </security> 
</system.webServer>

Performance tuning

WorkflowGen is installed with the following default webhooks settings (located under iisnode in \wfgen\hooks\web.config):

nodeProcessCountPerApplication="1"
maxConcurrentRequestsPerProcess="1024"

With these settings, only one node.exe instance will handle HTTP requests. This should be sufficient in most cases, but you can optimize performance if needed by adjusting these values based on the number of potential concurrent requests.

Create an incoming webhook application

To create a new incoming webhook application in your WorkflowGen application, click the Add Application button on the Applications page. Then, choose Incoming webhook from the Application type drop-down list, enter the Name and Description, and click Save.

The Applications page will now display your incoming webhook application information, including the application URL. This is the URL you should use to send WorkflowGen incoming webhhoks. The last component of this URL corresponds to a token that WorkflowGen will use to identify your incoming webhooks.

You should fill in the Impersonate username textbox with the WorkflowGen username you use to perform your desired operations. Be aware that your impersonated user must have your asked-operation-required rights to complete the action; if not, you will receive a security error on your response payload. As well, if the impersonate username is not set, the workflow engine service default identity will be used (as defined in the Security section on the Integration tab in the Configuration Panel).

Important notes

  • The generated URL and its associated token must remain private and not exposed to end-users in client-side (in JavaScript, for example). You should treat the token with the same level of security as you would a password.

  • If the token used in the incoming webhook URL is missing or invalid, a 404 status code will be returned. If the associated user is invalid, archived, or inactive, a 403 status code will be returned. In both cases, the response will contain a descriptive error message.

Send data in JSON

The incoming webhook application receives your HTTP POST request payload formatted as a JSON object.

Using the URL provided, you can post HTTP requests from external applications (e.g. Postman) to WorkflowGen in order to execute the available operations in your WorkflowGen application. For operations that require you to provide an object ID, the object ID value can be retrieved by using the GraphQL API. In most cases, object numbers can be used instead of IDs in operation payloads.

In case of an error, you will get a response payload providing error details such as:

{
  "error": "Advantys.Workflow.ServiceFacade: CreateRequest error: A process ID or name is required"
}

Curl example

The requests should respect the structure shown in this example, where operation refers to the name of the operation to execute, and args contains the input node that groups all of the request parameters to perform the operation.

To create a new request, the processName parameter is required. The processVersion parameter is optional and is used to find the correct process you want to use to create your request.

curl -u yourusername -X POST -H "Content-Type: application/json" -d '{
  "operation": "createRequest",
  "args": {
    "input": {
      "processName": "2_LEVELS_APPROVAL",
      "processVersion": 1
    }
  }
}' http://localhost/wfgen/hooks/yourtoken
Response payload

The response payload will be structured as follows:

{
  "clientMutationId": null,
  "requestId": "UmVxdWVzdDoxNzI4",
  "number": 10,
  "onBehalfOf": null,
  "onBehalfOfUserName": null
}
  • clientMutationId: This parameter will be null if the request creator did not define it in the request payload.

  • requestId: The newly created request ID.

  • number: The newly created request number.

  • onBehalfOf: This parameter contains the delegator ID; however, if the request was not created in delegation mode, its value will be null.

  • onBehalfOfUserName: This parameter contains the delegator username; however, if the request was not created in delegation mode, its value will be null.

System access users

Some operations (such as CancelAction and UpdateRequestDataset) require users to have system access to perform the operations. This can be configured in the System operations allowed users field under Security on the Integration tab in the Configuration Panel.

Incoming webhook operations

Create a new request

Request payload
{
  "operation": "createRequest",
  "args": {
    "input": {
      "processName": "2_LEVELS_APPROVAL",
      "processVersion": 1
    }
  }
}
Response payload
{
  "clientMutationId": null,
  "requestId": "UmVxdWVzdDoxNzI4",
  "number": 1728,
  "onBehalfOf": null,
  "onBehalfOfUserName": null
}

A parameter's array can be included in the createRequest operation payload. Be aware that a data with the same name and data type must previously exist in the process for each parameter in the array to store the parameter's value. The following example shows how to send parameters corresponding to the four supported data types (TEXT, NUMERIC, DATETIME, and FILE).

Request payload
{
  "operation": "createRequest",
  "args": {
    "input": {
      "processName": "2_LEVELS_APPROVAL",
      "processVersion": 1,
      "parameters": [
        {
          "name": "TEXT",
          "textValue": "My text parameter"
        },
        {
          "name": "NUMERIC",
          "numericValue": 5
        },
        {
          "name": "DATE",
          "dateTimeValue": "2017-02-23T20:46:00Z"
        },
        {
          "name": "FILE", 
          "fileValue": {
            "name": "TestFile.txt",
            "contentType": "text/plain",
            "size": 616,
            "url": "file:///c:/TestFile.txt",
            "updatedAt": "2017-02-21T15:06:38Z"
          }
        }
      ]
    }
  }
}
Response payload
{
  "clientMutationId": null,
  "requestId": "UmVxdWVzdDoxNzY1",
  "number": 1765,
  "onBehalfOf": null,
  "onBehalfOfUserName": null
}

Working with FILE parameters

As of version 7.2.0, the incoming webhook application supports the fileValue.url, fileValue.content, and fileValue.updatedAt fields when sending FILE parameters (as shown in the previous example):

  • fileValue.url: The file URL. The following path patterns are supported:

    Local file should use the File URI scheme:

    ...
    {
      "name": "FILE",
      "fileValue": {
          "name": "test.txt",
          "description": "test.txt",
          "contentType": "plain/text",
          "url": "file:///c:/temp/test.txt",
          "size": 4714,
          "updatedAt": "2017-03-15T15:02:00Z"
      }
    }
    ...
    

    Public file URL:

    ...
    {
      "name": "FILE",
      "fileValue": {
          "name": "update.zip",
          "description": "update.zip",
          "contentType": "application/zip",
          "url": "http://download.workflowgen.com/product/latest/update.zip",
          "size": 4120858,
          "updatedAt": "2017-03-15T15:02:00Z"
      }
    }   
    ...
    

    File URL:

    ...
    {
      "name": "FILE",
      "fileValue": {
          "name": "test.txt",
          "description": "test.txt",
          "contentType": "plain/text",
          "url": "http://localhost:8081/test.txt",
          "size": 4714,
          "updatedAt": "2017-03-15T15:02:00Z"
      }
    }
    ...
    
  • fileValue.content should contain the file content encoded in Base64. In this case, the fileValue.url field is not required.

  • fileValue.updatedAt should use the ISO 8601 date format.

Multipart file upload

As of WorkflowGen version 7.14.0, incoming webhooks support multipart file uploads for the following mutations:

  • createRequest

  • completeAction

  • completeFormAction

  • updateRequestDataset

Curl example for a single upload

curl -X POST http://localhost/wfgen/hooks/TOKENXXXXXXXXXXXXX -H 'content-type:multipart/form-data' -F "payload={\"operation\": \"createRequest\", \"args\": { \"input\": {\"processName\": \"SIMPLE_REQUEST\", \"processVersion\": 1, \"parameters\": [ { \"name\": \"FILE1\", \"fileValue\": {\"uploadMap\":\"1\" }}] } } }" -F "1=@C:\test1.txt"

  • The content type should be multipart/form-data.

  • The payload field is required and contains the operation and its arguments.

    • input.parameters[X].fileValue should contain an uploadMap whose value is the (\"fileValue\": {\"uploadMap\":\"1\" }) key of the file to be uploaded.

    • The key should be an alphanumeric string that matches the file key ("1" in the above example).

    • For each uploadMap declared, a file with the same key must be attached.

  • Each file to be uploaded should contain the alphanumeric key and the file path ("1=@C:\test1.txt").

    • Each attached file must match an uploadMap.

    • The files should follow the payload part.

Curl example for multiple uploads
curl -X \
    POST http://localhost/wfgen/graphql\
    -H 'content-type:multipart/form-data' \
    -F "operations={ \"query\": \"mutation ($fileUpload1: Upload, $fileUpload2: Upload) { createRequest(input: {processName: \\\"SIMPLE_REQUEST_MULTIPLE_FILES\\\" processVersion:1 parameters:[{name:\\\"FILE1\\\" fileValue:{ upload: $fileUpload1}},{name:\\\"FILE2\\\" fileValue:{ upload: $fileUpload2}}] }) { request { number } } }\", \"variables\": { \"fileUpload1\": null, \"fileUpload2\": null } }" \
    -F "map={ \"1\": [\"variables.fileUpload1\"],\"2\": [\"variables.fileUpload2\"]}" \
    -F "1=@C:\test1.txt" \
    -F "2=@C:\test2.txt"
Limits
  • The maximum number of uploads in the same request is 30.

  • The maximum file upload size is set in the HooksMaxInputFileSize configuration parameter.

Note: The multipart/form-data content type is only advised for HTTP requests with file uploads. If the fileValue.name, fileValue.description, fileValue.contentType, and fileValue.size properties are not defined, they will be set from the uploaded file information; otherwise, they will take the values defined the payload.

Cancel a request

You can cancel a request by using the request number or the request ID.

Request payloads
{
  "operation": "cancelRequest",
  "args": {
    "input": {
      "number": 1728
    }
  }
}
{
  "operation": "cancelRequest",
  "args": {
    "input": {
      "id": "UmVxdWVzdDoxNzI4"
    }
  }
}
Response payload
{
  "clientMutationId": null,
  "requestId": "UmVxdWVzdDoxNzI4",
  "number": 1728,
  "onBehalfOf": null,
  "onBehalfOfUserName": null
}

Complete an action

To complete an action, provide the request number and the action number, or the action ID.

Request payloads
{
  "operation": "completeAction",
  "args": {
    "input": {
      "requestNumber": 1765,
      "number": 1,
      "parameters": [
        {
          "name": "NEW_PARAMETER",
          "textValue": "My parameter"
        }
      ]
    }
  }
}
{
  "operation": "completeAction",
  "args": {
    "input": {
      "id": "QWN0aW9uOjE3NTktLS0x"
    }
  }
}
Response payload
{
  "clientMutationId": null,
  "actionId": "QWN0aW9uOjE3NTktLS0x",
  "number": 1,
  "requestNumber": 1759,
  "onBehalfOf": null,
  "onBehalfOfUserName": null
}

To complete an action, a parameter array can be included in the request payload arguments.

Request payload
{
  "operation": "completeAction",
  "args": {
    "input": {
      "requestNumber": 1765,
      "number": 1,
      "parameters": [
        {
          "name": "NEW_PARAMETER",
          "direction": "IN",
          "type": "TEXT",
          "textValue": "My parameter"
        }
      ]
    }
  }
}
Response payload
{
  "clientMutationId": null,
  "actionId": "QWN0aW9uOjE3NjUtLS0x",
  "number": 1,
  "requestNumber": 1765,
  "onBehalfOf": null,
  "onBehalfOfUserName": null
}

Cancel an action

To cancel an action, provide the request number and the action number, or the action ID.

Request payloads
{
  "operation": "cancelAction",
  "args": {
    "input": {
      "requestNumber": 1759,
      "number": 2
    }
  }
}
{
  "operation": "cancelAction",
  "args": {
    "input": {
      "id": "QWN0aW9uOjEwMDAtLS0x"
    }
  }
}
Response payload
{
  "clientMutationId": null,
  "actionId": "QWN0aW9uOjE3NTktLS0y",
  "number": 2,
  "requestNumber": 1759,
  "onBehalfOf": null,
  "onBehalfOfUserName": null
}

Assign an action

To assign an action, provide the request number and the action number, or the action ID; you must also provide the assigneeUserName or the assigneeId.

Request payloads
{
  "operation": "assignAction",
  "args": {
    "input": {
      "requestNumber": 1751,
      "number": 2,
      "assigneeUserName": "johnsmith"
    }
  }
}
{
  "operation": "assignAction",
  "args": {
    "input": {
      "id": "QWN0aW9uOjEwMDAtLS0x",
      "assigneeId": "QXNzaWduZWU6MQ=="
    }
  }
}
Response payload
{
  "clientMutationId": null,
  "actionId": "QWN0aW9uOjE3NTEtLS0y",
  "number": 2,
  "requestNumber": 1751,
  "onBehalfOf": null,
  "onBehalfOfUserName": null
}

Cancel an action assignment

To cancel an action assignment, you should provide the request number and the action number, or the action ID.

{
  "operation": "cancelActionAssignment",
  "args": {
    "input": {
      "requestNumber": 1751,
      "number": 2
    }
  }
}
{
  "operation": "cancelActionAssignment",
  "args": {
    "input": {
      "id": "QWN0aW9uOjEwMDAtLS0x"
    }
  }
}

Update request dataset

A request dataset context can be updated by adding a parameter array. In this case a request number or a request ID should be provided.

Request payloads
{
  "operation": "updateRequestDataset",
  "args": {
    "input": {
      "number": 1750,
      "parameters": [
        {
          "name": "NEW_PARAMETER",
          "textValue": "My parameter"
        }
      ]
    }
  }
}
{
  "operation": "updateRequestDataset",
  "args": {
    "input": {
      "id": "UmVxdWVzdDoxMDAw",
      "parameters": [
        {
          "name": "NEW_PARAMETER",
          "textValue": "My parameter"
        }
      ]
    }
  }
}
Response payload
{
  "clientMutationId": null,
  "requestId": "UmVxdWVzdDoxNzIx",
  "parameters": [
    {
      "name": "NEW_PARAMETER",
      "textValue": "My parameter"
    }
  ]
}

For more information on FILE parameter manipulations when sent within incoming webhook payloads, see the Working with FILE parameters section.

Create a favorite

The incoming webhook application lets users add processes and views to their favorites lists using the process or view IDs.

Request payload
{
  "operation": "createFavorite",
  "args": {
    "input": {
      "itemId": "UHJvY2VzczoxMTA="
    }
  }
}

The above code will create a favorite using the process or view description, but adding a custom description is also possible, as shown in the following example:

Request payload
{
  "operation": "createFavorite",
  "args": {
    "input": {
      "itemId": "UHJvY2VzczoxMTA=",
      "description": "My custom description"
    }
  }
}
Response payload
{
  "clientMutationId": null,
  "favorite": {
    "id": "RmF2b3JpdGU6MjA=",
    "ownerId": "VXNlcjox",
    "description": "My custom description",
    "type": "PROCESS",
    "itemId": "UHJvY2VzczoxMTA=",
    "onBehalfOf": null
  }
}

Update a favorite

The incoming webhook application lets users update an existing favorite process or view by using its favorite ID.

Request payload
{
  "operation": "updateFavorite",
  "args": {
    "input": {
      "id": "UHJvY2VzczoxMTA=",
      "description": "Updated description"
    }
  }
}
Response payload
{
  "clientMutationId": null,
  "favorite": {
    "id": "RmF2b3JpdGU6MTQ=",
    "ownerId": "VXNlcjox",
    "description": "Updated description",
    "type": "PROCESS",
    "itemId": "UHJvY2VzczoxMTA=",
    "onBehalfOf": null
  }
}

Delete a favorite

The incoming webhook application lets users delete an existing favorite process or view from their favorites list by using its favorites ID.

Request payload
{
  "operation": "deleteFavorite",
  "args": {
    "input": {
      "id": "RmF2b3JpdGU6MTQ="
    }
  }
}
Response payload
{
  "clientMutationId": null
}

Add a comment

The incoming webhook application lets users add comments to requests.

Request payload
{
  "operation": "addComment",
  "args": {
    "input": {
      "subjectId": "UmVxdWVzdDo0MzY1",
      "message": "This is my comment"
    }
  }
}
Response payload
{
  "clientMutationId": null,
  "comment": {
    "id": "Q29tbWVudDo0MzY1LS0tMg==",
    "message": "This is my comment",
    "postedAt": "2017-06-02T17:14:45.025Z",
    "authorId": "VXNlcjox",
    "subjectId": "UmVxdWVzdDo0MzY1",
    "onBehalfOf": null
  }
}

Remove a comment

The incoming webhook application lets users remove comments from requests.

Request payload
{
  "operation": "removeComment",
  "args": {
    "input": {
      "id": "Q29tbWVudDo0MzY1LS0tMg=="
    }
  }
}
Response payload
{
  "clientMutationId": null
}

Cancel a request's actions by name

All of the actions with the same name in a request can be cancelled at the same time by using their name in this operation payload.

Request payload
{
  "operation": "cancelRequestActionsByName",
  "args": {
    "input": {
      "requestNumber": 4399,
      "activityName": "Initiates"
    }
  }
}
Response payload
{
  "clientMutationId": null,
  "actionIds": [
    "QWN0aW9uOjQzOTktLS0x",
    "QWN0aW9uOjQzOTktLS0y",
    "QWN0aW9uOjQzOTktLS0z"
  ],
  "onBehalfOf": null,
  "onBehalfOfUserName": null
}

Delegation mode

Some of these operations can be done in delegation mode, by adding the onBehalfOfUserName (delegator username) or the onBehalfOf (delegator ID) arguments to the request JSON payload, such as in the following example:

Request payloads
{
  "operation": "createRequest",
  "args": {
    "input": {
      "processName": "2_LEVELS_APPROVAL",
      "processVersion": 1,
      "onBehalfOfUserName": "wfgen_admin"
    }
  }
}
{
  "operation": "createRequest",
  "args": {
    "input": {
      "processName": "2_LEVELS_APPROVAL",
      "processVersion": 1,
      "onBehalfOf": "VXNlcjox"
    }
  }
}

In this case, the response payload will also contain the onBehalfOf and onBehalfOfUserName arguments.

{
  "clientMutationId": null,
  "requestId": "UmVxdWVzdDoxNzI5",
  "number": 1729,
  "onBehalfOf": "VXNlcjox",
  "onBehalfOfUserName": "wfgen_admin"
}

In the case of CancelActionAssignment and UpdateRequestDataset operations, the delegation mode is not supported.

clientMutationId

The clientMutationId is an optional argument that can be used by the requester to identify the execution of an operation. Its value is defined in the input payload (e.g. a UUID). If defined, the same value is returned by the operation.

Request payload
{
  "operation": "createRequest",
  "args": {
    "input": {
      "processName": "2_LEVELS_APPROVAL",
      "processVersion": 1,
      "clientMutationId": "e9468d12-ca3e-4164-ba6c-2bb0843117d0"
    }
  }
}
Response payload
{
  "clientMutationId": "e9468d12-ca3e-4164-ba6c-2bb0843117d0",
  "requestId": "UmVxdWVzdDoxNzY4",
  "number": 1768,
  "onBehalfOf": null,
  "onBehalfOfUserName": null
}

Known limitations

For file type data parameters, the URL must start with file://, and the path has to be available to the WorkflowGen server.

Performance optimization

The value of the nodeProcessCountPerApplication setting is set to 0 by default for the best performance in Node.js applications. This creates one node process based on the number of virtual processors that are configured. You can change this value at any time to a custom number of node processes; for example, nodeProcessCountPerApplication=2 will create two node processes independently of the number of virtual processors.

For more information, see https://docs.microsoft.com/en-us/azure/app-service/app-service-web-nodejs-best-practices-and-troubleshoot-guide#nodeprocesscountperapplication.

results matching ""

    No results matching ""