# Script Tasks API

\
The platform provides the ability to create handler script task logic from Eximee Designer. The process designer only needs to write the handler logic and attach it in the process.

## Creating a script task <a href="#zadanieskryptowe-tworzeniezadaniaskryptowego" id="zadanieskryptowe-tworzeniezadaniaskryptowego"></a>

We can create and edit script tasks using the Eximee Designer application. To do this, in the module **Library** select the tab **Script tasks**:

<figure><img src="/files/beeab7485458078c98b5cd261b53e95f5465dcfc" alt=""><figcaption><p><em><strong>Figure 1.</strong> Script tasks tab window</em></p></figcaption></figure>

A detailed description of script creation is available in: [Script tasks](/documentation/documentation-en/budowanie-aplikacji/logika-biznesowa/scriptcode/zadanie-skryptowe-scripttask.md).

### Handler API <a href="#zadanieskryptowe-apihandlerow" id="zadanieskryptowe-apihandlerow"></a>

```typescript
interface Task {
   getVariable(name): string;                                 // Retrieving a process variable with the identifier specified in the parameter
   getAllVariables(): {[key: string]: string};                // Retrieving all variables in the process
   getProcessIntanceId(): string;                             // Returns the process instance identifier
}
 
interface Context {
   complete(variables: [key: string]: string, modelChanges?: [key: string]: string): void; // Finish the task and pass the variables specified in the parameter, and optionally changes in the data model, to the process
   handleFailure(cause: string): void;                        // Report an incident on the task (e.g. system error) together with the reason specified in the parameter (the process stops until intervention)    
   handleBpmnError(errorCode: string, cause?: string): void;  // Report an expected business error on the task together with the error code and the reason specified in the parameter (the BPMN error handling path is executed)
    
   // Deprecated
   getModel(String processInstanceId, List<String> fieldsNames): Map<String, String> // Call the data model by providing the process instance id and a list of keys whose values we want to retrieve.
                                                                                     // Deprecated method. Use api.model
}
 
interface Logger {
    info(message: string, ...args: any);                      // Logging at INFO level                
    debug(message: string, ...args: any);                     // Logging at DEBUG level
    warn(message: string, ...args: any);                      // Logging at WARN level
    error(message: string, ...args: any);                     // Logging at ERROR level
    trace(message: string, ...args: any);                     // Logging at TRACE level
}
 
function nonsensitive(arg: any): String;
 
function handle(task: Task, context: Context): void {}


```

{% hint style="info" %}
Set the list of groups that will have access to the process instance on the case list

[Process data operations and access](/documentation/documentation-en/budowanie-aplikacji/logika-biznesowa/scriptcode/skrypty-scriptservice/api-skryptow/operacje-i-dostep-do-danych-procesu.md)
{% endhint %}

### Sample script tasks <a href="#zadanieskryptowe-przykladowezadaniaskryptowe" id="zadanieskryptowe-przykladowezadaniaskryptowe"></a>

The script retrieves the variable with the identifier "testVariable", multiplies it by itself, and assigns the result to a new variable "result":

```javascript
function handle(task, context) {
    Logger.info("Starting script task sensitiveName={}, nonSensitiveName={}", 'SECRET_DATA', nonsensitive('NON_SECRET_DATA'))
 
    const testVariableNumber = task.getVariable('testVariable');
    const testVariablePower = testVariableNumber * testVariableNumber;
     
    Logger.info("Ending script task")
    context.complete({'result': testVariablePower});
 }
```

### Calling Rest services in a script task <a href="#zadanieskryptowe-wywolanieuslugrestwzadaniuskryptowym" id="zadanieskryptowe-wywolanieuslugrestwzadaniuskryptowym"></a>

Invocation documentation: [\[Rest\] Calling external REST services (ScriptCode)](/documentation/documentation-en/budowanie-aplikacji/logika-biznesowa/scriptcode/restapi-integracje-z-zewnetrznymi-systemami.md)

{% hint style="danger" %}
The only change compared to the above documentation is the configuration file.

For ScriptCode Handler, it is called **script-handler-api.xml** and is located in the directory **`/etc/eximee/webforms/script-handler-config`**
{% endhint %}

Example of a script task with a call to an external REST service:

```typescript
function handle(task, context) {
    // Retrieve the process variable with key "testVariable"
    const value = task.getVariable('testVariable');
     
    // Retrieve the process variable with key "result"
    const result = task.getVariable('result');
 
    if (value == null || isNaN(value)) {
        // Report an error on the task with error code "errorCode"
         context.handleBpmnError("errorCode", "No value for process variable with key testVariable");
    }
 
    value = value * 5
    result = result * 5
    Logger.info("Passed: [value={}, result={}]", value, result);
          
    try {
        let response = api.rest.v1.get("questionnaire", {}, {});
 
        Logger.info("Task ended successfully");
        context.complete({'variable1': value, 'variable2': result, 'Questionnaires': response.body});
    }
    catch(e) {
        Logger.warn("Exception occured: {}", e.message);
        context.handleFailure("Failed to retrieve questionnaire list " + e.message);
    }      
}
```

