[comment]: # ({96feb912-d3accdff})
# 1 Additional JavaScript objects

[comment]: # ({/96feb912-d3accdff})

[comment]: # ({3ede003a-ab8bd378})
### Overview

This section describes Zabbix additions to the JavaScript language implemented with Duktape, and supported [global JavaScript functions](#global-javascript-functions).

:::noteimportant
Do not use undeclared assignments in preprocessing JavaScript.
Use `var` to declare local variables.
:::

[comment]: # ({/3ede003a-ab8bd378})

[comment]: # ({c73f2449-c73f2449})
### Built-in objects

[comment]: # ({/c73f2449-c73f2449})

[comment]: # ({1dd6fb19-e5dc8dd0})
#### Zabbix

The Zabbix object provides interaction with the internal Zabbix functionality.

|Method|Description|
|--|--------|
|`log(loglevel, message)`|Writes <message> into Zabbix log using <loglevel> log level (see configuration file DebugLevel parameter).|

Example:

```default
Zabbix.log(3, "this is a log entry written with 'Warning' log level")
```

You may use the following aliases:

|Alias|Alias to|
|-----|--------|
|console.log(object)|Zabbix.log(4, JSON.stringify(object))|
|console.warn(object)|Zabbix.log(3, JSON.stringify(object))|
|console.error(object)|Zabbix.log(2, JSON.stringify(object))|

::: noteimportant
The total size of all logged messages is limited to 8 MB per script execution.
:::

|Method|Description|
|--|--------|
|`sleep(delay)`|Delay JavaScript execution by `delay` milliseconds.|

Example (delay execution by 15 seconds):

```default
Zabbix.sleep(15000)
```

[comment]: # ({/1dd6fb19-e5dc8dd0})

[comment]: # ({e31a78fd-413974f8})
#### HttpRequest

This object encapsulates cURL handle allowing to make simple HTTP requests.
Errors are thrown as exceptions.

::: noteimportant
The initialization of multiple `HttpRequest` objects is limited to 10 per script execution.
:::

|Method|Description|
|--|--------|
|`addHeader(value)`|Adds HTTP header field. This field is used for all following requests until cleared with the `clearHeader()` method.<br>The total length of header fields that can be added to a single `HttpRequest` object is limited to 128 Kbytes (special characters and header names included).|
|`clearHeader()`|Clears HTTP header. If no header fields are set, `HttpRequest` will set Content-Type to application/json if the data being posted is JSON-formatted; text/plain otherwise.|
|`connect(url)`|Sends HTTP CONNECT request to the URL and returns the response.|
|`customRequest(method, url, data)`|Allows to specify any HTTP method in the first parameter. Sends the method request to the URL with optional *data* payload and returns the response.|
|`delete(url, data)`|Sends HTTP DELETE request to the URL with optional *data* payload and returns the response.|
|`getHeaders(<asArray>)`|Returns the object of received HTTP header fields.<br>The `asArray` parameter may be set to "true" (e.g., `getHeaders(true)`), "false" or be undefined. If set to "true", the received HTTP header field values will be returned as arrays; this should be used to retrieve the field values of multiple same-name headers.<br>If not set or set to "false", the received HTTP header field values will be returned as strings.|
|`get(url, data)`|Sends HTTP GET request to the URL with optional *data* payload and returns the response.|
|`head(url)`|Sends HTTP HEAD request to the URL and returns the response.|
|`options(url)`|Sends HTTP OPTIONS request to the URL and returns the response.|
|`patch(url, data)`|Sends HTTP PATCH request to the URL with optional *data* payload and returns the response.|
|`put(url, data)`|Sends HTTP PUT request to the URL with optional *data* payload and returns the response.|
|`post(url, data)`|Sends HTTP POST request to the URL with optional *data* payload and returns the response.|
|`getStatus()`|Returns the status code of the last HTTP request.|
|`setProxy(proxy)`|Sets HTTP proxy to "proxy" value. If this parameter is empty, then no proxy is used.|
|`setHttpAuth(bitmask, username, password)`|Sets enabled HTTP authentication methods (HTTPAUTH\_BASIC, HTTPAUTH\_DIGEST, HTTPAUTH\_NEGOTIATE, HTTPAUTH\_NTLM, HTTPAUTH\_NONE) in the 'bitmask' parameter.<br>The HTTPAUTH\_NONE flag allows to disable HTTP authentication.<br>Examples:<br>``request.setHttpAuth(HTTPAUTH_NTLM | HTTPAUTH_BASIC, username, password)``<br>`request.setHttpAuth(HTTPAUTH_NONE)`|
|`trace(url, data)`|Sends HTTP TRACE request to the URL with optional *data* payload and returns the response.|

Example:

```javascript
try {
    Zabbix.log(4, 'jira webhook script value='+value);
  
    var result = {
        'tags': {
            'endpoint': 'jira'
        }
    },
    params = JSON.parse(value),
    req = new HttpRequest(),
    fields = {},
    resp;
  
    req.addHeader('Content-Type: application/json');
    req.addHeader('Authorization: Basic '+params.authentication);
  
    fields.summary = params.summary;
    fields.description = params.description;
    fields.project = {"key": params.project_key};
    fields.issuetype = {"id": params.issue_id};
    resp = req.post('https://jira.example.com/rest/api/2/issue/',
        JSON.stringify({"fields": fields})
    );
  
    if (req.getStatus() != 201) {
        throw 'Response code: '+req.getStatus();
    }
  
    resp = JSON.parse(resp);
    result.tags.issue_id = resp.id;
    result.tags.issue_key = resp.key;
} catch (error) {
    Zabbix.log(4, 'jira issue creation failed json : '+JSON.stringify({"fields": fields}));
    Zabbix.log(4, 'jira issue creation failed : '+error);
  
    result = {};
}
  
return JSON.stringify(result);
```

[comment]: # ({/e31a78fd-413974f8})

[comment]: # ({fdd63f84-06cac1ca})
#### XML

The XML object allows the processing of XML data in the item and low-level discovery preprocessing and webhooks.

::: noteimportant
In order to use XML object, server/proxy must be compiled with libxml2 support.
:::

|Method|Description|
|--|--------|
|`XML.query(data, expression)`|Retrieves node content using XPath. Returns null if node is not found.<br>**expression** - an XPath expression;<br>**data** - XML data as a string.|
|`XML.toJson(data)`|Converts data in XML format to JSON.|
|`XML.fromJson(object)`|Converts data in JSON format to XML.|

Example:

*Input:*

```xml
<menu>
    <food type = "breakfast">
        <name>Chocolate</name>
        <price>$5.95</price>
        <description></description>
        <calories>650</calories>
    </food>
</menu>
```

*Output:*

```json
{
    "menu": {
        "food": {
            "@type": "breakfast",
            "name": "Chocolate",
            "price": "$5.95",
            "description": null,
            "calories": "650"
        }
    }
}
```

[comment]: # ({/fdd63f84-06cac1ca})

[comment]: # ({46c5de71-a12fbdc2})
##### Serialization rules

XML to JSON conversion will be processed according to the following rules (for JSON to XML conversions reversed rules are applied):

1\. XML attributes will be converted to keys that have their names prepended with '@'.

Example:

*Input:*

```xml
<xml foo="FOO">
  <bar>
    <baz>BAZ</baz>
  </bar>
</xml>
```

*Output:*

```json
{
  "xml": {
    "@foo": "FOO",
    "bar": {
      "baz": "BAZ"
    }
  }
}
```

2\. Self-closing elements (<foo/>) will be converted as having 'null' value.

Example:

*Input:*

```xml
<xml>
  <foo/>
</xml>
```

*Output:*

```json
{
  "xml": {
    "foo": null
  }
}
```

3\. Empty attributes (with "" value) will be converted as having empty string ('') value.

Example:

*Input:*

```xml
<xml>
  <foo bar="" />
</xml>
```

*Output:*

```json
{
  "xml": {
    "foo": {
      "@bar": ""
    }
  }
}
```

4\. Multiple child nodes with the same element name will be converted to a single key that has an array of values as its value.

Example:

*Input:*

```xml
<xml>
  <foo>BAR</foo>
  <foo>BAZ</foo>
  <foo>QUX</foo>
</xml>
```

*Output:*

```json
{
  "xml": {
    "foo": ["BAR", "BAZ", "QUX"]
  }
}
```

5\. If a text element has no attributes and no children, it will be converted as a string.

Example:

*Input:*

```xml
<xml>
    <foo>BAZ</foo>
</xml>
```

*Output:*

```json
{
  "xml": {
    "foo": "BAZ"
   }
}
```

6\. If a text element has no children but has attributes, text content will be converted to an element with the key '\#text' and content as a value; attributes will be converted as described in the serialization rule 1.

Example:

*Input:*

```xml
<xml>
  <foo bar="BAR">
    BAZ
  </foo>
</xml>
```

*Output:*

```json
{
  "xml": {
    "foo": {
      "@bar": "BAR",
      "#text": "BAZ"
    }
  }
}
```

[comment]: # ({/46c5de71-a12fbdc2})

[comment]: # ({542f4966-1368a2b0})
### Global JavaScript functions

Additional global JavaScript functions have been implemented with Duktape:

-   btoa(data) - encodes the data to base64 string;
-   atob(base64\_string) - decodes base64 string as Uint8Array buffer.

```javascript
try {
    b64 = btoa("test string");
    buffer = atob(b64);

    // Note that decoding logic depends on the data format of the buffer.
    decoded = String.fromCharCode.apply(this, [].slice.call(buffer));
} 
catch (error) {
    return {'error.name' : error.name, 'error.message' : error.message};
}
```

-   md5(data) - calculates the MD5 hash of the data
-   sha256(data) - calculates the SHA256 hash of the data
-   hmac('\<hash type\>',key,data) - returns HMAC hash as hex formatted string; MD5 and SHA256 hash types are supported; key and data parameters support binary data.
Examples:
    -    `hmac('md5',key,data)`
    -    `hmac('sha256',key,data)`
-   sign(hash,key,data) - returns calculated signature (RSA signature with SHA-256) as a string, where:<br>
    **hash** - only 'sha256' is allowed, otherwise an error is thrown;<br>
    **key** - the private key.
    It should correspond to PKCS#1 or PKCS#8 standard.
    The key can be provided in different forms:<br>
    -    with spaces instead of newlines;
    -    with escaped or non-escaped `\n` instead of newlines;
    -    without any newlines as a single-line string;
    -    as a JSON-formatted string.

    The key also can be loaded from a user macro/secret macro/vault.

    **data** - the data that will be signed.
    It can be a string (binary data also supported) or buffer (Uint8Array/ArrayBuffer).<br>
    OpenSSL or GnuTLS is used to calculate the signatures.
    If Zabbix was built without any of these encryption libraries, an error will be thrown ('missing OpenSSL or GnuTLS library').

[comment]: # ({/542f4966-1368a2b0})
