> ## Documentation Index
> Fetch the complete documentation index at: https://docs.arc.cdata.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduction to ArcScript

> Core concepts of the ArcScript language, including items, feeds, operations, keywords, and built-in scripting items with example scripts.

export const siteNameShort = "Arc";

export const siteName = "CData Arc";

{siteNameShort}Script is an XML-based language included with {siteName} that can be used to write custom processing logic. {siteNameShort}Script makes it easy to transform files or messages and integrate with other business processes. {siteNameShort} includes complete [Example Scripts](#example-scripts) for sending emails, executing batch files, working with files, and more. You can insert these examples into your scripts and events from the admin console.

However, {siteNameShort}Script is also a high-level programming language that enables you to control almost every aspect of data access and processing. You can use [keywords](./keyword-reference/keywords), attributes, items, [operations](./operations/operations), and feeds to write scripts and use them in [events](./scripting#event-scripting) on all connectors, in the dedicated [Script](../connectors/script) and [REST](../connectors/rest) connectors, and in the [custom script](../connectors/xml-map/xml-map-advanced#custom-scripts) option in the [XML Map connector](../connectors/xml-map/xml-map).

* **Attribute**: The name part of a name-value pair, as in attribute="address", value="123 Pleasant Lane".
  * Use the `#` character to denote an attribute as an array. This means that the array can contain more than one value, where each value can be referenced using 1-based indexing.
  * For example, `[myitem.myattribute#2]` refers to the second value in the `myattribute` attribute.

* **Item**: A related group of attribute-value pairs that describe an input or output. For example:

  ```
  Attribute="name" value="Bob"
  Attribute="address" value="123 Pleasant Lane"
  Attribute="phone" value="123-4567"
  ```

* **Feed**: A list of items, such as a list of customers with their addresses and phone numbers.

* **Operation**: A generic name for methods that accept items as input and produce feeds as output.

* **Keyword**: An {siteNameShort}Script statement, such as [arc:set](./keyword-reference/op-arc-set).

<Note>Arrays in {siteNameShort}Script are limited to 32768 members.</Note>

{siteNameShort}Script includes many keywords that allow you to do the following:

* Describe script inputs and outputs
* Use high-level programming constructs such as if/else statements and case statements to control execution flow
* Call operations and define your own
* Create and modify items used as inputs to an operation, as well as feeds (the output of the operation)
* Process the feed resulting from an operation call by iterating through its items

## Example Scripts

{siteNameShort} includes complete code snippets for automating common actions, such as sending an email. On the [Script connector Settings tab](../connectors/script#settings-tab) or on the **Events** tab of any connector, click **Insert Snippet** and select the action you want to perform. The necessary code is inserted at the cursor.

The following sections describe how to use and extend these code snippets to write custom processing logic.

### Using Event Inputs

Each event provides relevant inputs that you can use as the input parameters of an operation. Input parameters are defined by the input attributes in the info section.

Use the event's predefined inputs to process the file that was sent or received or send an email containing any error messages. Other inputs are also available. For example, the available inputs for the **After Receive** event are:

```xml theme={null}
<arc:info title="After Receive" desc="This event is fired after receiving a file.">
  <input name="WorkspaceId"      desc="The id of the workspace that is receiving file." />
  <input name="ConnectorId"      desc="The id of the connector that is receiving file." />
  <input name="Direction"        desc="The direction of transaction." />
  <input name="Filename"         desc="The name of the file that was received." />
  <input name="FilePath"         desc="The path of the file that was received." />
  <input name="Attachment#"      desc="The path of the attachment was received." />
  <input name="MessageId"        desc="The Id of the transaction." />
  <input name="ErrorMessage"     desc="If an error occurred, this will contain the error message." />
</arc:info>
```

### Using Operations

Use the included code samples to invoke some of the built-in [operations](./operations/operations). The following example uses the [appSendEmail](./operations/op-app-send-email) operation to send an email after a file is received. To use it, simply replace the placeholder values:

```xml theme={null}
<!-- Send Email -->
<arc:set attr="email.To"         value="Recipient(s)"/>
<arc:set attr="email.Subject"    value="Before Send"/>
<arc:set attr="email.Message"    value="File [Filename] was processed."/>
<arc:call op="appSendEmail"/>
```

<Note>The script shown above only works if you have previously configured a mail server in **Settings** (accessed by clicking the gear icon). Navigate to the **Email Settings** section of the [Alerts tab](../getting-started/administration/settings/alerts). The appSendEmail operation uses the same mail server.</Note>

### Extending the Example Scripts

Use the included code samples to pass in predefined inputs to an [operation](./operations/operations). You can also pass in inputs that are specific to the operation. For example, the [appSendEmail](./operations/op-app-send-email) operation accepts several additional inputs, such as the body text and attachments. Provide these values by using the [arc:set](./keyword-reference/op-arc-set) keyword.

Use the [arc:call](./keyword-reference/op-arc-call) keyword to call any of the built-in operations in an event, or to make calls to the API.

Use other keywords to control execution flow and more. {siteNameShort}Script is computationally complete. It also includes enhancements designed to make processing and automation easy. See [Scripting](./scripting) for more information on the syntax of {siteNameShort}Script and its capabilities.

## Items in {siteNameShort}Script

Feeds are composed of *items*, but in {siteNameShort}Script, items themselves are used for much more than the individual parts of a feed. They are also used to represent inputs to operations.

### Declaring Items

For best readability and ease of later script modification, CData recommends creating explicit input items in {siteNameShort}Script and passing them into operations on separate lines. Items are created, named, and given attribute values through the [arc:set](./keyword-reference/op-arc-set) keyword:

```xml theme={null}
<arc:set item="input" attr="mask" value="*.txt" />
```

The previous snippet sets the `mask` attribute to the value `*.txt` on the item named `input`. In this case, the input item is like a variable in {siteNameShort}Script.

However, an item named `input` is never declared. Instead, the item is created the first time you try to set an attribute on it. In this example, if the input item doesn't exist, it is created and the mask attribute is set on it.

<Tip>
  You can also use a "shorthand" method to declare items and attributes. For example:

  ```xml theme={null}
  <arc:set attr="colors.myfavorite" value="green" />
  ```

  This snippet creates a `colors` item with a `myfavorite` attribute that has a value of `green`.
</Tip>

### Passing Items as Query String Parameters

An alternative to creating explicit input items is to pass input parameters to operations in the form of [arc:call](./keyword-reference/op-arc-call) query string parameters. For an example of the difference between explicitly declaring items and passing them as parameters, consider the following lines that declare an item called `file`, and pass this item into an operation to read a line:

```xml theme={null}
<arc:set attr="file.file" value="[filepath]" />

<arc:call op="fileReadLine" in="file">
```

To accomplish this using query string parameters, you can use this syntax instead:

```xml theme={null}
<arc:call op="fileReadLine?file=[filePath | urlencode]">
```

<Note>Using this format requires that you URL-encode the parameter using the `urlencode` argument. This ensures that the application correctly parses special or reserved characters in file names without encountering errors.</Note>

### Selecting Attribute Values

To reference an attribute, use the syntax `item.attribute` (for example, `input.mask`). To query an attribute value, surround the attribute name in square brackets (\[ ]). This tells the interpreter that you want to evaluate the string instead of interpreting it as a string literal.

For example, consider the following code snippet:

```xml theme={null}
<arc:set item="item1" attr="attr1" value="value1"/>
<arc:set item="item1" attr="attr2" value="item1.attr1"/>
<arc:set item="item1" attr="attr3" value="[item1.attr1]"/>
```

The results are the following:

* `item1.attr1` gets assigned the literal string value `value1`.
* `item1.attr2` gets assigned the literal string value `item1.attr1`.
* `item1.attr3` gets assigned the value `value1`, because the string `[item1.attr1]` gets evaluated at run time as the `attr1` attribute of `item1`.

<Note>You can use a backslash to escape square brackets in string literals.</Note>

### Default Item

In {siteNameShort}Script there is always an implicit, unnamed item on an internal stack of items, the *default item*. While you can use this item to write full scripts, best practice is to define your own explicit input and output items as needed. This makes scripts easier to read and reduces the risk of overwriting an existing attribute. For simple scripting cases, you can use the default item in the following two scenarios to make scripts slightly shorter and easier to write:

* Calling operations: The default item is the item passed to the operation called by your script if no other item is specified. This means you can use [arc:set](./keyword-reference/op-arc-set) to write attributes to the default unnamed item and those attributes are passed as input to the next operation called in the script. This is one way to provide an operation's required parameters.
* Processing the current item in the output of an operation or script: If you do not specify a variable name for an operation result, then inside the [arc:call](./keyword-reference/op-arc-call) block that invokes the operation, the default item refers to the current item produced by the operation.

Manipulate the default item by omitting the item attribute of an {siteNameShort}Script keyword, as shown in the following snippet:

```xml theme={null}
<arc:set attr="path" value="." />
```

## Built-in Items

In addition to items declared in a script, several built-in items are available in the scope of a script. Built-in items provide an interface for accessing parts of HTTP requests, responses, and more. These items are useful for mapping inputs in HTTP requests to operation inputs.

The following sections describe the built-in items.

### Application Log (\_log)

The `_log` item is a hook into the {siteNameShort} Application Log. Setting the `info` attribute of this item to a string causes that string to appear in the Application Log. For example:

```xml theme={null}
<arc:set attr="_log.info" value="this string appears in the Application Log when the script executes" />
```

You can set this attribute multiple times in the same script to log multiple messages to the Application Log. The attribute value does not need to be cleared or appended; setting the attribute value as shown in the previous example causes the specified value to be logged.

### ASP.NET Session (\_session)

ASP.NET session variables are available in {siteNameShort}Script through the `_session` item. Any object stored in the session can be accessed as attributes of this item. The attribute name represents the key used to store the object in the session.

### Connector (\_connector)

The `_connector` item provides access to the fields and properties of the current connector. The available properties are the same as the values stored in the *port.cfg* file in the connector's folder, and should be accessed using the following syntax:

`[_connector.propertyName]`

<Note>Using this item requires a scripting context in the connector. This is always available on the connector **Events** tab, and some connectors can also evaluate {siteNameShort}Script in special configurable fields.</Note>

### Connector State (\_state)

The `_state` item provides persistent key/value storage scoped to the current connector instance. Values written to `_state` persist across script executions, making it useful for duplicate detection, lookup tables, counters, and other scenarios where a script needs to remember a value between runs.

`_state` is available in all {siteNameShort}Script scripting contexts, including:

* Connector events such as `beforeSend`, `afterSend`, and `afterReceive`
* [Script](../connectors/script) and [Python](../connectors/python) connectors
* [XML Map](../connectors/xml-map/xml-map) connector

#### Examples

##### Write a Value

```xml theme={null}
<arc:set attr="_state.mykey" value="some value" />
```

##### Read a Value

```
[_state.mykey]
```

If the key does not exist, an empty value is returned.

##### Delete a Key

```xml theme={null}
<arc:unset attr="_state.mykey" />
```

##### Delete All Script-Managed Keys

```xml theme={null}
<arc:unset attr="_state.*" />
```

This removes all keys written by scripts without affecting the connector's own internal state entries.

##### Duplicate File Detection Example

```xml theme={null}
<arc:call op="messageRead" out="message">
  <arc:set attr="file.sha1hash" value="[message.data | sha1hash(true)]" />
</arc:call>
<!-- Use a sanitized filename as the key (replace . to avoid the disallowed character) -->
<arc:set attr="custom.key" value="[_input.filename | replace('.', '_')]" />
<arc:set attr="storedHash" value="[_state.[custom.key]]" />
<arc:if exp="![storedHash | def | equals([file.sha1hash])]">
  <!-- New or changed file: pass it through -->
  <arc:set attr="output.filepath" value="[_input.filepath]" />
  <arc:push item="output" />
  <!-- Store the hash for next time -->
  <arc:set attr="_state.[custom.key]" value="[file.sha1hash]" />
  <arc:else>
    <arc:throw code="match" desc="A file with name [_input.filename] and hash [file.sha1hash] was already processed." />
  </arc:else>
</arc:if>
```

#### Scoping

State is scoped to the individual connector instance, so two connectors using the same script do not share state. Keys written via `_state` are automatically isolated from the connector's own internal state entries.

#### Key Names

Key names follow standard {siteNameShort}Script attribute name rules. The following characters have special behavior or are not allowed:

| Character | Behavior                                                                                                                         |
| --------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `@`       | Treated as a namespace prefix: must be followed by a name (for example, `test@` is valid)                                        |
| `#`       | Treated as an array suffix: must follow a name, and any text after it must be a non-zero integer (for example, `test#` is valid) |
| `:`       | Treated as a prefix/name separator (for example, `prefix:name`): a second `:` is rejected                                        |
| `*`       | Treated as a wildcard: multiple `*` allowed but cannot appear after `#`                                                          |
| `.`       | Not allowed: causes an "Invalid attribute name" error                                                                            |

Values have no character restrictions; any character of any length can be stored as a value. If a key is extremely long, it is automatically truncated when stored.

Because `.` is not allowed in key names, filenames (which commonly contain periods) must be sanitized before use as a key. Replace `.` with an allowed character and use that sanitized key consistently when writing and reading, as shown in the following script:

```xml theme={null}
<arc:set attr="custom.key" value="[_input.filename | replace('.', '_')]" />
<arc:set attr="_state.[custom.key]" value="[file.sha1hash]" />
[_state.[custom.key]]
```

### HTTP Cookies (\_cookies)

Use the `_cookies` item to retrieve cookies in the request and set cookies in the response. A cookie with multiple key/value pairs is represented as a collection of attributes that correspond to the key/value pairs of the cookie. The name of the cookie prefixes each attribute of the collection.

### HTTP Headers (\_httpheaders)

The `_httpheaders` item provides easy access to HTTP headers in scripts and templates. You can read the HTTP request headers by reading from this item. Write to the outgoing response headers by writing to this item. For example, you can set the content type with a line like the following:

```xml theme={null}
<arc:set item="_httpheaders" attr="content-type" value="application/xml"/>
```

### HTTP Request (\_request)

You can access variables passed into the URL query string, POSTed to the script, and other variables as collections of attributes in the `_request` item. To access a specific collection of attributes, use the name of the collection as the prefix to the attribute you want to read. For example, `[_request.qstring:name]` reads the value of the variable "name" in the query string and `[_request.form:name]` reads the value of the variable "name" in the form data.

| Attribute         | Description                                                                                                                           |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `q[uery]string:*` | Access the values of query string parameters.                                                                                         |
| `form:*`          | Access the values of variables in the form data.                                                                                      |
| `server:*`        | Access the values of server variables.                                                                                                |
| `body`            | Access the raw contents (body) of the request.                                                                                        |
| `bodybase64`      | Access the base64-encoded contents (body) of the request.                                                                             |
| `auth:*`          | Access authentication information about the user. Determine whether the user is authenticated with `[_request.auth:isauthenticated]`. |
| `other:*`         | Access other information about the request. Retrieve the application path with `[_request.other:applicationpath]`.                    |

### HTTP Response (\_response)

The `_response` item allows the script writer to write directly to the HTTP response. You can set the following attributes:

| Attribute           | Description                                                                                                                                                |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `cookie:*`          | Set cookies in the response. The name of the attribute is the name of the cookie prefixed by `cookie:` and the value of the attribute is the cookie value. |
| `writefile`         | Write the content of the specified path to the response.                                                                                                   |
| `redirect`          | Send the redirect header to the client browser. This can be used to redirect the browser to another URL.                                                   |
| `statuscode`        | Set the HTTP status code of the response.                                                                                                                  |
| `statusdescription` | Set the HTTP status description of the response.                                                                                                           |

### Mapping Context (\_map)

The `_map` item is available in the [XML Map connector](../connectors/xml-map/xml-map). Attributes set in the `_map` item are always available later in the mapping (in other words, these attributes are not cleared and the `_map` item is never out of scope).

The `_map` item is useful for storing information that is calculated at one point in the mapping and referenced later in the mapping. For example, a mapping involving an EDI document might need to count the number of *Line Items* in the document, then include this count value in a CTT segment at the end of the document. The *Line Item* count can be calculated and stored as an attribute of the `_map` item, then that attribute can be referenced in the CTT segment mapping.

### Message (\_message)

When a file passes through an {siteNameShort} [flow](../flows/flows), the application adds metadata to the file. The resulting combination of the original file and application metadata is called a *message*.

The `_message` item provides access to the body and metadata of a message in scripting contexts (and in connector fields that can interpret scripting, such as the **Subject** field in the [Email Send Connector](../connectors/email-send)).

<Note>Arrays in {siteNameShort}Script are limited to 32768 members. If a message has headers that are repeated more than 32768 times, the oldest headers are dropped off the message.</Note>

#### Metadata

The message metadata includes:

* A unique Id (called a *MessageId*) that identifies the file regardless of any changes to the filename
* Information about failures and successes during processing
* Any custom metadata promoted programmatically in the flow

To access message metadata, use the `header:*` attribute of the `_message` item. For example, when an error occurs while processing a file in {siteNameShort}, the `x-trapped-errordescription` header is added to the message that represents that file. This header stores information about the error that occurred, including the ConnectorId where the error occurred and debugging information about the error. The following syntax references this header within a scripting context:

`[_message.header:x-trapped-errordescription]`

#### Body

To access the body of a message, use the `body` attribute of the `_message` item, as shown below:

`[_message.body]`

This returns the body of the message as a string.

#### Adding Tracked Headers

To add a [Tracked Header](../getting-started/administration/activity#tracked-headers) to a message, use the `trackedheader` attribute of the `_message` item, as shown below:

```xml theme={null}
<arc:set attr="output.filepath" value="[filepath]" />
<arc:set attr="_message.trackedheader:myHeaderName" value="Myvalue" />
<arc:push item="output" />
```

#### Adding Custom Headers

To add custom headers to files, set the `Header:header_name` attribute of the file item that is pushed out by the connector. For clarity, begin with a script that pushes an unmodified version of the input file as output:

```xml theme={null}
<arc:set attr="outfile.FilePath" value="[FilePath]" />
<arc:push item="outfile" />
```

The `[FilePath]` variable resolves to the full path (and filename) of the input file, so this script makes the output file the same as the input file.

The following addition to this script adds custom headers to the file before pushing it:

```xml theme={null}
<arc:set attr="outfile.FilePath" value="[FilePath]" />
<arc:set attr="outfile.Header:myHeaderName" value="myValue" />
<arc:push item="outfile" />
```

You can make custom headers searchable in the logs by navigating to the **Tracked Headers** field in the **Advanced Settings** section of the **Settings > Advanced** page, and adding the header name(s).

#### Logging Connector Events

To add logging of connector-defined Events to the `_message` body in {siteNameShort}Script, add a `log` attribute prefix, a valid log level entry, and a `value` to the message. The following example adds an `Info` row to the log file with the text from the `value` portion of the attribute:

```xml theme={null}
<arc:set attr="_message.log:info" value="This is an info level log entry" />
```

Valid log level entries are:

* Error
* Warning
* Info
* Debug
* Trace

### Script Inputs (\_input)

The input for a script can be read from the `_input` item. The `_input` item contains variables found in the URL query string and the POST data when the script is executed. If a variable of the same name exists in the POST data, it overrides the value from the query string.

When you read values from the default item in a script, you are reading values from `_input`; likewise, attributes that you write to the default item are passed as parameters to operations along with the input to the script. Only variables defined in the info block or in the script are available in the `_input` item.

<Note>`_input` is not the default item inside an [arc:call](./keyword-reference/op-arc-call) block. If you need access to it, you must reference it by name.</Note>

### Script Outputs (\_out\[n])

You can access the current item in the feed produced by the [arc:call](./keyword-reference/op-arc-call) keyword through the default item or the built-in `_outn` item, where `n` is the level of nesting of [arc:call](./keyword-reference/op-arc-call) keywords. For example, if you are inside a single [arc:call](./keyword-reference/op-arc-call) keyword, the item's name is `_out1`. If you are inside three levels of nested [arc:call](./keyword-reference/op-arc-call) keywords, then it is `_out3`.
