ym88659208ym87991671
Как написать свой сценарий | Документация для разработчиков
Skip to main content

Как написать свой сценарий

Обновлено 13 октября 2022

Создание своего сценария

При создании проекта автоматически создаются два сценария: run_app и hello_scenario. Ниже описан пример переиспользования этих сценариев и создания нового сценария, который разными способами приветствует пользователя при запуске смартапа.

Служебный сценарий – run_app

run_app – это служебный интент, который означает запуск смартапа без особого контекста. Сценарий для этого интента находится в <ИМЯ_ПРОЕКТА>/static/references/scenarios/run_app.json.

Ниже представлен пример сценария, который служит для перенаправления пользователя в сценарий приветствия при запуске смартапа. У сценария ниже нет явного указания типа, так как это базовый сценарий без формы.

ПолеОписание
run_appИмя текущего сценария
actions: typeТип действия. Например, run_scenario - тип, который запускает другой сценарий
actions: scenarioИмя сценария, который будет запущен. Например, hello_scenario - это сценарий приветствия

Пример:

{
"run_app": {
"actions": [
{
"type": "run_scenario",
"scenario": "hello_scenario"
}
]
}
}

Сценарий приветствия - hello_scenario

Ниже представлен сценарий другого типа – form_filling. Это означает, что сценарий будет выполнен только после заполнения формы с обязательными полями. При создании такого сценария вводится дополнительная сущность - форма (Form).

Данный сценарий можно поместить в отдельный файл или объявить рядом с уже существующим.

ПолеОписание
hello_scenarioИмя текущего сценария
typeТип сценария. Например, form_filling - тип сценария с формой
formИмя формы
actions: typeТип действия. Например, string - тип, который возвращает строку
actions: commandНазвание действия, которое будет совершено. В примере ниже - это выдача ответа пользователю
actions: nodes: pronounceTextОтвет, который будет выдан пользователю.В данном параметре используется шаблон Jinja. Фреймворк передает в окружение этого шаблона параметры, собираемые классом BasicParametrizer: входящее сообщение, формы, id текущего сценария, а также переменные и счётчики из actions. При выполнении сценария ниже, на любое входящее сообщение будет отправляться ответ: "Привет user_id!"

Пример:

{
"hello_scenario": {
"type": "form_filling",
"form": "hello_form",
"actions": [
{
"type": "string",
"command": "ANSWER_TO_USER",
"nodes": {
"pronounceText": "Привет {{main_form.name}}!"
}
}
]
}
}

Формы, по аналогии со сценариями, находятся в специальной директории - <ИМЯ_ПРОЕКТА>/static/references/forms/. Формы состоят из полей, а поля - из филлеров. Филлеры могут находить в тексте имена, числа, даты, города и прочие объекты. В примере ниже филлер user_id получает из сообщения id пользователя.

{
"hello_form": {
// имя формы
"fields": {
// словарь с полями
"name": {
// имя поля
"filler": {
// параметр с филлером внутри
"type": "user_id" // тип филлера
}
}
}
}
}

Сценарий приветствия - hello_form

Следующий пример - это создание сценария, который меняет способ приветствия в зависимости от возраста пользователя:

  • если пользователь моложе 50 лет, то приветствие идет через "Привет";
  • если пользователь старше 50 лет, то приветствие идет через "Здравствуйте".

Данный сценарий можно поместить в отдельный файл или объявить рядом с уже существующим. В сценарий можно попасть только из предыдущего сценария - hello_scenario:

{
"hello_scenario": {
/*"type": "form_filling" ... */
},
"gentle_hello_scenario": {
"actions": [
{
"type": "string",
"command": "ANSWER_TO_USER",
"nodes": {
"pronounceText": "Здравствуйте {{main_form.name}}!"
}
}
]
}
}

Узнать возраст пользователя можно через расширение уже существующей формы - hello_form.

ПолеОписание
questions: typeТип действия.
filler: typeТип филлера. Например, number_first - берет первую встречную цифру в тексте
{
"hello_form": {
"fields": {
"name": {
"filler": {
"type": "user_id"
}
},
"age": {
"questions": [
{
"type": "string",
"command": "ANSWER_TO_USER",
"nodes": {
"pronounceText": "Сколько вам лет?"
}
}
],
"filler": {
"type": "number_first"
}
}
}
}
}

Теперь необходимо добавить в hello_scenario новую сущность - Requirement. Через эту сущность задается условие на переход в другой сценарий.

{
"hello_scenario": {
"type": "form_filling",
"form": "hello_form",
"actions": [
{
"type": "else", // тип actions с условием
"requirement": {
// объект Requirement
"type": "template",
"template": "{{main_form.age >= 50}}" // шаблон Jinja
},
"action": {
// действие при успешном прохождении условия
"type": "run_scenario",
"scenario": "gentle_hello_scenario"
},
"else_action": {
"type": "string",
"command": "ANSWER_TO_USER",
"nodes": {
"pronounceText": "Привет {{main_form.name}}!"
}
}
}
]
},
"gentle_hello_scenario": {
"actions": [
{
"type": "string",
"command": "ANSWER_TO_USER",
"nodes": {
"pronounceText": "Здравствуйте {{main_form.name}}!"
}
}
]
}
}

Особенность slot filling

Запуск сценария с формой происходит только при заполнении всех обязательных полей, поэтому форма всегда пытается заполниться целиком. Но в SmartApp Framework все поля являются опциональными. Из-за этого, если в примере выше не указать возраст в первом сообщении, то уточняющий вопрос никогда не будет задан и это приведет к ошибке сравнения. В итоге поле age будет заполнено None.

> привет
TypeError: '>=' not supported between instances of 'NoneType' and 'int'
> привет, мне тридцать лет
pronounceText: Привет local_testing_1!

Во избежание этой ошибки необходимо сделать поле age обязательным, добавив свойство required: true. В этом случае, если поле будет пустым, то выполнится блок из questions.

> привет
pronounceText: Сколько вам лет?
> 50
pronounceText: Здравствуйте local_testing_1!
> привет 30
pronounceText: Привет local_testing_1!

При этом поле age все еще может быть заполнено первым сообщением. Чтобы поле заполнялось только ответом на заданный вопрос, необходимо выставить флаг available: false.

"age": {
"required": true,
"available": false,
"questions": [
{
"type": "string",
"command": "ANSWER_TO_USER",
"nodes": {
"pronounceText": "Сколько вам лет?"
}
}
],
"filler": {
"type": "number_first"
}
}
> привет 30
pronounceText: Сколько вам лет?
> 50
pronounceText: Здравствуйте local_testing_1!

Заметили ошибку?

Выделите текст и нажмите Ctrl + Enter, чтобы сообщить нам о ней