JavaScript actions
JAICP DSL has special action tags, which allow a state to execute a separate script. In this embedded script, any behavior can be implemented: the bot can execute any number of reactions or make transitions between the states of this embedded script. In the main script, however, this complex business logic is represented as a single tag.
Sometimes you might need to execute an action that doesn’t switch the context to a separate script. In this case, the state can simply call a JavaScript function which implements the appropriate behavior.
In addition to script actions, JAICP DSL also supports JavaScript (JS) actions.
Such action tags are implemented as regular function calls inside the script
tag rather than transitions to an embedded script.
How to create a JS action
In this section, we will develop a JS action tag which accepts two numbers as its parameters and makes the bot reply with the value of their sum.
JavaScript function
- Sign in to JAICP and select the necessary project.
- From the sidebar, navigate to Editor → Code.
- In the
src
directory, create a file calledfunctions.js
and write a function for your tag there.
function sumTwoNumbers(numberOne, numberTwo) {
var result = parseFloat(numberOne) + parseFloat(numberTwo);
if (!isNaN(result)) {
$reactions.answer(numberOne + " + " + numberTwo + " = " + result);
} else {
$reactions.answer("I don’t know how to calculate " + numberOne + " + " + numberTwo + ".");
}
}
Let’s go over the function code:
- The function accepts two arguments. They are converted to numbers using the
parseFloat
function. - The numbers are added to one another, and the sum is stored in the
result
variable. - If the sum has the value of
NaN
, the bot reports an error; otherwise, it replies with the sum value.
Tag settings
To use the above script as a action tag, you need to describe it in a special JSON settings file.
In the
src
directory, add a subdirectory for action tags, such asblocks
.In the
blocks
directory, add aSumTwoNumbers
subdirectory containing a file calledblock.json
.Add a JSON object with the tag settings into this file. For JS actions, some settings are different:
Property Type Description customTagType
String Action tag type: SC
orJS
. SpecifyJS
to make the tag a JS action.scenarioFile
String The path to the JavaScript file, relative to the src
directory.functionName
String The name of the function in scenarioFile
which will be called when the tag is used. Replaces thestartState
property.tipAll the other properties, including the parameter and J‑Graph apperance settings, are configured and work in the same way as their script action counterparts.
Here is a full settings example:
{
"tagName": "SumTwoNumbers",
"customTagType": "JS",
"scenarioFile": "functions.js",
"functionName": "sumTwoNumbers",
"caption": {
"eng": "Sum two numbers"
},
"description": {
"eng": "Use this block to calculate the sum of two numbers and send a reply with the result."
},
"hint": {
"eng": "Calculate the sum of two numbers and send a reply with the result"
},
"parameters": [
{
"name": "numberOne",
"type": "integer",
"required": true,
"localization": {
"eng": "First number"
}
},
{
"name": "numberTwo",
"type": "integer",
"required": true,
"localization": {
"eng": "Second number"
}
}
]
}
The remaining steps are the same as for script actions:
Specify the JSON file path in
chatbot.yaml
:customTags:
- src/blocks/SumTwoNumbers/block.jsonUse the tag in your script via the code editor or J‑Graph.
Benefits of JS actions
For developers who work with the script through code, JS actions may not offer many advantages.
If you import the file with the function using require
and call it from the script
tag, the bot behavior will remain the same:
- JS action
- Function
theme: /
state: SumTwoNumbers
q!: * @duckling.number::numberOne (plus/$regex<\+>) @duckling.number::numberTwo [equals] *
SumTwoNumbers:
numberOne = {{$parseTree._numberOne}}
numberTwo = {{$parseTree._numberTwo}}
a: Should I calculate anything else for you?
require: functions.js
theme: /
state: SumTwoNumbers
q!: * @duckling.number::numberOne (plus/$regex<\+>) @duckling.number::numberTwo [equals] *
script:
sumTwoNumbers($parseTree._numberOne, $parseTree._numberTwo);
a: Should I calculate anything else for you?
However, if the script is developed through the J‑Graph visual editor, you can use the function as an action block, which is a lot more convenient.
Differences from script action tags
Script action | JS action |
---|---|
Does the same as a transition to another state using go! with parameters. | Does the same as a function call inside the script tag. |
There can be at most one tag per state. If there are more, only the first action will be executed. | There can be any number of tags per state. All the actions will be executed. |
Parameter values can be extracted via the $request.data.args object. | Parameter values can be extracted as standard function arguments. |
It is recommended to include parameters for states of the main script where the bot should return after the action (such as okState ). | Since the main script continues after an action, including state parameters is not necessary. |