> 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).

# Scripts API

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

Below is example code that shows how to use input and how to return data.

```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}];
}
```

## Service script input <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 from the input data map or returns "null",
* String **getFirstParameter**(final String name, final String defaultIfEmpty); - retrieves the first element from a specific list from 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 it stores,
* String **isVisible**(final String id); - retrieves information on whether the component with the specified id is visible,
* String **getValue**(final String id); - retrieves the value of the component (also a session variable) with the specified id,
* void **setValue**(final String componentId, final String value); - sets the value **value** of the component with the specified **componentId**. The rule for providing componentId is the same as for 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, componentId should be prefixed with the character **@**

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

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

> **NOTE!** The attributes available for retrieval 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 the script execution in two ways:

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

\
Script output with a sample 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 follow 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('Wartosc zmiennej sesyjnej [arg1={}, arg2={}]', nonsensitive('arg1 nonsensitive test'), sessionVariable);
    return [{'sessionVar':sessionVariable }];
}
```

## Throwing business exceptions

Business errors have been 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>

It is possible to save certain data between service calls. This is what the object `registry`.

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

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

Data is stored in namespaces (namespace in the methods) defined by administrators. Each namespace can be assigned a data lifetime. 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 the data is saved.

{% hint style="info" %}
The object requires a running EximeeRegistry application to work correctly.
{% endhint %}

{% hint style="danger" %}
**Saving data using EximeeRegistry is not intended for saving 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); // matching version, save will succeed
context.registry().saveVersion('test','123123', 'new data', 'some other version'); // mismatched version, save will fail
context.registry().delete('test','123123');

```

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

{% hint style="warning" %}
Feature available since platform version: 3.190.0

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

{% hint style="info" %}
The application configuration retrieval feature 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 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 the endpoint it provides */xlsx/v1* - the module is currently provided separately; appropriate access configuration to the service in ScriptApi must be performed. Pass the following request to the module:

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

where in content we pass the file in base64 form. 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 content <a href="#skrypty-scriptservice-pobieraniezawartoscitresci" id="skrypty-scriptservice-pobieraniezawartoscitresci"></a>

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

From the script level, it is possible to 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 = "footer";
const wersjaArtefaktu = "*";
const jezyk = "pl";
 
const artefaktTresci = api.repository.v1.textContent(nazwaArtefaktu, wersjaArtefakut);
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 = "footer";
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 found in the artifact for language: " + jezyk}];
}
 
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)

## Process data operations and access

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 Value selection field from a list (Combobox) <a href="#skrypty-scriptservice-przykladowyskryptzasilajacykomponentpolewyboruwartoscizlisty-combobox-example" id="skrypty-scriptservice-przykladowyskryptzasilajacykomponentpolewyboruwartoscizlisty-combobox-example"></a>

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

Outputs **id**, **label**, and **description** should be connected to the appropriate 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': 'Default translation value 1', 'description': 'Description 1', },
            { 'id': 2, 'label': 'Default translation value 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 a component with the specified id. For the component **Attachments** the names of added files are determined using the attribute **fileNames** and come from the request as a JSON-formatted string (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!** Method **getData()** uses the component id, so the script is not universal - for each request the appropriate component id must be provided **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 Value selection field from a list (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 a component with the specified id. For the component **Dropdown for selecting a value from a list** 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.
