# Serverside javascript helpers

## `decodeURI` <a href="#getalleventdata" id="getalleventdata"></a>

Decodes any encoded characters in the provided URI. Returns a **string** that represents the decoded URI. Returns `undefined` when provided with invalid input.

**Syntax**

```javascript
decodeUri(encoded_uri);
```

**Example**

```javascript
const decodeUri = require('decodeUri');

const decodedUrl = decodeUri(data.encodedUrl);
if (decodedUrl) {
  // ...
}
```

| Parameter         | Type     | Description                                                                                                                                         |
| ----------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`encoded_uri`** | *string* | A URI that has been encoded by [`encodeUri()`](https://developers.google.com/tag-platform/tag-manager/server-side/api#encodeuri) or by other means. |

## `decodeUriComponent` <a href="#decodeuricomponent" id="decodeuricomponent"></a>

Decodes any encoded characters in the provided URI component. Returns a **string** that represents the decoded URI component. Returns `undefined` when given invalid input.

**Syntax**

```javascript
decodeUriComponent(encoded_uri_component);
```

**Example**

```javascript
const decodeUriComponent = require('decodeUriComponent');

const decodedQuery = decodeUriComponent(data.query);
if (decodedQuery) {
  // ...
}
```

| Parameter                   | Type     | Description                                                                                                                                                                     |
| --------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`encoded_uri_component`** | *string* | A URI component that has been encoded by [`encodeUriComponent()`](https://developers.google.com/tag-platform/tag-manager/server-side/api#encodeuricomponent) or by other means. |

## `encodeUri` <a href="#getalleventdata" id="getalleventdata"></a>

Returns an encoded Uniform Resource Identifier (URI) by escaping special characters. Returns a **string** that represents the provided string encoded as a URI.

**Syntax**

```javascript
encodeUri(uri);
```

**Example**

```javascript
const encodeUri = require('encodeUri');
const sendHttpGet = require('sendHttpGet');

sendHttpGet('https://www.example.com/' + encodeUri(pathInput));
```

| Parameter | Type     | Description     |
| --------- | -------- | --------------- |
| `uri`     | *string* | A complete URI. |

## `encodeUriComponent` <a href="#encodeuricomponent" id="encodeuricomponent"></a>

Returns an encoded Uniform Resource Identifier (URI) by escaping special characters. Returns a **string** that represents the provided string encoded as a URI.

**Syntax**

```javascript
encodeUriComponent(str);
```

**Example**

```javascript
const encodeUriComponent = require('encodeUriComponent');
const sendHttpGet = require('sendHttpGet');

sendHttpGet('https://www.example.com/?' + encodeUriComponent(queryInput));
```

| Parameter | Type     | Description           |
| --------- | -------- | --------------------- |
| **`str`** | *string* | A component of a URI. |

## `fromBase64` <a href="#frombase64" id="frombase64"></a>

Decodes a base64-encoded string. Returns `undefined` if the input is invalid.

**Syntax**

```javascript
fromBase64(base64EncodedString);
```

**Example**

```javascript
const fromBase64 = require('fromBase64');

const greeting = fromBase64('aGVsbG8=');
if (greeting === 'hello') {
  // ...
}
```

| Parameter                 | Type     | Description            |
| ------------------------- | -------- | ---------------------- |
| **`base64EncodedString`** | *string* | Base64 encoded string. |

## `generateRandom` <a href="#generaterandom" id="generaterandom"></a>

Returns a random **number** (integer) within the given range.

**Syntax**

```javascript
generateRandom(min, max);
```

**Example**

```javascript
const generateRandom = require('generateRandom');

const randomValue = generateRandom(0, 10000000);
```

| Parameter | Type     | Description                                                  |
| --------- | -------- | ------------------------------------------------------------ |
| **`min`** | *number* | Minimum potential value of the returned integer (inclusive). |
| **`max`** | *number* | Maximum potential value of the returned integer (inclusive). |

## `getAllEventData` <a href="#getalleventdata" id="getalleventdata"></a>

Returns a copy of the event data.

**Syntax**

```javascript
getAllEventData();
```

**Usage Example**

```javascript
const getAllEventData= require('getAllEventData');
const eventModel = getAllEventData();
//build body request from event properties 
const body = {
    crm_id:eventModel.user.id,
    currency:eventModel.currency
};
```

{% hint style="info" %}
Notice that the event data may contains more properties that what you sent initially because of system properties that are added automatically on [web events](https://doc.commandersact.com/developers/tracking-and-integrations/tracking/about-events/js-sdk-event-specificity) and [app sdk events](https://doc.commandersact.com/developers/tracking-and-integrations/tracking/about-events/mobile-sdk-event-specificity#event-specificity-for-mobile-app).
{% endhint %}

**Data example:**

If you send this web event:

```javascript
cact('trigger', 'search', {
  "search_term": "blue t-shirt",
  "user": {
    "id": "12345",
    "email": "anakin.skywalker@domain.com",
    "consent_categories": ["1","3"]
  }
);
```

Then the getAllEventData() function will return this object:

```json
{
   "event_name": "search",
   "search_term": "blue t-shirt",
   "user": {
      "id": "12345",
      "email": "anakin.skywalker@domain.com",
      "consent_categories": ["1","3"]
   },
   "url": "https://www.mywebsite.com/path1/path2/", //Automatically added if missing
   "path": "/path1/path2/", //Automatically added
   "referrer": "https:///www.google.fr", //Automatically added
   "title": "My page title", //Automatically added if missing
   "context": {
      "event_id": "202110130000000000", //Automatically added
      "generatorVersion": "10.0", //Automatically added
      "containerVersion": "3.1", //Automatically added
      "event_timestamp": "1639044446636", //Automatically added
      "page": { //Automatically added
         "title": "Search page", //Automatically added
         "url": "https://shop.com/search?q=...", //Automatically added
         "lang": "en", //Automatically added
         "referrer": "https:///www.google.fr", //Automatically added
         "viewport": { //Automatically added
            "width": 320, //Automatically added
            "height": 568 //Automatically added
         }
      },
      "device": { //Automatically added
         "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36",//Automatically added
         "ip": "102.3.4.56",//Automatically copied from the request header
         "lang": "fr",//Automatically added
         "cookie": "_fbp=123; _fbc=456; _ga=789",//Automatically added
         "timezone": "Europe/Paris"//Automatically added
      }
   }
}
```

## `getCookieValues` <a href="#getcookievalues" id="getcookievalues"></a>

Returns an array containing the values of all cookies with the given name.

**Syntax**

```
getCookieValues(name[, noDecode]);
```

**Example**

```javascript
const getCookieValues = require('getCookieValues');
const facebook_fbp = getCookieValues('fbp')[0];
if (facebook_fbp ) {  // ...}
```

***

**Parameters**

| Parameter      | Type      | Description                                                                                  |
| -------------- | --------- | -------------------------------------------------------------------------------------------- |
| **`name`**     | *string*  | Name of the cookie.                                                                          |
| **`noDecode`** | *boolean* | If `true`, the cookie values will not be decoded before being returned. Defaults to `false`. |

## `getEventData` <a href="#geteventdata" id="geteventdata"></a>

Returns a copy of the value at the given path in the event data. Returns `undefined` if there is no event data or if there is no value at the given path.

**Syntax**

```
getEventData(keyPath);
```

**Example**

```javascript
const getEventData = require('getEventData');

const campaignId = getEventData('campaign.id');
const itemId = getEventData('items.0.id');
const referrer = getEventData('page_referrer');
```

**Parameters**

| Parameter     | Type  | Description                                                                                                                                                                                       |
| ------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`keyPath`** | *any* | The path of the key, where path components are separated by dots. The path components can be keys in an object or indices in an array. If `keyPath` is not a string, it is coerced into a string. |

## `getRemoteAddress` <a href="#getremoteaddress" id="getremoteaddress"></a>

Returns a **string** representation of the IP address where the request originated, e.g. `62.123.65.780` for IPv4 or `2001:0db8:85a3:0:0:8a2e:0370:1234` for IPv6

**Syntax**

```
getRemoteAddress();
```

## `getTimestamp` <a href="#gettimestamp" id="gettimestamp"></a>

**Deprecated.** Prefer [getTimestampMillis](https://developers.google.com/tag-platform/tag-manager/server-side/api#gettimestampmillis).

Returns a **number** that represents the current time in milliseconds since Unix epoch, as returned by `Date.now()`.

**Syntax**

```
getTimestamp();
```

## `getTimestampMillis` <a href="#gettimestampmillis" id="gettimestampmillis"></a>

Returns a **number** that represents the current time in milliseconds since Unix epoch, as returned by `Date.now()`.

**Syntax**

```
getTimestampMillis();
```

## `getType` <a href="#gettype" id="gettype"></a>

Returns a string describing the given value's type.

| Input Type  | Returned Value |
| ----------- | -------------- |
| *string*    | 'string'       |
| *number*    | 'number'       |
| *boolean*   | 'boolean'      |
| *null*      | 'null'         |
| *undefined* | 'undefined'    |
| *Array*     | 'array'        |
| *Object*    | 'object'       |
| *Function*  | 'function'     |

**Syntax**

```
getType(value);
```

**Example**

```javascript
const getType = require('getType');

const type = getType(value);
if (type === 'string') {
  // Handle string input.
} else if (type === 'number') {
  // Handle numeric input.
} else {
  logToConsole('Unsupported input type: ', type);
}
```

**Parameters**

| Parameter   | Type  | Description  |
| ----------- | ----- | ------------ |
| **`value`** | *any* | Input value. |

## `logToConsole` <a href="#logtoconsole" id="logtoconsole"></a>

Logs its argument(s) to the console.

These logs are visible within Destination Builder's console.

**Example**

```
const logToConsole = require('logToConsole');

const product_color= "red";
const product_price= 10;
logToConsole('color is: ', product_color, ' and price is: ', product_price);
```

**Syntax**

```
logToConsole(argument1[, argument2, ...]);
```

**Parameters**

The function takes one or more arguments, each of which is converted to a string, if necessary, and logged to the console.

## `makeInteger` <a href="#makeinteger" id="makeinteger"></a>

Converts the given value to a **number** (integer).

**Syntax**

```
makeInteger(value);
```

**Parameters**

| Parameter   | Type       | Description           |
| ----------- | ---------- | --------------------- |
| **`value`** | *any type* | The value to convert. |

## `makeNumber` <a href="#makenumber" id="makenumber"></a>

Converts the given value to a **number**.

**Syntax**

```
makeNumber(value);
```

**Parameters**

| Parameter   | Type       | Description           |
| ----------- | ---------- | --------------------- |
| **`value`** | *any type* | The value to convert. |

## `makeString` <a href="#makestring" id="makestring"></a>

Returns the given value as a **string**.

**Syntax**

```
makeString(value);
```

**Parameters**

| Parameter   | Type       | Description           |
| ----------- | ---------- | --------------------- |
| **`value`** | *any type* | The value to convert. |

## `parseUrl` <a href="#parseurl" id="parseurl"></a>

Returns an object that contains all of a given URL's component parts, similar to the `URL` object.

This API will return `undefined` for any malformed URL. For properly formatted URLs, fields not present in the URL string will have a value of an empty string, or in the case of `searchParams`, an empty object.

The returned object will have the following fields:

```
{  
    href: string,  
    origin: string, 
    protocol: string,  
    username: string,  
    password: string,  
    host: string,  
    hostname: string,  
    port: string,  
    pathname: string,  
    search: string,  
    searchParams: Object<string, (string|Array)>,  
    hash: string,
}
```

**Syntax**

```
parseUrl(url);
```

**Example**

```
const parseUrl = require('parseUrl');const urlObject = parseUrl('https://abc:xyz@example.com:8080/foo?param=val%2Cue#bar');
```

**Parameters**

| Parameter | Type     | Description                       |
| --------- | -------- | --------------------------------- |
| **`url`** | *string* | The full url that will be parsed. |

## `sha256` <a href="#sha256" id="sha256"></a>

Calculates the SHA-256 digest of the input and invokes a callback with the digest encoded in base64, unless the `options` object specifies a different output encoding.

This API signature and behavior matches the [`sha256`](https://developers.google.com/tag-platform/tag-manager/templates/api#sha256) API for web containers; however, Custom Templates in server containers should use the [`sha256Sync`](https://developers.google.com/tag-platform/tag-manager/server-side/api#sha256sync) API for simpler code.

**Syntax**

```
sha256(input, onSuccess, options = undefined);
```

**Example**

```
const encodeUriComponent = require('encodeUriComponent');const sendHttpGet = require('sendHttpGet');const sha256 = require('sha256');sha256('inputString', (digest) => {  sendHttpGet('https://example.com/collect?id=' + encodeUriComponent(digest));});sha256('inputString', (digest) => {  sendHttpGet('https://example.com/collect?id=' + encodeUriComponent(digest));}, {outputEncoding: 'hex'});
```

**Parameters**

| Parameter       | Type       | Description                                                                                                                                                        |
| --------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`input`**     | *string*   | The string to hash.                                                                                                                                                |
| **`onSuccess`** | *function* | Called with the resulting digest, encoded in base64, unless the `options` object specifies a different output encoding.                                            |
| **`options`**   | *object*   | *Optional* options object to specify the output encoding. If specified, the object should contain the key `outputEncoding` with value as one of `base64` or `hex`. |

## `sha256Sync` <a href="#sha256sync" id="sha256sync"></a>

Calculates and returns the SHA-256 digest of the input, encoded in base64, unless the `options` object specifies a different output encoding.

**Syntax**

```
sha256Sync(input, options = undefined);
```

**Example**

```
const encodeUriComponent = require('encodeUriComponent');const sendHttpGet = require('sendHttpGet');const sha256Sync = require('sha256Sync');const digestBase64 = sha256Sync('inputString');const digestHex = sha256Sync('inputString', {outputEncoding: 'hex'});sendHttpGet('https://example.com/collect?id=' + encodeUriComponent(digestBase64));sendHttpGet('https://example.com/collect?id=' + encodeUriComponent(digestHex));
```

**Parameters**

| Parameter     | Type     | Description                                                                                                                                                        |
| ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`input`**   | *string* | The string to hash.                                                                                                                                                |
| **`options`** | *object* | *Optional* options object to specify the output encoding. If specified, the object should contain the key `outputEncoding` with value as one of `base64` or `hex`. |

## `signHmac` <a href="#signhmac" id="signhmac"></a>

Generates an HMAC signature for the given payload, using `sha256` and `base64` encoding by default, unless the `options` object specifies otherwise. Objects passed as payload are automatically `JSON.stringify`'d. Returns a **string**.

**Syntax**

```javascript
signHmac(payload, secret, options = undefined);
```

**Example**

```javascript
const signHmac = require('signHmac');

// Sign a string with default options (sha256 + base64)
const signature = signHmac('my payload', 'mySecretKey');

// Sign with custom algorithm and encoding
const signatureHex = signHmac('my payload', 'mySecretKey', { alg: 'sha1', outputEncoding: 'hex' });

// Sign an object (automatically JSON.stringify'd)
const objectSignature = signHmac({ key: 'value' }, 'mySecretKey');
```

**Parameters**

| Parameter     | Type             | Description                                                                                          |
| ------------- | ---------------- | ---------------------------------------------------------------------------------------------------- |
| **`payload`** | *string\|object* | The data to sign. Objects are automatically converted to JSON strings.                               |
| **`secret`**  | *string*         | The secret key used for HMAC generation.                                                             |
| **`options`** | *object*         | *Optional* options object to customize the algorithm and output encoding. See options details below. |

**Options**

| Property             | Type     | Default    | Description                                                                                                                      |
| -------------------- | -------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------- |
| **`alg`**            | *string* | `'sha256'` | The hash algorithm. Supported values: `'sha256'`, `'sha1'`, `'sha512'`, `'sha384'`, `'md5'` and other OpenSSL digest algorithms. |
| **`outputEncoding`** | *string* | `'base64'` | The output encoding. Supported values: `'base64'`, `'base64url'`, `'hex'`, `'binary'` (`latin1`).                                |

## `toBase64` <a href="#tobase64" id="tobase64"></a>

Encodes a string as base64.

**Syntax**

```
toBase64(input);
```

**Example**

```
const toBase64 = require('toBase64');const base64Hello = toBase64('hello');
```

**Parameters**

| Parameter   | Type     | Description       |
| ----------- | -------- | ----------------- |
| **`input`** | *string* | String to encode. |

## `JSON` <a href="#json" id="json"></a>

Returns an object that provides JSON functions.

The `parse()` function parses a JSON string to construct the value or object described by the string. If the value cannot be parsed (malformed JSON), the function will return `undefined`. If the input value is not a string, the input will be coerced to a string.

The `stringify()` function converts the input into a JSON string. If the value cannot be parsed (ex. the object has a cycle), the method will return `undefined`.

**Syntax**

```
JSON.parse(yourString);
JSON.stringify(yourObject);
```

**Example**

```
const JSON = require('JSON');
// The JSON input string is converted to an object.
const object = JSON.parse('{"foo":"bar"}');
// The input object is converted to a JSON string.
const str = JSON.stringify({foo: 'bar'});
```

***

## `Math` <a href="#math" id="math"></a>

An object providing `Math` functions.

**Syntax**

```
const Math = require('Math');
// Retrieve the absolute value.
const absolute = Math.abs(-5);
// Round the input down to the nearest integer.
const roundedDown = Math.floor(4.6);
// Round the input up to the nearest integer.
const roundedUp = Math.ceil(2.1);
// Round the input to the nearest integer.
const rounded = Math.round(4.2);
// Return the largest argument.
const biggest = Math.max(1, 4);
// Return the smallest argument.
const smallest = Math.min(4, 5);
// Return the first argument raised to the power of the second argument.
const powerful = Math.pow(4, 2);
// Return the square root of the argument.
const unsquared = Math.sqrt(81);
```

**Parameters**

Math function parameters are converted to numbers.

## `sendHttpGet` <a href="#sendhttpget" id="sendhttpget"></a>

Makes an HTTP GET request to the specified URL, and invokes a callback with the response once the request completes or times out.

**Syntax**

```javascript
sendHttpGet(url[, callback[, options]]);
```

**Example**

```javascript
const sendHttpGet = require('sendHttpGet');
// Sends a GET request and nominates response// based on the response from the GET 
sendHttpGet('https://example.com/collect', function(statusCode, headers, body) {
    if (statusCode != 200) {yourCallbackFunction();}
}, {
    headers: {key: 'value'},
    timeout: 500
});
```

**Parameters**

| Parameter      | Type       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| -------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`url`**      | *string*   | The request URL.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| **`callback`** | *function* | <p>An optional callback to invoke upon request completion, error, or timeout.<br><br>It is invoked with the <strong>response status code</strong>, the <strong>response headers</strong>, and the <strong>response body</strong> (or undefined if there was no response body).<br>If the request failed (e.g. invalid URL, no route to host, SSL negotiation failure, etc.), the callback will be invoked with a <strong>response status code of zero</strong>, <strong>no headers</strong>, and an <strong>undefined body</strong>.<br>If the <code>'timeout'</code> option was set and the request timed out, the callback will be invoked with a <strong>response status code of -1</strong>, <strong>no headers</strong>, and an <strong>undefined body</strong>.</p> |
| **`options`**  | *object*   | Optional request options. The supported options are **headers**, **timeout**. Advanced options can be added in **extraOptions**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |

#### **Options**

* **headers**: Additional request headers represented as an object.
* **timeout**: The timeout, in milliseconds, before the request is aborted.
* **extraOptions**: Advanced options (ex: {strictSSL:true})

## `sendHttpRequest` <a href="#sendhttprequest" id="sendhttprequest"></a>

Makes an HTTP request to the specified URL, and invokes a callback with the response once the request completes or times out.

**Syntax**

```
sendHttpRequest(url[, callback[, options[, body]]]);
```

**Example**

```javascript
const sendHttpRequest = require('sendHttpRequest');
const body = {
    user_type:'vip',
    account:'123'
};
// Sends a POST request 
sendHttpRequest('https://example.com/collect', function(statusCode, headers, body) {
    //your callback code...
}, {
    headers: {
        token: '123456789'
    },
    method: 'POST',
    timeout: 1000
},  JSON.stringify(body));
```

**Parameters**

| Parameter      | Type       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| -------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`url`**      | *string*   | The request URL.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| **`callback`** | *function* | <p>An optional callback to invoke upon request completion, error, or timeout.<br><br>It is invoked with the <strong>response status code</strong>, the <strong>response headers</strong>, and the <strong>response body</strong> (or undefined if there was no response body).<br>If the request failed (e.g. invalid URL, no route to host, SSL negotiation failure, etc.), the callback will be invoked with a <strong>response status code of zero</strong>, <strong>no headers</strong>, and an <strong>undefined body</strong>.<br>If the 'timeout' option was set and the request timed out, the callback will be invoked with a <strong>response status code of -1</strong>, <strong>no headers</strong>, and an <strong>undefined body</strong>.</p> |
| **`options`**  | *object*   | Optional request options. The supported options are: **headers**, **method**, and **timeout**. Unknown option keys are ignored. Advanced options can be added in **extraOptions.**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| **`body`**     | *string*   | Optional request body.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |

**Options**

* **headers**: Additional request headers.
* **method**: The request method, defaults to 'GET'.
* **timeout**: The timeout, in milliseconds, before the request is aborted.
* **extraOptions**: Advanced options (ex: {strictSSL:true})

## `md5Sync`

Calculates and returns the `md5` digest of the input.

**Syntax**

```
md5Sync(input);
```

**Example**

```javascript
const md5Sync= require('md5Sync');
const email = {};
email.md5 = md5Sync(user.user_email);
sendHttpGet('https://example.com/collect?e5=' + email.md5);
```

## `templateDataStorage` <a href="#templatedatastorage" id="templatedatastorage"></a>

The `templateDataStorage` helper allows temporary storage and retrieval of data, such as API tokens, during script execution. It is particularly useful for caching reusable data to reduce redundant API calls. Data stored in `templateDataStorage` persists on the server running the template. Since templates execute on multiple servers, and each server may have multiple instances, stored data is not guaranteed to be accessible for all subsequent template execution.

**Syntax**

```javascript
templateDataStorage.setItemCopy(key, value);
templateDataStorage.getItemCopy(key);
templateDataStorage.removeItemCopy(key);
```

**Example: Managing API Tokens**

```javascript
const sendHttpRequest = require('sendHttpRequest');
const templateDataStorage = require('templateDataStorage');

const tokenKey = 'apiToken';

function fetchNewToken(callback) {
  sendHttpRequest('https://example.com/api/token', function (status, _, body) {
    if (status === 200) {
      const { accessToken, expiresIn } = JSON.parse(body);
      const tokenData = { token: accessToken, expiry: Date.now() + expiresIn * 1000 };
      templateDataStorage.setItemCopy(tokenKey, tokenData);
      callback(accessToken);
    } else {
      callback(null);
    }
  }, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ clientId: 'id', clientSecret: 'secret' }) });
}

function sendEvent(eventData) {
  const cachedToken = templateDataStorage.getItemCopy(tokenKey);
  const token = cachedToken && cachedToken.expiry > Date.now() ? cachedToken.token : null;

  sendHttpRequest('https://example.com/api/events', function (status) {
    if (status === 401) {
      fetchNewToken(function (newToken) {
        if (newToken) {
          sendHttpRequest('https://example.com/api/events', () => {}, { method: 'POST', headers: { Authorization: `Bearer ${newToken}` }, body: JSON.stringify(eventData) });
        }
      });
    }
  }, { method: 'POST', headers: { Authorization: `Bearer ${token}` }, body: JSON.stringify(eventData) });
}

sendEvent({ eventName: 'purchase', value: 100 });
```

| Method                        | Description                                                                                           |
| ----------------------------- | ----------------------------------------------------------------------------------------------------- |
| **`setItemCopy(key, value)`** | Stores a value under the specified key. Overwrites the value if the key already exists.               |
| **`getItemCopy(key)`**        | Retrieves the value associated with the specified key. Returns `undefined` if the key does not exist. |
| **`removeItemCopy(key)`**     | Deletes the value associated with the specified key.                                                  |

| Parameter   | Type     | Description                                                |
| ----------- | -------- | ---------------------------------------------------------- |
| **`key`**   | *string* | The unique identifier for the data to be stored/retrieved. |
| **`value`** | *any*    | The data to be stored (for `setItemCopy`).                 |