### Retrieving business application configuration <a href="#zadanieskryptowe-pobieraniekonfiguracjiaplikacjibiznesowej" id="zadanieskryptowe-pobieraniekonfiguracjiaplikacjibiznesowej"></a>

Invocation documentation: [Scripts (scriptService)#Retrievingapplicationconfiguration](/documentation/documentation-en/budowanie-aplikacji/logika-biznesowa/scriptcode/skrypty-scriptservice/api-skryptow.md#skrypty-scriptservice-pobieraniekonfiguracjiaplikacji)

Example of a script task with configuration retrieval:

```javascript
function handle(task, context) {
    // Retrieve variables from the configuration
    const skipTask = api.config.v1.get("script.task.skip.task")
    const titleName = api.config.v1.getOrDefault("script.task.title.name", "Default title")
     
    // Finish the task and pass the variables (skipTask, titleName) to the process
    context.complete({'skipTask': skipTask, 'titleName': titleName});
}
```

### Calling Eximee Status in ScriptCode Handler <a href="#zadanieskryptowe-wywolanieeximeestatuswscriptcodehandlerze" id="zadanieskryptowe-wywolanieeximeestatuswscriptcodehandlerze"></a>

{% hint style="danger" %}
For the call to work properly, the EXIMEE\_STATUS\_URL parameter pointing to the eximee-status API must be set.

The methods calling eximee-status require the process variable **statusId**, which should contain the request number for which the specified update is to occur.
{% endhint %}

#### Status API <a href="#zadanieskryptowe-statusapi" id="zadanieskryptowe-statusapi"></a>

```typescript
interface EximeeStatusClient {
   updateStatus(statusName: string, statusDescription: string): void;   // Update the status name and description
   updateMetadata(metadata: string): void;                               // Update request metadata
   getMetadata(): Object;                                               // Retrieve request metadata
   getClientFormsBasicInfo(): Object;                                   // Retrieve the list of request statuses for the logged-in client (Method available from version 4.154.0. The client must be logged in for the functionality to work.)
 }
```

Example ScriptCodeHandler with eximee-status call:

```javascript
function handle(task, context) {
    try {
        api.status.v1.updateStatus("NEW_STATUS", "STATUS_DESC");
 
        Logger.info("Task ended successfully");
        context.complete({});
    }
    catch(e) {
        Logger.warn("Exception occured: {}", e.message);
        context.handleFailure("Failed to retrieve questionnaire list " + e.message);
    }      
}
```

### Retrieving Content contents <a href="#zadanieskryptowe-pobieraniezawartoscitresci" id="zadanieskryptowe-pobieraniezawartoscitresci"></a>

{% hint style="info" %}
Functionality available from platform version: **3.332.0**
{% endhint %}

From a script task, you can retrieve the contents of the artifact **Content** (textContent) created in **Eximee Designer**, using the function: `api.repository.v1.textContent`. This function returns an object that contains the content for each defined translation. To retrieve the content for a given translation, we use the function `language`. Example usage:

```javascript
const artifactName = "footer";
const artifactVersion = "*";
const language = "pl";
  
const contentArtifact = api.repository.v1.textContent(artifactName, artifactVersion);
const footerPl = contentArtifact.language(language).text();
```

{% hint style="danger" %}

1. The function **`textContent`** throws an exception if it does not find an artifact with the specified parameters.
2. The function **`language`** throws an exception if it does not find a translation in the specified language.
   {% endhint %}

If we are not sure that the parameters we provided are correct, we can handle exceptions using **try catch**:

```javascript
const artifactName = "footer";
const artifactVersion = "*";
const language = "pl";
  
let contentArtifact;
try {
    contentArtifact = api.repository.v1.textContent(artifactName, artifactVersion);
} catch (error) {
    context.handleFailure("No artifact found with name: " + artifactName + " and version: " + artifactVersion);
    return;
}
  
let footerPl;  
try {
    footerPl = contentArtifact.language(language).text(); 
} catch (error) {
    context.handleFailure("No translation for language found in the artifact: " + language);
    return;
}
 
context.complete({'output': footerPl});
```

### Data model

More information in [Data model API](/documentation/documentation-en/budowanie-aplikacji/model-danych/wykorzystanie-modelu-danych/api-modelu-danych.md)

### Saving data in the data model

In script tasks, we can save data to the model using the 'complete' method; the first parameter saves data to the process, and the second parameter saves data to the model:

{% hint style="warning" %}
The model key must exist in the data model for it to be saved correctly
{% endhint %}

```js
function handle(task, context) {
    const branchId = task.getVariable('branchId');
    const isDocumentChangedRequired = task.getVariable('isDocumentChangedRequired');
    const documentsNotes = task.getVariable('documentsNotes');
 
    let modelUpdate = { "Ugoda.Adres.Oddzial": branchId, "Ugoda.CzyWymaganaZmianaTresciUmowy": isDocumentChangedRequired }
 
    if (isDocumentChangedRequired == "true") {
        modelUpdate['Ugoda.Uwagi'] = documentsNotes
    }
    context.complete({}, modelUpdate);
}
```


---

# 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://docs.eximee.com/documentation/documentation-en/budowanie-aplikacji/logika-biznesowa/scriptcode/zadanie-skryptowe-scripttask/api-zadan-skryptowych.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.
