[[condition-script]]
==== Script Condition

A watch <<condition, condition>> that evaluates a script. The default scripting language is 
`groovy`. You can use any of the scripting languages supported by Elasticsearch as long as the 
language supports evaluating expressions to Boolean values. Note that the `mustache` and 
`expression` languages are too limited to be used by this condition. For more information, 
see {ref}/modules-scripting.html[Scripting] in the Elasticsearch Reference.

IMPORTANT:  You must explicitly {ref}/modules-scripting.html#enable-dynamic-scripting[enable 
            dynamic scripts] in `elasticsearch.yml` to use `inline` or `indexed` scripts. 

===== Using a Script Condition

The following snippet configures an inline `script` condition that always returns `true`:

[source,json]
--------------------------------------------------
"condition" : {
  "script" : "return true"
}
--------------------------------------------------

This example defines a script as a simple string. This format is actually a shortcut for defining an
<<condition-script-inline, inline>> groovy script. The formal definition of a script is an object
that specifies the script type and optional language and parameter values. If the `lang` attribute
is omitted, the language defaults to groovy. Elasticsearch supports three script types: 
<<condition-script-inline, Inline>>, <<condition-script-file, File>>, and 
<<condition-script-indexed, Indexed>>. 

For example, the following snippet shows a formal definition of an `inline` script that explicitly 
specifies the language and defines a single script parameter, `result`. 

[source,json]
--------------------------------------------------
"condition" : {
  "script" : {
    "inline" : "return result",
    "lang" : "groovy",
    "params" : {
      "result" : true
    }
  }
}
--------------------------------------------------

[[condition-script-inline]]
===== Inline Scripts

Inline scripts are scripts that are defined in the condition itself. The following snippet shows the
formal configuration of a simple groovy script that always returns `true`. 

[source,json]
--------------------------------------------------
"condition" : {
  "script" : {
    "inline" : "return true"
  }
}
--------------------------------------------------

[[condition-script-file]]
===== File Scripts

File scripts are scripts that are defined in files stored in the `config/scripts` directory. The 
following snippet shows how to refer to the `my_script.groovy` file:

[source,json]
--------------------------------------------------
"condition" : {
    "script" : {
      "file" : "my_script"
    }
  }
--------------------------------------------------

As with <<condition-script-inline, Inline>> scripts, you can also specify the script language and 
parameters:

[source,json]
--------------------------------------------------
"condition" : {
  "script" : {
    "file" : "my_script",
    "lang" : "javascript",
    "params" : {
      "result" : true
    }
  }
}
--------------------------------------------------

[[condition-script-indexed]]
===== Indexed Scripts

Indexed scripts refer to scripts that were {ref}/modules-scripting.html#_indexed_scripts[indexed] 
in Elasticsearch. The following snippet shows how to refer to a script by its `id`:

[source,json]
--------------------------------------------------
"condition" : {
  "script" : {
    "id" : "my_script"
  }
}
--------------------------------------------------

As with <<condition-script-file, File>> and <<condition-script-inline, Inline>> scripts, you can 
also specify the script language and parameters:

[source,json]
--------------------------------------------------
"condition" : {
  "script" : {
    "id" : "my_script",
    "lang" : "javascript",
    "params" : { "color" : "red" }
  }
}
--------------------------------------------------

[[accessing-watch-payload]]
===== Accessing the Watch Payload

A script can access the current watch execution context, including the payload data, as well as 
any parameters passed in through the condition definition.

For example, the following snippet defines a watch that uses a <<input-search, `search` input>> 
and uses a `script` condition to check if the number of hits is above a specified threshold:

[source,json]
--------------------------------------------------
{
  "input" : {
    "search" : {
      "search_type" : "count",
      "indices" : "log-events",
      "body" : {
        "query" : { "match" : { "status" : "error" } }
      }
    }
  },
  "condition" : {
    "script" : {
      "script" : "return ctx.payload.hits.total > threshold",
      "params" : {
        "threshold" : 5
      }
    }
  }
  ...
}
--------------------------------------------------

When you're using a scripted condition to evaluate an Elasticsearch response, keep in mind that 
the fields in the response are no longer in their native data types. For example, the  
`@timestamp` in the response is a string, rather than a `DateTime`. To compare the response
`@timestamp` against the `ctx.execution_time`, you need to parse the `@timestamp` string into 
a `DateTime`. For example:

[source,json]
--------------------------------------------------
org.elasticsearch.common.joda.time.DateTime.parse(@timestamp)
--------------------------------------------------

You can reference the following variables in the watch context:

[options="header"]
|======
| Name                                  | Description
| `ctx.watch_id`                        | The id of the watch that is currently executing.
| `ctx.execution_time`                  | The time execution of this watch started.
| `ctx.trigger.triggered_time`          | The time this watch was triggered.
| `ctx.trigger.scheduled_time`          | The time this watch was supposed to be triggered.
| `ctx.metadata.*`                      | Any metadata associated with the watch.
| `ctx.payload.*`                       | The payload data loaded by the watch's input.
|======
