Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 41 Next »

Общее описание

Сценарии позволяют описывать диалоги  системы autoFAQ с пользователями. Диалог может включать в себя переписку с пользователем, обращение к данным во внешних системах и обогащение ответов.

Система позволяет создавать сценарии диалогов произвольной сложности и прикреплять их напрямую к документам в базах знаний. В случае когда база знаний по запросу пользователя определяет документ, содержащий вместо ответа сценарий, бот начнет вести с пользователем описанный в сценарии диалог.  

Описание сценариев в системе ведется при помощи языка DSL autoFAQ. Тело сценария состоит из последовательных операций. Каждая операция располагается в отдельной строке, для связи со следующей операцией в конце строки требуется указание символа "+". Некоторые операции могут содержать 1 или несколько опциональных модификаторов. 


Системные переменные

Для работы с контекстом в сценариях доступны следующие системные переменные:

{userFullName} - имя пользователя

{userLogin} - логин пользователя

{userEmail} - электронная почта пользователя

{userPayload.<название_даных>} - дополнительные данные о пользователе, полученные при идентификации пользователя во внешней системе

{platformInMessageQuery} - текст запроса пользователя

{http_code} - переменная содержит код статуса последнего запроса к API

Пользовательские переменные

В сценариях возможно создавать и использовать для хранения данных любые пользовательские переменные. Значение переменной будет потеряно после завершения сценария. 

{userSaidYes} - пример пользовательской переменной 

Списки

Переменная attachments[]  хранит не одно значение, а список значений, при записи новых значений в данную переменная они будут дописаны в конец списка.

запроситьФайл("Приложите файл").сохранитьРезультат("file")+    -   полученные данные перезапишут значение переменной
запроситьФайл("Приложите файл").сохранитьРезультат("files[]")+ -   полученные данные будут дописаны в список

Порядок выполнения шагов сценария 

Все шаги сценария выполняются последовательно с первой до последней строки. Если вы хотите временно исключить одну из строк из процесса выполнения сценария - установите в начале данной строки символ //

сообщениеПользователю.сШаблоном("Привет")+						- шаг будет выполнен
//сообщениеПользователю.сШаблоном("Привет, {userFullName}")+ 	- шаг не будет выполнен

В конце сценария обязательно размещение одного из шагов завершения сценария:

завершить - завершение текущего сценария
завершитьСШаблоном("Пока!") - завершение текущего сценария с выводом сообщения пользователю
завершитьСНовымЗапросом("Новый запрос") - завершение текущего сценария и одновременный запуск нового чата с указанным запросом
завершитьИПеревестиНаОператора - завершение текущего сценария и перевод диалога в очередь оператору

Список команд языка DSL 

сообщениеПользователю.сШаблоном("сообщение")  

Вывод простого текстового сообщения пользователю без ожидания ответной реакции. 

Сообщение может содержать HTML форматирование, а также использовать вставку значений переменных. Сообщение будет передано в текущий открытый диалог, в тот же канал. Система самостоятельно проверит форматирование сообщения на соответствие требованиям канала. 

сообщениеПользователю.сШаблоном("Текст сообщения")+	- вывод простого текстового сообщения
сообщениеПользователю.сШаблоном("Сообщение от {userFullName}")+	- вывод текстового сообщения с использованием данных из переменной
сообщениеПользователю.сШаблоном("Пройдите по <a href='https://yandex.ru'>ссылке</a>")+	- вывод HTML форматированного сообщения

сообщениеПользователю.сФайлами(111).сШаблоном("сообщение")

Расширением предыдущей команды служит часть ".сФайлами", которая позволяет отправить пользователю файлы из соответствующего документа.

сообщениеПользователю.сФайлами(523).сШаблоном("Высылаю файл") - отправка файла с идентификатором 523 пользователю вместе с сопровождающим текстом
сообщениеПользователю.сФайлами(523, 524, 525).сШаблоном("Высылаю файл") - отправка нескольких файлов пользователю
сообщениеПользователю.сФайлами(523).сШаблоном("") - отправка файла пользователю без сопровождающего текста

Идентификатор файла копируется из формы прикладывания файла к документу-сценарию.

