# Straatos Script Service API

Straatos engine provides JavaScript activity. This document describes available calls for developers writing JavaScript activities.

### Available Variables

Constants are declared and initialised by Straatos. They cannot be changed, just queried.

{% hint style="info" %}
Constants are case sensitive.
{% endhint %}

<table><thead><tr><th width="324.90911865234375">Name</th><th>Description</th></tr></thead><tbody><tr><td>workflowId</td><td>ID of workflow this workflowInstance is in. WorkflowId changes every time workflow is (re-)published.</td></tr><tr><td>workflowName</td><td>Name of workflow</td></tr><tr><td>workflowInstanceId</td><td>Unique ID of every workflowInstance. This will not change as long as the instance is in the workflow.</td></tr><tr><td>activityId</td><td>Uniquely identifies activity within current workflow.</td></tr><tr><td>activityName</td><td>Name of Script activity</td></tr><tr><td>activityInstanceId</td><td>Increasing sequence number representing logId of activity</td></tr><tr><td>activityInstanceDate</td><td>Date that activity execution started</td></tr><tr><td>workflowInstanceDate</td><td>Date the workflowInstance arrived in the workflow</td></tr><tr><td>console</td><td>Object with method log(String). Output will appear in efektif log.</td></tr></tbody></table>

***

### Utility Methods

JavaScript activity provides “Straatos”-object containing several methods providing functionality. The following are description of these methods:

#### Generate a UUID

Generate a UUID (or GUID), please use:

```javascript
var guid = straatos.uuid();
```

***

### Sequence Number

The method nextSequenceNumber() generates sequence number that is unique for the workflow.

Identifier makes it possible to have several sequences in one process:

<table><thead><tr><th width="324.90911865234375">Name</th><th>Description</th></tr></thead><tbody><tr><td>nextSequenceNumber()</td><td>Retrieves the next sequence number for the specified identifier</td></tr><tr><td>clearSequenceNumber()</td><td>Clears the sequence (ie it will start at 1 again)</td></tr></tbody></table>

#### Sample Code

```javascript
var id = straatos.nextSequenceNumber('sequence1');

straatos.clearSequenceNumber('sequence1'); // clears the sequence
```

***

### Getting Variables from Other WorkflowInstances in the Same Flow

Straatos provides two ways to get variables from other workflowInstances in the same workflow.

<table><thead><tr><th width="324.908935546875">Name</th><th>Description</th></tr></thead><tbody><tr><td>variablesByWorkflowInstanceId('')</td><td>Gets variables of workflowInstance defined by</td></tr><tr><td>variablesByDocumentId()</td><td>Gets variables of workflowInstance defined by (every workflowInstance also has unique documentId attached)</td></tr></tbody></table>

#### Sample Code

```javascript
var DocumentId = 12345;

var frontVariables =
    JSON.parse(straatos.variabesByDocumentId(DocumentId));

function value(name) {
    var values = frontVariables.filter(function (entry) {
        return entry.variableId == name;
    });

    return values.length > 0 ? values[0].value : null;
}

var FirstName = value('FirstNameF');
var LastName = value('LastNameF');
```

***

### Getting activityIds, documentId and workflowInstanceId

The ActivityId is used in multiple API methods, such as the message() method, to identify a specific activity within a workflow.

#### Getting ActivityId by Name

The method activityIdForName(activityName) allows you to retrieve the ActivityId when you provide an ActivityName.

Key Points:

* ActivityId is a unique identifier for an activity in a workflow.
* ActivityName is the user-defined name/description of an activity.
* The activityIdForName(activityName) method helps map the activity name to its corresponding ID.

<table><thead><tr><th width="324">Name</th><th>Description</th></tr></thead><tbody><tr><td>activityIdForName()</td><td>Returns activityId for the given activityName (only works for the current workflow, ie workflow the workflowInstance is in)</td></tr><tr><td>getActivityIdsByDocumentId()</td><td>Returns <strong>list of activityIds</strong> where workflowInstance defined by DocumentId is in (there is a 1:1 relation between documentId and workflowInstanceId).</td></tr><tr><td>getWorkflowInstanceIdByDocumentId()</td><td>Get workflowInstanceId (a string) for specified documentId</td></tr><tr><td>documentIdsForFilter()</td><td>Perform search on all documents on given variables</td></tr></tbody></table>

