> For the complete documentation index, see [llms.txt](https://docs.eximee.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.eximee.com/documentation/documentation-en/budowanie-aplikacji/logika-biznesowa/scriptcode/skrypty-scriptservice/api-skryptow.md).

# Script API

## Retrieving input data <a href="#skrypty-scriptservice-pobieraniedanychwejsciowych" id="skrypty-scriptservice-pobieraniedanychwejsciowych"></a>

Below is an example code that shows how to use input and how data should be returned.

```javascript
function callService(context){
  const firstArgument = context.getFirstParameter("firstArgument");
  const firstArgumentList = context.getParameters("firstArgument");
  const keySet = context.getInputParameters().keySet();
  const comboboxLabel = context.getData("GesCombobox1","label");
  const result = "service script constant " + firstArgument + " list value: " + firstArgumentList + " and first from list: " + firstArgumentList.get(0) + " keySet " + keySet;
  return [{'output': result}];
}
```

## Input to the Service Script <a href="#skrypty-scriptservice-wejsciedoskryptserwisu" id="skrypty-scriptservice-wejsciedoskryptserwisu"></a>

As input (parameter *context* in the code above) there is an object that provides the following methods:

* List\<String> **getParameters**(final String name); - retrieves a specific list from the input data map,
* String **getFirstParameter**(final String name); - retrieves the first element from a specific list in the input data map or returns "null",
* String **getFirstParameter**(final String name, final String defaultIfEmpty); - retrieves the first element from a specific list in the input data map, and if it does not exist or is empty returns "defaultIfEmpty",
* Map\<String, List\<String>> **getInputParameters**(); - returns the entire input data map that it stores,
* String **isVisible**(final String id); - retrieves information whether the component with the given id is visible,
* String **getValue**(final String id); - retrieves the value of the component (also a session variable) with the given id,
* void **setValue**(final String componentId, final String value); - sets the value **value** of the component with the given **componentId**. The rule for specifying componentId is the same as with getValue.\
  When calling a script inside a composite component, in order to set the value of a component / session variable embedded in the same component, you should prefix componentId with the character **@**

> **NOTE!** An attempt to execute **setValue** on a component that listens to another component or on a component, **that** which is listened to by other components, will result in throwing an exception.

* String **getData**(final String id, final String attribute); - retrieves the value of a specific attribute for the component with the given id

> **NOTE!** The available attributes depend on the component.

* List\<Map\<String, String>> **callService**(String name, Map\<String, List\<String>> input); - allows calling ServiceProxy,
* ValidatorOutput **validate**(String name, Map\<String, List\<String>> input); - allows calling the validator

## Output from the Service Script <a href="#skrypty-scriptservice-wyjsciezeskryptserwisu" id="skrypty-scriptservice-wyjsciezeskryptserwisu"></a>

We can return the result of script execution in two ways:

1. **List of maps** - the array of objects in the output is parsed into a list of maps, then processed in the standard way.
2. **Single map** - the return value is wrapped as a single-element list, then processed in the standard way.

\
Script output with an example list:

```javascript
  return [{'output': 'result1'},{'output': 'result2'},{'output': 'result3'}];
```

## Logging <a href="#skrypty-scriptservice-logowanielogowanie" id="skrypty-scriptservice-logowanielogowanie"></a>

Logging input data is automatic

Manual logging should be consistent with the description in [Logging in ScriptCode](/documentation/documentation-en/budowanie-aplikacji/logika-biznesowa/scriptcode/logowanie-w-scriptcode.md)

```javascript
function callService(context) {
    const sessionVariable = context.getValue("@sessionVar");
    Logger.info('Session variable value [arg1={}, arg2={}]', nonsensitive('arg1 nonsensitive test'), sessionVariable);
    return [{'sessionVar':sessionVariable }];
}
```

## Throwing business exceptions

Business errors are described in detail on the page [Error pages](/documentation/documentation-en/budowanie-aplikacji/interfejs-uzytkownika/formularze/tworzenie-formularza/strony-bledow.md#bledy-biznesowe).

## Saving temporary data <a href="#skrypty-scriptservice-zapisdanychtymczasowych" id="skrypty-scriptservice-zapisdanychtymczasowych"></a>

{% hint style="warning" %}
**Outdated!** The following fragment about the Eximee Registry API requires updating.
{% endhint %}

It is possible to save certain data between service calls. The object is used for this `registry`.

Possible methods that can be called on the object `registry`:

* save(namespace, id, data) - saves data
* saveVersion(namespace, id, data, version) - saves data with version verification. If the version field is not set or is empty - saves without verification. If the value of the version field does not match the current version of the stored data, the request will end with an error.
* get(namespace, id) - retrieves data
* getVersion(namespace, id) - retrieves the object { data: 'saved data', version: 'current data version' }
* delete(namespace, id) - deletes data.

Data is stored in namespaces (namespace in the methods) defined by administrators. A data lifetime can be set for each namespace. By default, it is **90 days**. Providing the same id across multiple save calls updates the data associated with that id. The data version is a unique identifier generated each time data is saved.

{% hint style="info" %}
For correct operation, the object requires a running EximeeRegistry application.
{% endhint %}

{% hint style="danger" %}
**Saving data using EximeeRegistry is not intended for storing anything permanently!**
{% endhint %}

**Examples:**

```javascript
context.registry().save('test', '123123', 'temporary data');
context.registry().get('test', '123123'); // will return 'temporary data'
const item = context.registry().getVersion('test', '123123'); // will return object {data,version}
context.registry().saveVersion('test','123123', 'new data', item.version); // version matches, save will succeed
context.registry().saveVersion('test','123123', 'new data', 'some other version'); // version does not match, save will fail
context.registry().delete('test','123123');

```

## Retrieving application configuration <a href="#skrypty-scriptservice-pobieraniekonfiguracjiaplikacji" id="skrypty-scriptservice-pobieraniekonfiguracjiaplikacji"></a>

{% hint style="warning" %}
Functionality available from platform version: 3.190.0

The functionality works on requests run as [Business application](/documentation/documentation-en/wprowadzenie/aplikacja-biznesowa.md)
{% endhint %}

{% hint style="info" %}
The application configuration retrieval functionality is available for scripts (scriptService), script tasks (scriptTask), and script validators (validationScript).
{% endhint %}

In scripts, it is possible to retrieve the application configuration

```javascript
interface Api {
    config: {
        v1: {
          get(key: string): string;
          getOrDefault(key: string, defaultValue: string): string;
        }
    }
}
```

Example script for retrieving configuration:

```javascript

function callService(context) {
    let value1
    try {
        value1 = api.config.v1.get("application.url");
    } catch (e) {
        value1 = "default"
    }
 
    let value2 = api.config.v1.get("application.url");
 
    let value3 = api.config.v1.getOrDefault("not_existing_key", "defaultValue")
 
    return [{'value1': value1, 'value2': value2, 'value3': value3}];
}

```

## Processing xlsx files <a href="#skrypty-scriptservice-przetwarzanieplikowxlsx" id="skrypty-scriptservice-przetwarzanieplikowxlsx"></a>

{% hint style="warning" %}
Required module xlsx-sheet-handling-module
{% endhint %}

It is possible to read xlsx files attached to the request. To do this, use the xlsx-sheet-handling-module and its provided endpoint */xlsx/v1* - the module is currently provided separately; the appropriate access configuration for the service in ScriptApi must be set up. The following request should be sent to the module:

```javascript
{
    content: string
}
```

where in content we pass the file in base64 format. In this form it is passed to the service when we map uploader to the input (in the case of multiple files in uploader, it is a list). In response we will receive a map divided into: sheet → row → column

```javascript
{
    "sheet": {
        "1": {
            "A": { "test"
                }
            }
    }
}
```

Example:

```javascript
function callService(context) {
    let files = context.getParameters("uploader");
 
    if (files.size() === 0) {
        return [{}];
    }
 
    let header = {};
    let body = {'content': files.get(0)}
 
    try {
        let response = api.rest.v1.post('excelDocument', { pathParams: ['xlsx', 'v1'] }, header , body);
     
        return [{'output': JSON.stringify(response.body)}];
    } catch (error) {
        Logger.info(error );
        return [{'output': 'An error occurred'}];
    }
 
}
```

## Retrieving the content of Content <a href="#skrypty-scriptservice-pobieraniezawartoscitresci" id="skrypty-scriptservice-pobieraniezawartoscitresci"></a>

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

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

```javascript
const nazwaArtefaktu = "stopka";
const wersjaArtefaktu = "*";
const jezyk = "pl";
 
const artefaktTresci = api.repository.v1.textContent(nazwaArtefaktu, wersjaArtefaktu);
const stopkaPl = artefaktTresci.language(jezyk).text();
```

{% hint style="danger" %}

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

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

```javascript
const nazwaArtefaktu = "stopka";
const wersjaArtefaktu = "*";
const jezyk = "pl";
 
let artefaktTresci;
try {
    artefaktTresci = api.repository.v1.textContent(nazwaArtefaktu, wersjaArtefaktu);
} catch (error) {
    return [{'output': "No artifact found with name: " + nazwaArtefaktu + " and version: " + wersjaArtefaktu}]
}
 
let stopkaPl;   
try {
    stopkaPl = artefaktTresci.language(jezyk).text();  
} catch (error) {
    return [{'output': "No translation for language: " + jezyk + " was found in the artifact"}];
}
 
return [{'output': stopkaPl}];


```

## Mathematical operations in ScriptCode

More information in [Mathematical operations in ScriptCode](/documentation/documentation-en/budowanie-aplikacji/logika-biznesowa/scriptcode/skrypty-scriptservice/api-skryptow/operacje-matematyczne-w-scriptcode.md)

## Operations and access to process data

More information in [Operations and access to process data](/documentation/documentation-en/budowanie-aplikacji/logika-biznesowa/scriptcode/skrypty-scriptservice/api-skryptow/operacje-i-dostep-do-danych-procesu.md)

## Retrieving request statuses

More information in [Retrieving request statuses](/documentation/documentation-en/budowanie-aplikacji/logika-biznesowa/scriptcode/skrypty-scriptservice/api-skryptow/pobieranie-statusow-wnioskow.md)

## Data model

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

## Other examples

### Populating the List value selection component (Combobox) <a href="#skrypty-scriptservice-przykladowyskryptzasilajacykomponentpolewyboruwartoscizlisty-combobox-example" id="skrypty-scriptservice-przykladowyskryptzasilajacykomponentpolewyboruwartoscizlisty-combobox-example"></a>

The script populates **Selection field** from a list (Combobox) based on the passed 'locale' parameter.

Outputs **id**, **label**, and **description** should be bound to the corresponding combobox fields, respectively **id**, **text**, and **description**.

Combobox-populating script:

```javascript
function callService(context) {
    const locale = context.getFirstParameter('locale');
    if (locale === 'pl') {
        return [
            { 'id': 1, 'label': 'Value 1', 'description': 'Description 1', },
            { 'id': 2, 'label': 'Value 2', 'description': 'Description 2' }
        ];
    } else if (locale === 'en') {
        return [
            { 'id': 1, 'label': 'Label 1', 'description': 'Description 1', },
            { 'id': 2, 'label': 'Label 2', 'description': 'Description 2' }
        ];
    } else {
        return [
            { 'id': 1, 'label': 'Value of default translation 1', 'description': 'Description 1', },
            { 'id': 2, 'label': 'Value of default translation 2', 'description': 'Description 2' }
        ];
    }
}
```

### Retrieving file names from the Attachments component

The script uses the method **getData()**, which retrieves the value of a specific attribute for the component with the given id. For the **Attachments** the names of added files are determined using the attribute **fileNames** and come from the request as a string in JSON format (e.g. *\["name1.png", "name2.png"]*), therefore it is necessary to convert this string into an object using the method **JSON.parse**.

{% hint style="warning" %}
**NOTE!** The method **getData()** uses the component id, so the script is not universal - for each request, you must provide the appropriate component id **Attachments**:
{% endhint %}

```javascript
function callService(context) {
    const zalacznik1 = JSON.parse(context.getData("@GesUploadFile1", "fileNames"));
    const zalacznik2 = JSON.parse(context.getData("@GesUploadFile2", "fileNames"));
}
```

### Retrieving the value of the List value selection field (Combobox) from a repeatable section <a href="#skrypty-scriptservice-fragmentskryptupobierajacegowartoscipolawyboruwartoscizlisty-comboboxa-zsekcji" id="skrypty-scriptservice-fragmentskryptupobierajacegowartoscipolawyboruwartoscizlisty-comboboxa-zsekcji"></a>

The script uses the method **getData()**, which retrieves the value of a specific attribute for the component with the given id. For the **List value selection field** the values (labels) of the given keys are determined using the attribute **label.**

```javascript
for (let i=0; i<10; i++)  {
        let id = "GesRepeatableSection1.row" + i + ".GesCombobox1";
        let etykieta = context.getData(id, "label");
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.eximee.com/documentation/documentation-en/budowanie-aplikacji/logika-biznesowa/scriptcode/skrypty-scriptservice/api-skryptow.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