Замечание: Передача файлов пользователю поддерживается только для документов баз знаний с типом сценарий и не поддерживается для сценариев приветствия и интеграций.


задатьПользователюВопрос("сообщение")  

Вывод текстовой информации и ожидание ввода пользователя. Поддерживает вывод форматированного сообщения с использованием переменных, получение и проверку данных на соответствие шаблону. Время ожидания ответа от пользователя устанавливается таймером сценариев в разделе Настройки - Запросы - Сценарии.

Функции операции:

.сВариантамиОтвета(варианты) - функция предоставляет пользователю варианты выбора из списка. В случае если канал позволяет отображать кнопки - варианты будет представлены кнопками, в противном случае варианты будут представлены автоматически сгенерированным списком. При этом пользователь сохраняет возможность написать ответ вручную минуя варианты выбора.

задатьПользователюВопрос("На какую дату нужен пропуск ?").сВариантамиОтвета("Сегодня", "Завтра").сохранитьРезультат("day")+

.проверитьФормат(формат, сообщение) - функция проверяет полученные от пользователя данные на соответствие шаблону. В случае соответствия передает данные далее, в обратном случае выводит текст сообщения и ожидает получения корректной информации.

задатьПользователюВопрос("Укажите дату?").проверитьФормат("(0[1-9]|[12][0-9]|3[01])[- \/.](0[1-9]|1[012])[- \/.](19|20)\\d\\d", "Не понял вас, повторите пожалуйста.").сохранитьРезультат("day")+

//  выражение для проверки, что email имеет корректный формат
задатьПользователюВопрос("Какой ваш email?").проверитьФормат("^\S+@\S+\.\S+$", "Пожалуйста, введите корректный email").сохранитьРезультат("user_said_email")+

.сохранитьРезультат(переменная) - функция сохраняет полученные данные в переменную для дальнейшего использования в сценарии.

задатьПользователюВопрос("Как дела ?").сохранитьРезультат("what")+

вызвать  

Вызывает внешние команды и системы. В настоящее время поддерживается обращение только к API (REST и SOAP) сервисам, планируется подключение к почтовым , FTP и прочим сервисам

Функции операции:

.внешнийСервис(адрес, тип) - обязательная функция, которая формирует вызов API сервисов.  В параметрах указывается адрес сервиса и тип запроса. Поддерживаются основные HTTP запросы - GET, POST, PUT.

вызвать.внешнийСервис("https://api.autofaq.ai/v1/ping","GET")+[.сохранитьРезультат("result")|.сохранитьРезультатКакСтроку("result")]

.сПараметрами() - необязательная функция, передает в запрос список параметров адресной строки, параметры будут собраны в соответствующий запросу формат

вызвать.внешнийСервис("https://api.autofaq.ai/api/v1/services/123/status","GET").сПараметрами(("foo","bar"),("user_token","1234567"))+

.сЗаголовками() - необязательная функция, передает в запрос список заголовков в формате пар ключ:значение

вызвать.внешнийСервис("https://api.autofaq.ai/api/v1/documents", "POST").сЗаголовками(("Content-Type", "application/json"),("charset", "utf-8"),("Authorization","Bearer {user_token}"))+

.сТеломСообщения() - необязательная функция, передает тело запроса. Поддерживаются форматы x-www-form-urlencoded и json

вызвать.внешнийСервис("https://api.autofaq.ai/api/v1/documents", "POST").сЗаголовками(("Content-Type", "application/json")).сТеломСообщения({"name":"new document", "question":"new question"})+

вызвать.внешнийСервис("https://api.autofaq.ai/api/v1/documents", "POST").сЗаголовками(("Content-Type", "application/x-www-form-urlencoded")).сТеломСообщения("name=new document, question=new question")+

.сСоставнымТеломСообщения() - необязательная функция, передает multipart тело запроса для передачи файлов 

вызвать.внешнийСервис("https://api.autofaq.ai/api/v1/documents", "POST").сСоставнымТеломСообщения(("content" -> "C:/docker.yml")).сохранитьРезультат("callRes")+