#### Sample Code

```javascript
var emailGroupId;

var documentIds = straatos.documentIdsForFilter({
    EmailUniqueId: emailGroupId
});

var activityId = straatos.activityIdForName('Wait for last Document');

var workflowInstances = [];

for (var i = 0; i < documentIds.length; i++) {
    var documentId = documentIds[i];
    if (documentId != _documentId) {
        workflowInstances.push({
            workflowInstanceId: straatos.getWorkflowInstanceIdByDocumentId(documentId)
        });
    }
}

var workflowMessageData = {
    workflowId: workflowId,
    activityId: activityId,
    workflowInstances: workflowInstances
};

console.log('workflowMessageData input: ' + JSON.stringify(workflowMessageData));

straatos.sendWorkflowMessage(workflowMessageData).fail (function (jqXHR, error) {
    straatos.SetError('Send Workflow Message: ' + error);
});
```

***

### Getting Variable Values

It is possible to get variables from other workflowInstances in the same workflow using these methods:

<table><thead><tr><th width="329.4544677734375">Name</th><th>Description</th></tr></thead><tbody><tr><td>variablesByDocumentId()</td><td>Gets JSON string containing all variables by documentId</td></tr><tr><td>variablesByWorkflowInstanceId()</td><td>Gets JSON string containing all variables by workflowInstanceId</td></tr></tbody></table>

***

### Converting to-and-from Byte Arrays

Several convenience methods are provided to convert to and from byte arrays.

