JavaScript-действия
В JAICP DSL есть особые теги действий, которые позволяют вызвать из стейта отдельный сценарий. В этом подсценарии бот может реализовать любое поведение: выполнять произвольное число реакций, переходить по стейтам самого подсценария. При этом в основном сценарии эта сложная логика представлена как один тег.
Иногда в сценарии нужно выполнить действие без переключения контекста в отдельный подсценарий. В таком случае из стейта достаточно просто вызвать JavaScript-функцию, которая реализует нужное поведение.
Помимо сценарных действий JAICP DSL поддерживает JavaScript-действия (JS-действия).
Для них теги действий реализованы не как переход в подсценарий, а как обычный вызов функции внутри тега script
.
Как создать JS-действие
В этом разделе мы разработаем тег JS-действия, который принимает в качестве параметров два числа и отправляет ответ со значением их суммы.
JavaScript-функция
- Авторизуйтесь в JAICP и выберите нужный проект.
- На панели управления слева перейдите в Редактор → Код.
- Создайте в директории
src
файлfunctions.js
и напишите в нем функцию для вашего тега.
function sumTwoNumbers(numberOne, numberTwo) {
var result = parseFloat(numberOne) + parseFloat(numberTwo);
if (!isNaN(result)) {
$reactions.answer(numberOne + " + " + numberTwo + " = " + result);
} else {
$reactions.answer("Я не знаю, как посчитать " + numberOne + " + " + numberTwo + ".");
}
}
Разберем код функции:
- Функция принимает два аргумента. При помощи функции
parseFloat
они приводятся к числам. - Числа складываются, и сумма сохраняется в переменную
result
. - Если сумма имеет значение
NaN
, бот отправляет сообщение об ошибке, иначе — ответ со значением суммы.
Настройки тега
Чтобы использовать сценарий выше как тег действия, его нужно описать в специальном JSON-файле с настройками.
Создайте в директории
src
поддиректорию для тегов действий, напримерblocks
.Создайте в директории
blocks
поддиректориюSumTwoNumbers
, а в ней файлblock.json
.В файл запишите JSON-объект с настройками тега. Для JS-действий некоторые настройки отличаются:
Поле Тип Описание customTagType
Строка Тип тега действия: SC
илиJS
. Чтобы сделать тег JS-действием, укажите значениеJS
.scenarioFile
Строка Путь к нужному JavaScript-файлу относительно директории src
.functionName
Строка Название функции в файле scenarioFile
, которая будет вызвана при использовании тега. Заменяет полеstartState
.подсказкаВсе остальные поля, включая настройки параметров и отображения в J‑Graph, заполняются и работают так же, как для тегов сценарных действий.
Полный пример настроек:
{
"tagName": "SumTwoNumbers",
"customTagType": "JS",
"scenarioFile": "functions.js",
"functionName": "sumTwoNumbers",
"caption": {
"ru": "Сложить два числа",
"eng": "Sum two numbers"
},
"description": {
"ru": "Используйте этот блок, чтобы сложить два числа и отправить ответ со значением суммы.",
"eng": "Use this block to calculate the sum of two numbers and send a reply with the result."
},
"hint": {
"ru": "Сложить два числа и отправить ответ со значением суммы",
"eng": "Calculate the sum of two numbers and send a reply with the result"
},
"parameters": [
{
"name": "numberOne",
"type": "integer",
"required": true,
"localization": {
"ru": "Первое число",
"eng": "First number"
}
},
{
"name": "numberTwo",
"type": "integer",
"required": true,
"localization": {
"ru": "Второе число",
"eng": "Second number"
}
}
]
}
Дальнейшие шаги не отличаются от сценарных действий:
Укажите путь к JSON-файлу в
chatbot.yaml
:customTags:
- src/blocks/SumTwoNumbers/block.jsonИспользуйте тег в сценарии через редактор кода или J‑Graph.
Преимущества JS-действий
С точки зрения разработки сценария через редактор кода JS-действия не дают больших преимуществ.
Если подключить файл с функцией через require
и вызвать ее из тега script
, поведение бота не изменится:
- JS-действие
- Функция
theme: /
state: SumTwoNumbers
q!: * [чему равно] @duckling.number::numberOne (плюс/$regex<\+>) @duckling.number::numberTwo *
SumTwoNumbers:
numberOne = {{$parseTree._numberOne}}
numberTwo = {{$parseTree._numberTwo}}
a: Посчитать для вас что-нибудь еще?
require: functions.js
theme: /
state: SumTwoNumbers
q!: * [чему равно] @duckling.number::numberOne (плюс/$regex<\+>) @duckling.number::numberTwo *
script:
sumTwoNumbers($parseTree._numberOne, $parseTree._numberTwo);
a: Посчитать для вас что-нибудь еще?
Однако если сценарий разрабатывается через графический редактор J‑Graph, функцию можно использовать как блок действия и работать с ней в удобном интерфейсе.
Отличия от сценарных действий
Сценарное действие | JS-действие |
---|---|
Эквивалентно переходу в другой стейт через тег go! с передачей параметров. | Эквивалентно вызову функции через тег script . |
В одном стейте может быть не более одного тега. Если их больше, то будет выполнено только первое действие. | Может быть произвольное число тегов в одном стейте. Все действия будут выполнены. |
Значения параметров можно извлечь через объект $request.data.args . | Значения параметров можно извлечь как стандартные аргументы функции. |
Желательно предусмотреть параметры для стейтов основного сценария, в которые бот должен вернуться после действия (например, okState ). | После действия продолжает выполняться основной сценарий, поэтому параметры для стейтов предусматривать не обязательно. |