.сохранитьРезультат() - функция обрабатывает полученный ответ в формате JSON, сохраняет значения указанных полей в переменные сценария. Функция обрабатывает каждое значение ключа ответа и сохраняет его в отдельной переменной. В качестве параметров команды указываются пары ключ ответа - переменная

вызвать.внешнийСервис("https://api.autofaq.ai/api/v1/documents", "POST").сТеломСообщения({"name":"new document", "question":"new question"}).сохранитьРезультат(("message", "response_message"),("code", "response_code"))+

.сохранитьРезультатКакСтроку() - функция обрабатывает полученный ответ в формате JSON и сохраняет сериализованный в текст ответ целиком в переменную. 

вызвать.внешнийСервис("https://api.autofaq.ai/api/v1/documents", "POST").сТеломСообщения({"name":"new document", "question":"new question"}).сохранитьРезультатКакСтроку("result")+

установитьПеременную(переменная, значение)

Операция установки значений переменной, старое значение будет затерто. При указании значения допускается использование переменных.

установитьПеременную("date", "Сегодня {new_date}")+

установитьПеременнуюВДиалог(переменная, *аргументы)

Операция установки переменной для диалога (подробней Интеграции) . При указании значения допускается использование переменных.

Устаревший формат:
установитьПеременнуюВДиалог("ответ", значение = "{ответ}", название = "Ответ пользователя", показыватьОператору = true, обязательное = true, редактируемое = true)

Актуальный формат:
установитьПеременнуюВДиалог(
    ключ = "priority",                  - системное название задаваемой переменной, любой текст
    значение = "[\"v1\", \"v2\"]",      - значение по умолчанию: число/текст/массив/булево значение
    название = "Выберите критичность",  - название, которое будет отображаться в интерфейсе, текст
    редактируемое = true,               - является ли поле редактируемым или нет, возможные значения: true/false
    показыватьОператору = true,         - показывать ли оператору задаваемое поле, возможные значения: true/false
    обязательное = true,                - является ли обязательным при закрытии диалога, возможные значения: true/false
    множественныйВыбор = true,          - можно ли выбрать несколько вариантов, применимо только для выпадающего списка, возможные значения: true/false
    тип = "Выпадающий список",          - тип задаваемой переменной, возможные значения в таблице ниже
    варианты = "{\"v1\": \"High\", \"v2\": \"Medium\"}" - список возможных значений, применимо только для выпадающего списка, можно задать как с помощью другой переменной, так и напрямую
)

Список возможных типов с примерами использования:

Тип

Пример использования

Текст

установитьПеременнуюВДиалог(
	ключ = "NonEditabletext",
    значение = "Нередактируемый текст",
    название = "Примечание",
    показыватьОператору = true,
    редактируемое = false,
    обязательное = false,
    тип = "Текст"
)
установитьПеременнуюВДиалог(
    ключ = "textField",
    значение = "г.Москва Ул.Тверская",
    название = "Адрес",
    показыватьОператору = true,
    редактируемое = true,
    обязательное = true,
    тип = "Текст"
)

Число

установитьПеременнуюВДиалог(
	ключ = "number",
    значение = "",
    название = "Возраст",
    показыватьОператору = true,
    редактируемое = true,
    обязательное = true,
    тип = "Число"
)

Выпадающий список

установитьПеременную("priority", "{\"v1\": \"Blocker\", \"v2\": \"Critical\", \"v3\": \"Major\", \"v4\": \"Minor\"}")+
установитьПеременнуюВДиалог(
    ключ = "priority",
    значение = "[\"v1\", \"v2\"]",
    название = "Выберите критичность",
    редактируемое = true,
    показыватьОператору = true,
    обязательное = true,
    множественныйВыбор = true,
    тип = "Выпадающий список",
    варианты = "{priority}"
)
установитьПеременнуюВДиалог(
    ключ = "severity",
    значение = "",
    название = "Выберите важность",
    редактируемое = true,
    показыватьОператору = true,
    обязательное = true,
    тип = "Выпадающий список",
    варианты = "{\"v1\": \"High\", \"v2\": \"Medium\", \"v3\": \"Low\"}"
)

Переключатель