<table><thead><tr><th width="329.4544677734375">Name</th><th>Description</th></tr></thead><tbody><tr><td>getBytes(inputString)</td><td>Converts inputString to byte array, using UTF-8 encoding.</td></tr><tr><td>getString(byte[])</td><td>Converts byte array to a string, using utf-8 character set.</td></tr><tr><td>getString(&#x3C;byte[]>, )</td><td>Convert byte array to a string, using specified character set.</td></tr></tbody></table>

***

### Base64 Encoding and Decoding

<table><thead><tr><th width="328.54541015625">Name</th><th>Description</th></tr></thead><tbody><tr><td>decodeBase64()</td><td>Returns (possibly binary) byteArray of base64 encoded string.</td></tr><tr><td>encodeBase64()</td><td>Returns base64 encoded string representation of (binary-) byteArray.</td></tr></tbody></table>

#### Sample Code

```javascript
try {
    var dataAcceptingSystemUrl = "https://<someDataAcceptingSystems URL>/documentimportsrv";

    // variables need to be defined before call to multiString
    ReferenceNumber103 = straatos.getWorkflowData('some.ref.number.' + EmailUniqueId);

    var base64String;
    var documentBase = AttachmentFileName.replace('.pdf','');
    var documentInfo = straatos.adapter.getDocumentInfo();

    straatos.ajax({
        url: documentInfo.originalURL + '?w=' + straatos.webServiceKey,
        dataType: 'binary'
    }).done(function (pdf) {
        base64String = straatos.encodeBase64(pdf);

        var documentData = multiString(function() {/** 
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:doc="http://nsServer.net/documentimportsrv">
<soapenv:Header/>
<soapenv:Body>
<doc:ImportDoc>
<doc:documentImportReq>
<doc:Docs>
<doc:Doc>
<doc:Content>#base64String#</doc:Content>
<doc:FileExt>pdf</doc:FileExt>
<doc:Filename>#AttachmentFileName#</doc:Filename>
<doc:FilenameBase>#documentBase#</doc:FilenameBase>
</doc:Doc>
</doc:Docs>
<doc:IdentifierNr>#ReferenceNumber103#</doc:IdentifierNr>
<doc:Type>DOCTYPE</doc:Type>
</doc:documentImportReq>
</doc:ImportDoc>
</soapenv:Body>
</soapenv:Envelope>
        **/});

        straatos.ajax({
            url: dataAcceptingSystemUrl,
            data: documentData,
            method: 'POST',
            contentType: 'text/xml; charset=UTF-8',
            dataType: 'text/xml',
            headers: {
                SOAPAction: 'dataAcceptingSystemUrl + /IDocumentImportSrv/ImportDoc"'
            }
        }).done(function (responseString) {
            console.log('Document Import Response: ' + responseString);
            if (responseString != '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><ImportDocumentResponse xmlns="http://nsServer.net/documentimportsrv"/></s:Body></s:Envelope>') {
                straatos.SetError('Response from document import service: ' + responseString);
            }
        }).fail(function (jqXHR, error) {
            straatos.SetError('document import service: ' + error);
            console.log('Document Import Service: ' + error);
        });

    }).fail(function (jqXHR, error) {
        straatos.SetError('Get original: ' + error);
    });

} catch(err) {
    straatos.SetError('error: ' + error);
    console.log('error: ' + err);
}

// Hack that converts multi line comment to multi line string
function multiString(f) {
    var result = f.toString().replace('function() {/**', '').replace('**/}', '');
    result = result.replace(/#([^#]+)#/g, function (match, variable) {
        // console.log('replacing ' + match + ', variable: ' + variable + ', value: ' + eval(variable));
        return eval(variable);
    });
    return result;
}
```

***

### Workflow Data

Functionality is provided to store and retrieve data on workflow level. This data remains available when the workflow is re-published.

<table><thead><tr><th width="328.54541015625">Name</th><th>Description</th></tr></thead><tbody><tr><td>setWorkflowData(, )</td><td>Sets workflow data.</td></tr><tr><td>getWorkflowData()</td><td>Gets workflow data for specified key</td></tr><tr><td>removeWorkflowData()</td><td>Removes workflow data for specified key</td></tr><tr><td>clearAllWorkflowData()</td><td>Removes all workflow data for current workflow</td></tr></tbody></table>

Example:

```javascript
straatos.getWorkflowData('reference-' + EmailUniqueId);
```

***

### Messaging Other WorkflowInstances

Send other (waiting) workflowInstances a message that they can continue the workflow.

<table><thead><tr><th width="328.54541015625">Name</th><th>Description</th></tr></thead><tbody><tr><td>sendWorkflowMessage({})</td><td>Sends a message to workflowInstance. Message should contain workflowId, activityId and an array of workflowInstances to message. Optionally variables per workflowInstance. See example below.</td></tr></tbody></table>

Parameters:

* workflowId:
  * ID (a guid) of current workflow.
* activityId:
  * ID (a string) of activity. See activityForName() method to get activityId via activityName.
* workflowInstances:
  * List of one or more workflowInstances that should receive the message.

Each workflowInstance should contain workflowInstanceId and optionally list named variables of id-value pairs.

#### Sample Code

```javascript
var workflowInstanceId = '';

var messageInput = {
    workflowId: workflowId,
    activityId: activityId,
    workflowInstances: [{
        workflowInstanceId: workflowInstanceId,
        variables: [
            {'id' : 'Variable1', 'value' : 'string123'},
            {'id' : 'Var2', 'value' : 123 }
        ]
    }]
};

straatos.sendWorkflowMessage(messageInput)
.done(function () {
    console.log('Ok');
}).fail(function (jqXHR, error) {
    straatos.SetError('Message error: ' + error);
});
```

***

### Calling Web Services (Ajax Support)

Straatos provides an api to call web services. The way it can be used is similar to a jQuery Ajax call, however, it supports a subset of the functionality.

This Ajax call can also be used to call additional functionality the Straatos REST API provides. For more information, please open the link below.

<https://docs.google.com/document/d/1ui5UhztqodEmLn6rY36AQ00rUsiLKfwNNvXdzLw6CJ0/edit?ts=5829c792#bookmark=id.fccwvtqnhhu3>

<table><thead><tr><th width="326.727294921875">Name</th><th>Description</th></tr></thead><tbody><tr><td>ajax()</td><td>Performs the call. See table below for the request options</td></tr></tbody></table>

Request specification:

<table><thead><tr><th width="327.63623046875">Name</th><th>Description</th></tr></thead><tbody><tr><td>url</td><td>Required: Complete url to call. Calls to urls containing localhost are not allowed.</td></tr><tr><td>data</td><td>Data you want to pass, or the multipart object from straatos.newFormData call</td></tr><tr><td>method</td><td>Possible values are GET, POST, PUT, DELETE and OPTIONS. When not specified, it defaults to GET</td></tr><tr><td>contentType</td><td>Optional contentType of data to be sent, default is 'application/json'</td></tr><tr><td>dataType</td><td>Optional contentType of expected data for example: 'binary' or 'text/html'</td></tr><tr><td>headers</td><td>Optional array with headers that will be passed to the call</td></tr><tr><td>timeout</td><td>Optional timeout in milliseconds. The default is 60 seconds. This one parameter specifies connectTimout, requestTimeout and socketTimeout.</td></tr></tbody></table>

#### Sample Code

```javascript
try {
    straatos.ajax({
        url: externalAPIURL,
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        data: JSON.stringify({'client_id': '', 'client_secret': ''})
    }).done(function (output) {
        var response = JSON.parse(output);
        console.log('++ response: ' + JSON.stringify(response));
        token = response.access_token;
    }).fail(function (jqXHR, error) {
        straatos.setError('Access Token Error: ' + error);
        console.log('Access Token Error: ' + error);
    });
} catch(err) {
    console.log('Get Access Token Error: ' + err);
}
```

***

### Multipart Support

Multipart support is available to create multipart messages. If boundaries are needed between parts, they should be added manually by the developer.

To get a new Multipart object, call straatos.newFormData().

#### Adding Data

To add data to multipart objects, call one of these methods:

<table><thead><tr><th width="327.6363525390625">Name</th><th>Description</th></tr></thead><tbody><tr><td>append()</td><td>Adds a string, this string will be utf-8 encoded</td></tr><tr><td>append(, )</td><td>Adds a string with a custom character set. Values used can be ‘utf-8’, or any of the character sets from the table below.</td></tr><tr><td>append(&#x3C;byte []>)</td><td>Appends a byte array to multipart object</td></tr></tbody></table>

#### Getting Data

To get the data from the multipart object, call one of these methods:

<table><thead><tr><th width="327.6363525390625">Name</th><th>Description</th></tr></thead><tbody><tr><td>getByteArray()</td><td>Returns byte array (byte[]) representing multipart data</td></tr><tr><td>toString()</td><td>Returns utf-8 decoded string of multipart data</td></tr></tbody></table>

#### Sample Code

```javascript
var multipart = straatos.newFormData();

multipart.append('This is string 1');

var boundaryName = 'Straatos-' + straatos.uuid(); //The Boundary Name must be unique as part of the entire post. Hence in this case we use 'Straatos- and a unique ID' to make it unique.

var boundary = '--' + boundaryName + '\r\n';

var multipart = straatos.newFormData();

multipart.append(boundary);

multipart.append('Content-Type: ' + mimeType + '\r\n');

multipart.append('Content-Disposition: document; name="' + documentName + '"; filename="' + fileName + '"\r\n');

multipart.append('\r\n');

multipart.append(fileContents);

multipart.append('\r\n');

multipart.append(boundary);

multipart.append('Content-Type: application/json; charset=UTF-8\r\n');

multipart.append('Content-Disposition: meta\r\n');

multipart.append('\r\n');

multipart.append(JSON.stringify(metadata) + '\r\n');

multipart.append('--' + boundaryName + '--\r\n'); //The last Boundary must have the two dashes (--) at the end.

straatos.ajax({
    url: APIBaseURL + '/api/v1/delivery',
    method: 'POST',
    data: multipart,
    contentType: 'multipart/related; boundary="' + boundaryName + '"', //Note: The Boundary Name needs to be in double quotes and must be defined here.
    headers: {
        'Authorization': 'Bearer ' + tokenResult.access_token
    }
}).done(function (response) {
    console.log('Peax response: ' + response);
    PeaxUploadId = JSON.parse(response).id;
}).fail(function (jqXHR, error) {
    straatos.setError('Peax upload: ' + error);
});
```

***

### Getting History or Audit Trail Info

This API call returns JSON string containing history of the document. This will not include the currently executed step.

* straatos.history() returns json string containing history of the current workflowInstance (not including current running activity).
* straatos.history(number documentId) returns json string containing history of workflowInstance identified by documentId provided. This document must be part of the same workflow as the calling document.

Since a string is returned, JSON.parse() should be called on the string before accessing json objects within the returned data.

#### Sample Code

```javascript
// Example:
var hist_str = straatos.history();
var hist = JSON.parse(hist_str);
console.log(JSON.stringify(hist)); // prints the whole history object
console.log('WorkflowInstance started at: ' + JSON.stringify(hist.start));
console.log('Nr of log entries: ' + hist.activityInstances.length);

// Example with documentId:
var hist_str2 = straatos.history(877603);
var hist2 = JSON.parse(hist_str2);
console.log(JSON.stringify(hist2)); // prints the whole history object
console.log(JSON.stringify(hist2.start));
console.log('Second: ' + hist2.activityInstances.length);
```

***

### setSecret and getSecret

The Set Secret and Get Secret functions provided by the Script task or Interact API enable the secure storage of sensitive data such as passwords, tokens, API keys, and connection strings.

How It Works:

* setSecret:&#x20;
  * This function securely stores the data in Straatos's vault.

* getSecret:&#x20;
  * This function retrieves the stored data from the vault for use within the workflow.

Best Practices:

* It is crucial not to store secrets directly in script code. Instead, utilize the setSecret and getSecret functions to manage sensitive data securely.

#### Storing a Secret

```javascript
var result = straatos.setSecret('mySecretName', 'mySecretValue');
```

The above code stores the return value in a variable. That variable will either contain a 'true' or 'false' value, depending on if the storing of the secret was successful. This result should be checked by the code.

#### Retrieving a Secret

```javascript
var secret = straatos.getSecret('mySecretName');
```

***

### Database (SQL) Queries

The straatos.data.query lets user connect to a database and execute SQL queries. This function can be used to read data from Database (Select), but also to update, truncate, drop databases (tables).

The sample code below shows how a database is updated.

```javascript
var sqlUpdate = 'DECLARE @UNI UNIQUEIDENTIFIER ' +
'SET @UNI = NEWID() ' +
'INSERT INTO BBAuditLog (id,AuditLogRecordId,UserName, EventDate, WorkflowStep, BatchId, Area, RecordName, RecordValue) ' +
'OUTPUT @@RowCount as RowsAffected ' +
'VALUES (NewID(),@AuditLogRecordId,@UserName,@EventDate,@WorkflowStep,@BatchId,@Area,@RecordName,@RecordValue);';

var sqlParam = {
    '@AuditLogRecordId': AuditLogRecordId,
    '@UserName': LastSavedBy,
    '@EventDate': moment(LastSavedDateTime).format('YYYY-MM-DDThh:mm:ssZ'),// LastSavedDateTime,
    '@WorkflowStep': ReportType,
    '@BatchId':BatchId,
    '@Area':'Header'
};

var dbConnString = 'Server=<ServerName>,1433;Database=<DBName>;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;TrustServerCertificate=False';
var dbUser = '<Username>';
var dbPassword = '<Password>';

var query = {
    ConnectionString: dbConnString,
    User: dbUser,
    Password: dbPassword,
    SqlQuery: sqlUpdate,
    Parameters: sqlParam
};

var sqlresult = straatos.data.query(query);
```

***

### Supported Character Sets

Supported charsets (java might support more, but this is the minimum).

* US-ASCII Seven-bit ASCII, a.k.a. ISO646-US.
* ISO-8859-1 ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1.
* UTF-8 Eight-bit UCS Transformation Format.
* UTF-16BE Sixteen-bit UCS Transformation Format, big-endian byte order.
* UTF-16LE Sixteen-bit UCS Transformation Format, little-endian byte order.
* UTF-16 Sixteen-bit UCS Transformation Format, byte order identified by an optional byte-order mark.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://help.cumuluspro.net/developer-guide/straatos-api/straatos-script-service-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