установитьПеременнуюВДиалог(
	ключ = "switcher",
    значение = "true",
    название = "Активный?",
    показыватьОператору = true,
    редактируемое = true,
    обязательное = true,
    тип = "Переключатель"
)

если(условие) 

Операция сравнения переменных. Доступны операции сравнения:  равенство (==), больше (>), меньше (<), неравенство (!=). 

Функции операции:

.то(список операций) - блок операций, которые будут выполнены в случае истинности проверки

если("{error} == 1").то(сообщениеПользователю.сШаблоном("Система не работает"))+

Блок операций может состоять из нескольких операций, различные операции в блоке соединены знаком +

если("{when_error} == 1").то(
   задатьПользователюВопрос("Не разобрал дату. Введи пожалуйста еще раз").сохранитьРезультат("when")+
   вызвать.внешнийСервис("http://yandex.ru", "GET").сПараметрами(("text","{when}")).сЗаголовками().сохранитьРезультат(("name", "when"))
)+

.и(условие) - функция объединения условий

если("{error} == 0").и("{connection_mistakes} == 0").то(сообщениеПользователю.сШаблоном("Система работает"))+

.или(условие) - функция выполняет дизъюнкцию условий

если("{error} == 1").или("{connection_mistakes} == 1").то(сообщениеПользователю.сШаблоном("Система не отвечает"))+

запроситьФайл("сообщение")

Процедура получения файла  и записи его в переменную. Пользователю будет выведен текст сообщения

запроситьФайл("Приложите файл")+

Функции операции:

.можноПропустить(сообщение) - функция позволяет пользователю пропустить отправку файла

запроситьФайл("Приложите файл").можноПропустить("Пропустить")+

.сохранитьРезультат(переменная) - функция сохраняет файл в переменную или список

запроситьФайл("Приложи файл").сохранитьРезультат("files[]")+

повторитьСШага(номер шага, "сообщение")

Операция перехода к указанной строке сценария. Если текст вопроса не задан, переход осуществляется безусловно (без вопросов), если текст сообщения задан - пользователю будет задан вопрос с вариантами ответа "Да" и "Нет".

повторитьСШага(4,"Повторим?")+
если("{answer} == 0").то(повторитьСШага(8))+

установитьМетку()

Установка определенной метки в коде, чтобы потом в нее можно было перейти из любого места сценария.

установитьМетку("раз")

перейтиНаМетку()

Осуществить переход на установленную метку в сценарии.

перейтиНаМетку("раз").неБольше(3)  - осуществится переход на метку 3 раза
перейтиНаМетку("раз").            - осуществится переход на метку, ограничение на количество переходов - 10

запросВБазыЗнаний("вопрос", переменная)

Проверка наличия у системы автоматического ответа на указанный запрос. Если в базах знаний есть ответ, который удовлетворяет требованиям по точности, переменной будет присвоено значение true, если ответа нет - false.

запросВБазыЗнаний("Как купить слона", "botKnows")+
если("{botKnows} == true").то(сообщениеПользователю.сШаблоном("Ответ есть"))+

комментарий("сообщение")

Команда позволяет добавлять комментарий в диалог.

комментарий("текст комментария")

выполнитьJs(скрипт)

Выполнить произвольный скрипт на JavaScript. Шаг позволяет реализовать произвольную логику вычислений или разбор сложных объектов.

Javascript VM сответствует ECMAScript 5.1

JS скрипт имеет доступ ко всем переменным сценария. Результаты скрипта следует записать в JSON объект и передать его на выход, в DSL сценарии можно будет получить к ним доступ по названиям полей.

выполнитьJs("""
var uids = JSON.parse(results);
var ln = uids.length;
if (ln == 0) {var uuid = '';} else {var uuid = uids[0]["UUID"];}
var exit = {'uuid':uuid, 'numberOfUids':ln};
exit;
""") +
завершитьСШаблоном("Заявка создана, всего создано полей {numberOfUids}, первый id - {uuid}.")

Внутри JavaScript есть возможность получить данные об операторе для случая, когда запущен сценарий на интеграцию по кнопке. Название объекта - initByOperator.

Пример использования:

выполнитьJs("""
var initByOperator = JSON.parse(initByOperator);
var initByOperatorLogin = initByOperator.login;
var exit = {'operatorLogin ': initByOperatorLogin, 'operatorFIO': initByOperator.fullName, 'operatorEmail': initByOperator.email};
exit;
""")+
комментарий("ФИО оператора: {operatorFIO}") +
комментарий("Логин оператора: {operatorLogin}") +
комментарий("Email оператора: {operatorEmail}") +

Весь список параметров, к которым можно получить доступ:

id: String, login: String, fullName: Option[String], isActive: Boolean, isNotify: Boolean, serviceId: String, actions: Seq[UserRoleType], email: Option[String], settings: UserSettings = UserSettings()

knowledgeBases: Seq[Long] = Seq.empty, autoAssignEnabled: Boolean = false


добавитьПолеВФормуОператора(*args) и показатьФормуОператору(имя = "форма")

Для конструирования формы, которая будет показана оператору в момент работы сценария интеграции, добавлена команда добавитьПолеВФормуОператора со следующими параметрами:

форма: String, - имя формы - обязательный параметр
переменная: String, - имя переменнной, которая пойдет в сценарий и имя в html form - обязательный параметр
название: String - имя на форме,
тип: String - Тип HTML ввода - обязательный параметр, если не задано или неверное -> нередактируемый текст 
описание: String  - описание на форме,
значение: String - предопределенное значение,
обязательное: Boolean - обязательность - по-умолчанию - false,
варианты: String - варианы для выпадающих списков - пример - {\"v1\": \"l1\", \"v2\": \"l2\"}

Пример:

добавитьПолеВФормуОператора(
  форма = "Заведение заявки в Jira",
  переменная = "t6",
  название = "Теги",
  тип = "Множественный выбор",
  описание = "Выберите теги, которыми пометить обращение",
  варианты = "{tags}",
  обязательное = true
)

Список возможных значений параметра "тип":

  • "Нередактируемый текст"

  • "Однострочный редактируемый текст"

  • "Многострочный редактируемый текст"

  • "Переключатель"

  • "Целое число"

  • "Выпадающий список"

  • "Множественный выбор"

После того, как все поля формы заданы, нужно использовать команду для показа формы:

показатьФормуОператору(имя = "Заведение заявки в Jira")

завершитьСШаблоном("сообщение")

Операция завершения сценария. Если сообщение указано - перед остановкой сценария пользователю будет выведен текст сообщения.  

завершитьСШаблоном("Всего хорошего, {userFullName}")
вызвать.внешнийСервис("{url}", "POST").сПараметрами(("accessKey", "{accessKey}")).сТеломСообщения("{"email":"{myEmail}"}").сохранитьРезультатКакСтроку("res")+
если("{http_code} > 210").то(завершитьСШаблоном("Не смог выполнить запрос. Ошибка:<br>{res}"))+

завершитьСНовымЗапросом("вопрос")

Операция завершения текущего сценария и вызова другого документа по запросу в бота. После завершения этого сценария, но в рамках текущей сессии боту будет передан приведенный запрос. Запрос будет обработан по стандартной процедуре, так как если бы этот запрос написал пользователь. Если результатом поиска по данному запросу будет документ с ответом в виде сценария, то по завершении текущего сценария будет сразу запущен следующий сценарий.

задатьПользователюВопрос("Что еще вы хотели узнать ?").сохранитьРезультат("what")+
завершитьСНовымЗапросом("{what}")

завершитьИПеревестиНаОператора

Операция завершения текущего сценария и перевода диалога в очередь оператору. Запрос будет обработан по стандартной процедуре, так как если бы этот запрос написал пользователь и он сразу попал в очередь оператору.

сообщениеПользователю.сШаблоном("Привет!")+
завершитьИПеревестиНаОператора

завершитьИЗакрытьДиалог()

Операция завершения текущего сценария и закрытия всего диалога.


Пример сценариев

Сценарий с вызовом внешнего сервиса, разбором ответа в JS.

установитьПеременную("host_cities", "https://api.autofaq.ai/v1/query") +
установитьПеременную("service_id", "121000") +
установитьПеременную("service_token", "939b8") +
установитьПеременную("other_score", "0.5") +
задатьПользователюВопрос("Уточните ваш город, пожалуйста?").сохранитьРезультат("city")+
вызвать.внешнийСервис("{host_cities}", "POST").сЗаголовками(("Content-Type", "application/json"),("charset", "utf-8")).сТеломСообщения("{\"service_token\": \"{service_token}\",\"service_id\":{service_id},\"query\":\"{city}\"}").сохранитьРезультатКакСтроку("results")+
выполнитьJs("""
var result = JSON.parse(results); var score = 0.0; var answer = '';
if (result.results.length > 0) {
	answer = result.results[0]['answer']; score = result.results[0]['score'];
    answer = answer.replace(/\n/g,'<br>');
} 
var exit = {'answer':answer, 'score':score}; exit;
""") +
если("{http_code} > 210").то(завершитьСШаблоном("Что-то сломалось. Зайдите попозже."))+
если("{score} < {other_score}").то(завершитьСШаблоном("Вот в этом городе у нас ничего нет"))+
сообщениеПользователю.сШаблоном("В указанном городе можно приобрести по адресам: <br>{answer}")+
задатьПользователюВопрос("Все ок?").сВариантамиОтвета("Да", "А мне не выдают").сохранитьРезультат("what")+
если("{what} == Да").или("{what} == да").то(завершитьСШаблоном("ну и отлично. Всего хорошего!"))+
завершитьСНовымЗапросом("Перевести на оператора")

Сценарий для интеграции на событие "Нажатие кнопки оператором"

комментарий("Запуск интеграции по кнопке.")+
установитьПеременнуюВДиалог("Поле 2", значение = "Field 2", название = "Поле 2", показыватьОператору = true, обязательное = true, редактируемое = false)+
установитьПеременную("priority", "{\"v1\": \"Blocker\", \"v2\": \"Critical\", \"v3\": \"Major\", \"v4\": \"Minor\"}") +
добавитьПолеВФормуОператора(
  форма = "Заведение заявки в Jira",
  переменная = "t1",
  название = "Что вам нужно сделать: ",
  тип = "Нередактируемый текст",
  значение = "Заполните форму"
) +
добавитьПолеВФормуОператора(
  форма = "Заведение заявки в Jira",
  переменная = "t2",
  название = "Название заявки",
  тип = "Однострочный редактируемый текст",
  описание = "Введите название заводимой заявки",
  значение = "Введите",
  обязательное = true
) +
добавитьПолеВФормуОператора(
  форма = "Заведение заявки в Jira",
  переменная = "t3",
  название = "Критичность",
  тип = "Выпадающий список",
  описание = "Выберите из списка критичность заявки",
  обязательное = true,
  значение = "v3", 
  варианты = "{priority}"
) +
добавитьПолеВФормуОператора(
  форма = "Заведение заявки в Jira",
  переменная = "t4",
  название = "Описание",
  тип = "Многострочный редактируемый текст",
  описание = "Опишите вашу проблему",
  обязательное = true
) +
добавитьПолеВФормуОператора(
  форма = "Заведение заявки в Jira",
  переменная = "t5",
  название = "Уведомить руководителя?",
  тип = "Переключатель",
  обязательное = false
) +
установитьПеременную("tags", "{\"v1\": \"Teacher\", \"v2\": \"Student\", \"v3\": \"Sales\", \"v4\": \"Tech\"}") +
добавитьПолеВФормуОператора(
  форма = "Заведение заявки в Jira",
  переменная = "t6",
  название = "Теги",
  тип = "Множественный выбор",
  описание = "Выберите теги, которыми пометить обращение",
  варианты = "{tags}",
  обязательное = true
) +
добавитьПолеВФормуОператора(
  форма = "Заведение заявки в Jira",
  переменная = "t7",
  тип = "Целое число",
  название = "Частота возникновения проблемы",
  описание = "% пользователей, у которых возникает проблема" 
) +
показатьФормуОператору(имя = "Заведение заявки в Jira") +
комментарий("Вот что у нас получилось: {t2}, {t3}, {t4}")+
комментарий("Конец сценария интеграции!")


  • No labels