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 25 Next »

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

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

Короткий опрос пользователя и возврат ответов

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

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

 Нажмите здесь, чтобы развернуть пример сценария
//
// Сценарий простой переписки с пользователем
//
// Приветственное сообщение и первый вопрос
сообщениеПользователю.сШаблоном("Добрый день! Сейчас я помогу!") +
задатьПользователюВопрос("Я правильно понял, что вы заблудились в лесу?").сВариантамиОтвета("Да", "Нет").сохранитьРезультат("answer_1")+
//
// Если пользователь выберет нет - сценарий завершается
если("{answer_1} == Нет").то(
    сообщениеПользователю.сШаблоном("Ок, тогда я отключаюсь. Всего хорошего!") +
    завершить
)+
//
// Сообщения пользователю и начало опроса
сообщениеПользователю.сШаблоном("Если вы заблудились в лесу - главное сохранять спокойствие!") +
сообщениеПользователю.сШаблоном("Ваша главная задача - решить куда идти и выйти из леса.") +
задатьПользователюВопрос("Посмотрите вокруг - вы видите деревья?").сВариантамиОтвета("Да", "Нет").сохранитьРезультат("answer_2")+
//
// Пользователь ответил Нет - сценарий возвращает сообщение для этого случая и завершается 
если("{answer_2} == Нет").то(
    сообщениеПользователю.сШаблоном("Поздравляю! Вы не в лесу. Проблема решена. Всего хорошего") +
    завершить
)+
//
// Пользователь ответил Да - сценарий продолжает передавать сообщения пользователю
сообщениеПользователю.сШаблоном("Посмотрите на мох на стволах деревьев. Мох зеленый, зеленый цвет успокаивает.") +
сообщениеПользователю.сШаблоном("Обратите внимание на какой стороне дерева чаще всего встречается мох - это направление на север.") +
сообщениеПользователю.сШаблоном("Теперь важно вспомнить как вы пришли сюда и идти обратно.") +
задатьПользователюВопрос("Вы можете вспомнить откуда пришли?").сВариантамиОтвета("Да","Нет").сохранитьРезультат("answer_3") +
//
// Пользователь ответил Нет - сценарий возвращает сообщение для этого случая и завершается
если("{answer_3} == Нет").то(
    сообщениеПользователю.сШаблоном("Тогда вам все равно куда идти. Идите на север, ориентируясь на мох. Всего хорошего и удачи!") +
    завершить  
) + 
//
// Пользователь выбрал вариант Да - сценарий возвращает сообщение для этого случая и завершается
сообщениеПользователю.сШаблоном("Отлично! Идите обратно. Всего хорошего и удачи!") +
завершить

Короткий опрос пользователя и передача запроса операторам

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

 Нажмите здесь, чтобы развернуть пример сценария
//
// Сценарий первичного анкетирования и передачи запроса операторам
//
// Начинается опрос
задатьПользователюВопрос("Уточните, пожалуйста, что для Вас является приоритетным?").сВариантамиОтвета("Получение максимальной суммы","Простота получения").сохранитьРезультат("UserSaid_Priority")+
задатьПользователюВопрос("Укажите, на какие цели предназначается займ?").сохранитьРезультат("UserSaid_Priority_2")+
сообщениеПользователю.сШаблоном("Пожалуйста не закрывайте окно чата оператор подберет для Вас наиболее выгодное предложение!")+
//
// завершаем сценарий и передаем диалог операторам
завершитьИПеревестиНаОператора

Анкетирование пользователя и сохранение результатов в профиле пользователя

Сценарий проверит данные в профиле пользователя по списку и попросит пользователя указать отсутствующие данные. Список переменных указывается в самом сценарии. Для каждого вопроса предусмотрена кнопка Пропустить, нажатие пользователя на эту кнопку фиксируется в переменной пользователя как символ -.

 Нажмите здесь, чтобы развернуть пример сценария
//
// Сценарий заполнения данных пользователя
//
установитьПеременную("enteredEmail", "") +
установитьПеременную("enteredPhone", "") +
установитьПеременную("enteredFIO", "") +
установитьПеременную("enteredTall", "") +
установитьПеременную("enteredRegion", "") +
установитьПеременную("enteredLink", "") +
установитьПеременную("enteredCheck", "") +
//
// Опрос
если("{userFullName} == ").то(
	задатьПользователюВопрос("Укажите как вас зовут").сВариантамиОтвета("Пропустить").сохранитьРезультат("enteredFIO") 	
) +
если("{userEmail} == ").то(
	задатьПользователюВопрос("Укажите адрес вашей электронной почты").сВариантамиОтвета("Пропустить").сохранитьРезультат("enteredEmail") 	
) +
если("{userPhone} == ").то(
	задатьПользователюВопрос("Укажите номер вашего телефона").сВариантамиОтвета("Пропустить").сохранитьРезультат("enteredPhone") 	
) +
если("{userPayload.рост} == ").то(
	задатьПользователюВопрос("Укажите ваш рост").сВариантамиОтвета("Пропустить").сохранитьРезультат("enteredTall") 	
) +
если("{userPayload.регион} == ").то(
	задатьПользователюВопрос("Укажите ваш город").сВариантамиОтвета("Пропустить").сохранитьРезультат("enteredRegion") 	
) +
если("{userPayload.ссылка} == ").то(
	задатьПользователюВопрос("Укажите ссылку на ваш профиль").сВариантамиОтвета("Пропустить").сохранитьРезультат("enteredLink") 	
) +
//
// Замена нажатой кнопки Пропустить на символ -
если("{enteredFIO} == Пропустить").то(
	установитьПеременную("enteredFIO", "-")
) +
если("{enteredEmail} == Пропустить").то(
	установитьПеременную("enteredEmail", "-")
) +
если("{enteredPhone} == Пропустить").то(
	установитьПеременную("enteredPhone", "-")
) +
если("{enteredTall} == Пропустить").то(
	установитьПеременную("enteredTall", "-")
) +
если("{enteredRegion} == Пропустить").то(
	установитьПеременную("enteredRegion", "-")
) +
если("{enteredLink} == Пропустить").то(
	установитьПеременную("enteredLink", "-")
) +
//
// Проверка данных и сохранение тех переменных пользователя для которых в опросе были указаны данные
если("{enteredFIO} != ").то(
	установитьПеременнуюПользователю("userFullName", "{enteredFIO}") +
	установитьПеременную("enteredCheck", "1")
) +
если("{enteredEmail} != ").то(
	установитьПеременнуюПользователю("userEmail", "{enteredEmail}") +
	установитьПеременную("enteredCheck", "1")
) +
если("{enteredPhone} != ").то(
	установитьПеременнуюПользователю("userPhone", "{enteredPhone}") +
	установитьПеременную("enteredCheck", "1")
) +
если("{enteredTall} != ").то(
	установитьПеременнуюПользователю("userPayload.рост", "{enteredTall}") +
	установитьПеременную("enteredCheck", "1")
) +
если("{enteredRegion} != ").то(
	установитьПеременнуюПользователю("userPayload.регион", "{enteredRegion}") +
	установитьПеременную("enteredCheck", "1")
) +
если("{enteredLink} != ").то(
	установитьПеременнуюПользователю("userPayload.ссылка", "{enteredLink}") +
	установитьПеременную("enteredCheck", "1")
) +
//
// Если хоть одно значение было указано сценарий сообщит со сохранении данных
если("{enteredCheck} == 1").то(
	сообщениеПользователю.сШаблоном("Спасибо. Все записал.")
) + 
//
завершить

Опрос пользователя и получение ответа из Confluence

Сценарий уточняет вопрос у пользователя и в зависимости от выбора пользователя возвращает в ответ одну из двух статей из Confluence.

Токен для обращения сервиса в Confluence следует получать у администраторов Confluence или по документации.

 Click here to expand...
//
// Сценарий получения ответа из статьи Confluence
//
// Настройки сценария
//
// Укажите адрес установки Confluence
установитьПеременную("confluense_host", "https://ХХХХХХХХХ.atlassian.net/") +
// URL для запросов получения контента статей
установитьПеременную("confluense_url", "wiki/rest/api/content/") +
// Укажите токен для API запросов в Confluence 
установитьПеременную("confluense_token", "ХХХХХХХХХХХХХХХХХ")+
//
// Основной код сценария
//
// Приветственное сообщение и первый вопрос
сообщениеПользователю.сШаблоном("Добрый день! Сейчас я помогу!") +
задатьПользователюВопрос("Подскажите, описание какого релиза вас интересует?").сВариантамиОтвета("5.0.4", "5.0.5").сохранитьРезультат("answer_1")+
//
если("{answer_1} == 5.0.4").то(
	установитьПеременную("article", "3154706435")
) +
если("{answer_1} == 5.0.5").то(
	установитьПеременную("article", "3160571905") 
) +
//
// 
вызвать.внешнийСервис("{confluense_host}{confluense_url}{article}", "GET").сПараметрами(("expand", "body.storage")).сЗаголовками(("Content-Type", "application/json"),("charset", "utf-8"),("Authorization", "{confluense_token}")).сохранитьРезультат(("body.storage.value","body"))+
//
// Проверка результатов запроса, в случае ошибки сценарий сообщит об ошибке и завершится 
если("{http_code} > 210").то(
	комментарий("Сценарий не смог получить данные. {http_code}")+
	сообщениеПользователю.сШаблоном("Что-то сломалось и я не могу получить для вас ответ.")+
	завершить
)+
//
// 
сообщениеПользователю.сШаблоном("{body}")+
завершить

Стартовые и приветственные сценарии

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

Такие сценарии размещаются в Приветствии или Интеграции на поступление диалога.

Разные приветствия для пользователей разных каналов

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

 Нажмите здесь, чтобы развернуть пример сценария
//
// Сценарий описывает различные приветствия в зависимости от типа и ИД канала
//
если("{channelType} == Telegram").то(
    сообщениеПользователю.сШаблоном("Добро пожаловать в наш Telegram")
)+
если("{channelId} == 2f7ce72f-8003-4e17-b879-e3c71f239149").то(
    сообщениеПользователю.сШаблоном("Здравствуйте!")
)+
//
// Завершение сценария и передача запроса в базы знаний
завершитьСНовымЗапросом("{platformInMessageQuery}")

Сообщение об отсуствии операторов поддержки вне рабочего времени

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

 Нажмите здесь, чтобы развернуть пример сценария

//
// Сценарий сообщает об отсутствии операторов поддержки в ночное время
//
// Настройка сценария
// Смещение текущего времени службы поддержки относительно GMT в часах
установитьПеременную("HourOffset", "3")+
// время начала работы службы поддержки
установитьПеременную("startHour", "9")+
// время окончания работы службы поддержки (не включая)
установитьПеременную("endHour", "22") +
//
// Основной код сценария
// 
// проверка текущего времени
выполнитьJs("""
var serverTime = new Date();
var serverTimeStamp = serverTime.getTime();
var timeZoneOffset = serverTime.getTimezoneOffset();

var currentTimeStamp = serverTimeStamp + (parseInt(HourOffset) *  3600000) - (timeZoneOffset * 60000);

var currentDate = new Date(currentTimeStamp);
var currentHour = parseInt(currentDate.getHours());

var start = parseInt(startHour);
var stop = parseInt(endHour);

if (currentHour >= start && currentHour < stop) {
	var workTime = 1;
} else {
	var workTime = 0;	
}

var exit = {'workTime':workTime};
exit;
""") +
//
// Сейчас рабочее время, сценарий передает запрос в базы знаний без уведомлений пользователя
если("{workTime} == 1").то(
	комментарий("Рабочее время. Продолжаем штатно") + 
	завершитьСНовымЗапросом("{platformInMessageQuery}")
)+
//
// Сейчас нерабочее время, перед сообщением пользователю сценарий уточняет наличие ответа в базе знаний
запросВБазыЗнаний("{platformInMessageQuery}", "botKnows")+
//
// В базе знаний есть ответ, сценарий уведомляет пользователя об отсутствии операторов и передает запрос в базы знаний
если("{botKnows} == true").то(
	комментарий("Бот знает ответ, продолжаем не взирая на график.") + 
	сообщениеПользователю.сШаблоном("Операторы службы поддержки сейчас не работают, но Вы можете получить консультацию у нашего бота. Операторы смогут подключиться с {startHour}:00 по МСК.")+ 
	завершитьСНовымЗапросом("{platformInMessageQuery}")
)+
//
// В базе знаний нет ответа, сценарий сообщает об отсутствии операторов службы поддержки, завершается и закрывает диалог
комментарий("Бот не понял. Операторы не работают")+
сообщениеПользователю.сШаблоном("Сейчас служба поддержки не работает. Просим писать нам с {startHour}:00 по {endHour}:00 МСК.<br>Unfortunately you contacted us outside of our support service hours. We will reply to you in the morning. Thank you for waiting.")+
завершитьИЗакрытьДиалог()

Меню наиболее частых запросов

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

Если пользователь вместо выбора варианта напишет свой запрос, то сценарий передаст его в базы знаний.

 Нажмите здесь, чтобы развернуть пример сценария
//
// Сценарий проверяет наличие ответа и если ответа нет то предлагает пользователю меню запросов
// 
// Проверка наличия ответа на запрос в базах знаний
запросВБазыЗнаний("{platformInMessageQuery}", "botKnows")+
//
// В базе знаний есть ответ, сценарий передает запрос в базу знаний
если("{botKnows} == true").то(	
	завершитьСНовымЗапросом("{platformInMessageQuery}")
)+
//
// В базе знаний нет прямого ответа на запрос, сценарий предлагает выбрать из готовых вариантов
задатьПользователюВопрос("Здравствуйте 😊<br>Что Вас интересует?").сВариантамиОтвета("Первое","Второе","Компот").сохранитьРезультат("userChoice")+
//
// Если пользователь выбрал первый вариант, то сценарий передает запрос "Первые блюда" в базу знаний
если("{userChoice} == Первое").то(
	завершитьСНовымЗапросом("Первые блюда")
)+
//
// Если пользователь выбрал второй вариант, то сценарий передает запрос "Вторые блюда" в базу знаний
если("{userChoice} == Второе").то(
	завершитьСНовымЗапросом("Вторые блюда")
)+
//
// Если пользователь выбрал третий вариант, то сценарий отправляет ответ и завершается
если("{userChoice} == Компот").то(
	сообщениеПользователю.сШаблоном("Закончился. Всего хорошего!") +
	завершить
)+
//
// Если пользователь не выбирал вариантов а написал другой запрос, то он передается в базы знаний
завершитьСНовымЗапросом("{userChoice}")

Создание тегов к диалогу

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

Переменные диалога могут применяться для сохранения данных относящихся к отдельному диалогу - тегирования, сохранения комментарием или выбору тематик.

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

 Нажмите здесь, чтобы развернуть пример сценария
//
// Сценарий создает переменные диалога 
//
// Настройки сценария
//
// Сценарий описывает варианты для одноуровневого списка приоритетов
установитьПеременную("priorities_list","""{"1": "Критичный", "2": "Срочный", "3": "Средний", "4": "Низкий"}""") +
//
// Сценарий описывает варианты многоуровневневого списка тематик через JS код
выполнитьJs("""
var network = [{"label":"Разрыв соединения","value":"11"}, {"label":"Низкая скорость","value":"12"}];
var equipment = [{"label":"Клиентский роутер","value":"21"}, {"label":"Коммутатор","value":"22"},{"label":"Кабели","value":"23"}];
var other = [{"label":"Кривые руки","value":"31"}, {"label":"Проблемы с учетной записью","value":"32"}, {"label":"Проблемы с документацией","value":"33"}];

var topics = {};
topics[JSON.stringify(network)] = 'Сетевые проблемы';
topics[JSON.stringify(equipment)] = 'Проблемы с оборудованием';
topics[JSON.stringify(other)] = 'Прочие проблемы';

var exit = {'topics': JSON.stringify(topics)};
exit;
""") +
//
// Основной код сценария
//
// Создание переменной выбора приоритета из списка
установитьПеременнуюВДиалог(
    ключ = "1_priority",
    значение = "",
    название = "Выбор срочности",
    редактируемое = true,
    показыватьОператору = true,
    обязательное = true,
    множественныйВыбор = true,
    тип = "Выпадающий список",
    варианты = "{priorities_list}"
)+
//
// Создание переменной выбора сервиса из списка
установитьПеременнуюВДиалог(
    ключ = "2_topicId",
    значение = "",
    название = "Выбор тематики",
    редактируемое = true,
    показыватьОператору = true,
    обязательное = false,
    множественныйВыбор = false,
    тип = "Выпадающий список",
	варианты = "{topics}"
)+
//
// Создание переменной указания адреса
установитьПеременнуюВДиалог(
    ключ = "3_address",
    значение = "",
    название = "Адрес",
    редактируемое = true,
    показыватьОператору = true,
    обязательное = false,
    множественныйВыбор = false,
    тип = "Текст"
)+
//
// Создание переменной указания комментария к заявке
установитьПеременнуюВДиалог(
    ключ = "4_comment",
    значение = "",
    название = "Комментарий к вызову",
    редактируемое = true,
    показыватьОператору = true,
    обязательное = false,
    множественныйВыбор = false,
    тип = "Текст"
)+
завершить

Создание тегов к диалогу и автоматическое предзаполнение полей

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

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

Если классификация проходит с недостаточной уверенностью, то переменная диалога будет пустой.

Сценарий удобен тем, что список вариантов для выбора хранится в отдельной базе знаний и изменять его может любой супервизор сервиса без вмешательства в текст сценария. База знаний может находиться в режиме “Не используется” и применяться только для хранения спсика продуктов. Автоматическая классификация и предзаполнение переменной позволят значительно экономить время оператора на заполнение переменных диалога

 Нажмите здесь, чтобы развернуть пример сценария
//
// Сценарий создает переменные диалога и автоматически предзаполняет часть из них 
// на основе классификации запроса пользователя 
//
// Настройки сценария
//
// Настройки для проведения классификации запроса пользователя
//
// Адрес API ендпойнтов для запросов баз знаний 
установитьПеременную("kb_qna_enpoint", "https://chat.autofaq.ai/core-api/query/api/v1/query") +
установитьПеременную("kb_crud_endpoint", "https://chat.autofaq.ai/core-api/crud/api/v1/services/") +
//
// Укажите токен для запроса в базу знаний, брать из поля "user token" в разделе Настройки - Общие - Параметры прямого подключения к базам знаний через API
установитьПеременную("autorizationToken", "ХХХХХХХХХ")+
//
// Укажите ID и токен базы знаний -  классификатора продуктов, брать в настройках базы знаний
установитьПеременную("kb_product_id", "ХХХХ")+
установитьПеременную("kb_product_token", "ХХХХХХХХХХХ")+
//
// Укажите минимальный уровень уверенности ответа для успешной классификации
установитьПеременную("minimumScore", "10") +
//
// Основной код сценарий
//
// Сценарий отправляет запрос на классификацию сообщения пользователя
вызвать.внешнийСервис("{kb_qna_enpoint}","POST").сЗаголовками(("Content-Type", "application/json"),("charset", "utf-8"),("AUTOFAQ-User-Token", "{autorizationToken}")).сТеломСообщения("""{"service_token":"{kb_product_token}","service_id":"{kb_product_id}","query":"{platformInMessageQuery}"}""").сохранитьРезультатКакСтроку("answer")+
//
// Проверка резльтатов запрос, если запрос завершился с ошибкой сценарий оставляет комментарий для администратора сервиса 
если("{http_code} != 200").то(  
  комментарий("При запросе на классификацию возникла ошибка {http_code}, текст ошибки {answer}")
)+
//
// Разбор ответа от классификатора, если результаты классификации содержат результат с уверенностью выше установленной, то сценарий вернет название этого документа
выполнитьJs("""
var docName = '';
var docId = '';
var docScore = 0.0;

try {
    var answerParsed = JSON.parse(answer);
} catch(err) {    
    var answerParsed = {};
}

if (answerParsed.hasOwnProperty('results') && answerParsed.results.length > 0)  {
    if (Math.floor(answerParsed.results[0].score * 100) > minimumScore) {
        docName = answerParsed.results[0]['name'];
        docId = answerParsed.results[0]['document_id'].toString();
        docScore = answerParsed.results[0]['score'];
    }
}
var exit = {'docName':docName, 'docId':docId, 'docScore':docScore};
exit;
""")+
//
// Сценарий оставляет комментарий с результатами классификации для администратора сервиса
комментарий("Результаты классификации: определен документ {docName} с уверенностью {docScore}")+
//
// Сценарий получает полный список документов из базы знаний - классификатора для отображения в переменной диалога
вызвать.внешнийСервис("{kb_crud_endpoint}{kb_product_id}","GET").сЗаголовками(("Content-Type", "application/json"),("charset", "utf-8"),("AUTOFAQ-User-Token", "{autorizationToken}")).сПараметрами(("include_documents","1")).сохранитьРезультатКакСтроку("answerDocs")+
//
// Проверка резльтатов запрос, если запрос завершился с ошибкой сценарий оставляет комментарий для администратора сервиса 
если("{http_code} != 200").то(
  // добавление комментария в диалог и завершение сценария
  комментарий("При запросе на получение списка документов возникла ошибка {http_code}, текст ошибки {answerDocs}")
)+
//
// Разбор ответа из базы знаний, сценарий на выходе сохранит список документов в формате "ID документа" - "Название документа" 
выполнитьJs("""
try {
    var answerParsed = JSON.parse(answerDocs);
} catch(err) {    
    var answerParsed = {};
}

var docs = {};

if (answerParsed.hasOwnProperty('documents') && answerParsed.documents.length > 0) {
    for (var i = 0; i < answerParsed.documents.length; i++)  {
        docs[answerParsed.documents[i].document_id] = answerParsed.documents[i].name;    
    } 
}
var exit = {'docs':JSON.stringify(docs)};
exit;
""") +
//
// Сценарий создает переменню диалога для выбора продукта и предзаполняет его
установитьПеременнуюВДиалог(
    ключ = "service",
    значение = "{docId}",
    название = "Выберите продукт",
    редактируемое = true,
    показыватьОператору = true,
    обязательное = true,
    множественныйВыбор = false,
    тип = "Выпадающий список",
    варианты = "{docs}"
)+
завершить

Автоматическое определение группы

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

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

 Нажмите здесь, чтобы развернуть пример сценария
//
// Сценарий автоматически определяет группу по тексту запроса пользователя  
// актуально при подключении пользовательского канала одновременно к нескольким группам
// в этом случае АФ не будет запрашивать выбор группы у пользователя 
//
// Настройки сценария
//
// Настройки для проведения классификации запроса пользователя
//
// Адрес API ендпойнтов для запросов баз знаний 
установитьПеременную("kb_qna_enpoint", "https://chat.autofaq.ai/core-api/query/api/v1/query/batch") +
//
// Укажите токен для запроса в базы знаний, брать из поля "user token" в разделе Настройки - Общие - Параметры прямого подключения к базам знаний через API
установитьПеременную("autorizationToken", "ХХХХХХХХХХХХХ")+
//
// Укажите количество групп
установитьПеременную("groups_amount", "3")+
//
// Укажите ID и токены баз знаний групп - по паре переменных на каждую группу по аналогии
// Данные первой группы 
установитьПеременную("kb_ids_1", "ХХХХ")+
установитьПеременную("kb_tokens_1", "ХХХХХХХХХХХХХХ")+
// Данные второй группы
установитьПеременную("kb_ids_2", "ХХХХ, ХХХХ")+
установитьПеременную("kb_tokens_2", "ХХХХХХХХХХХХХ, ХХХХХХХХХХХХ")+
// Данные третей группы
установитьПеременную("kb_ids_3", "ХХХХ")+
установитьПеременную("kb_tokens_3", "ХХХХХХХХХХХХХХХХХ")+
//
// Сценарий сохраняет текст запроса для отправки в базы знаний
установитьПеременную("queryText", "{platformInMessageQuery}")+
//
выполнитьJs("""
var g_num = Number(groups_amount);
var kb_ids = {};
kb_ids[0] = kb_ids_1.split(',').map(function(item) {return item.trim();});
kb_ids[1] = kb_ids_2.split(',').map(function(item) {return item.trim();});
kb_ids[2] = kb_ids_3.split(',').map(function(item) {return item.trim();});

var kb_tokens = {};
kb_tokens[0] = kb_tokens_1.split(',').map(function(item) {return item.trim();});
kb_tokens[1] = kb_tokens_2.split(',').map(function(item) {return item.trim();});
kb_tokens[2] = kb_tokens_3.split(',').map(function(item) {return item.trim();});

var exit = {};
for (var i = 0; i < g_num; i++) {
    var query_temp = [];
    for (var j = 0; j < kb_ids[i].length; j++) {
        var q = {'service_id':Number(kb_ids[i][j]),'service_token':kb_tokens[i][j],'query':queryText,'top_k':1};
        var z = query_temp.push(q);
    }
    var qq = 'query_text_' + (i+1).toString();
    exit[qq] = JSON.stringify(query_temp);
}
exit;
""")+
//
// Сценарий отправляет запросы на классификацию сообщения пользователя в базы знаний группы 1
вызвать.внешнийСервис("{kb_qna_enpoint}","POST").сЗаголовками(("Content-Type", "application/json"),("charset", "utf-8"),("AUTOFAQ-User-Token", "{autorizationToken}")).сТеломСообщения("{query_text_1}").сохранитьРезультатКакСтроку("answer_1")+
// Проверка резльтатов запрос, если запрос завершился с ошибкой сценарий оставляет комментарий для администратора сервиса 
если("{http_code} != 200").то(  
  комментарий("При запросе на классификацию возникла ошибка {http_code}, текст ошибки {answer_1}")
)+
//
// Сценарий отправляет запросы на классификацию сообщения пользователя в базы знаний группы 2
вызвать.внешнийСервис("{kb_qna_enpoint}","POST").сЗаголовками(("Content-Type", "application/json"),("charset", "utf-8"),("AUTOFAQ-User-Token", "{autorizationToken}")).сТеломСообщения("{query_text_2}").сохранитьРезультатКакСтроку("answer_2")+
// Проверка резльтатов запрос, если запрос завершился с ошибкой сценарий оставляет комментарий для администратора сервиса 
если("{http_code} != 200").то(  
  комментарий("При запросе на классификацию возникла ошибка {http_code}, текст ошибки {answer_2}")
)+
//
// Сценарий отправляет запросы на классификацию сообщения пользователя в базы знаний группы 3
вызвать.внешнийСервис("{kb_qna_enpoint}","POST").сЗаголовками(("Content-Type", "application/json"),("charset", "utf-8"),("AUTOFAQ-User-Token", "{autorizationToken}")).сТеломСообщения("{query_text_3}").сохранитьРезультатКакСтроку("answer_3")+
// Проверка резльтатов запрос, если запрос завершился с ошибкой сценарий оставляет комментарий для администратора сервиса 
если("{http_code} != 200").то(  
  комментарий("При запросе на классификацию возникла ошибка {http_code}, текст ошибки {answer_3}")
)+
//
// Разбор ответов
выполнитьJs("""
var answers = {};
var results = {};
var res = 0.0;

try {
    answers[0] = JSON.parse(answer_1);
    answers[1] = JSON.parse(answer_2);
    answers[2] = JSON.parse(answer_3);
} catch(err) {
    answers[0] = [];
    answers[1] = [];
    answers[2] = [];
}
var keys = Object.keys(answers);
for (var i = 0; i < keys.length; i++) {
    res = 0.0;

    for (var j = 0; j < answers[i].length; j++) {
        if (answers[i][j].hasOwnProperty('results') && answers[i][j].results.length > 0) {
            if (answers[i][j].results[0].score > res) {
                res = answers[i][j].results[0].score;
            }
        }
    }
    results[i] = res;
}
var k = Object.keys(results).reduce(function(a, b){ return results[a] > results[b] ? a : b });
try {
    var group = Number(k) + 1;
} catch(err) {
    var group = 0;
}
var exit = {'group':JSON.stringify(group)};
exit;
""")+
//
// Сценарий определил группу, ответ из баз знаний которой пришел с максимальной уверенностью и переводит запрос на эту группу
комментарий("Определил группу номер {group}")+
если("{group} == 1").то(
    комментарий("Перевожу чат на группу Вторая линия HR")+
    перевестиНаГруппу("ХХХХХ-ХХХХ-ХХХХ-ХХХХ-ХХХХХ").иЗавершить
)+
если("{group} == 2").то(
    комментарий("Перевожу чат на группу Первая линия")+
    перевестиНаГруппу("ХХХХХ-ХХХХ-ХХХХ-ХХХХ-ХХХХХ").иЗавершить
)+
если("{group} == 3").то(
    комментарий("Перевожу чат на группу Вторая линия IT")+
    перевестиНаГруппу("ХХХХХ-ХХХХ-ХХХХ-ХХХХ-ХХХХХ").иЗавершить
)+
//
// Сценарий не смог определить группу и переводит запрос на группу по-умолчанию
комментарий("Перевожу чат на группу по-умолчанию")+
перевестиНаГруппу("ХХХХХ-ХХХХ-ХХХХ-ХХХХ-м").иЗавершить

Аутентификация пользователей

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

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

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

 Нажмите здесь, чтобы развернуть пример сценария
//
// Приветственный сценарий с авторизацией пользователя и отправкой проверочного кода на почту
//
// Настройки сценария
// Укажите адреса для API вызовов  
установитьПеременную("get_user_url", "https://itsm.company.ru/api/v1/getUser")+
установитьПеременную("post_url", "http://porter/api/postman/mail")+
//
// Укажите API ключ для запросов на получение данных о пользователях
установитьПеременную("apikey", "ХХХХХХХХХ==")+
//
// Сценарий считывает табельный номер из профиля пользователя
установитьПеременную("user_tabNumber", "{userPayload.tabNumber}") +
//
// Если табельный номер проставлен, то сценарий сразу передает запрос в базы знаний без процедуры аутентификации
// В дальнейшем сбда можно вставить проверку времени действия аутентификации или проверку на увольнение сотрудника
если("{user_tabNumber} != ").то(
  завершитьСНовымЗапросом("{platformInMessageQuery}")
)+
//
// Приветственное сообщение для неавторизованных пользователей
сообщениеПользователю.сШаблоном("Привет, я - бот-помощник. Для работы с ботом приготовьте, пожалуйста, свой табельный номер и проверьте доступ к рабочей электронной почте.") +
//
// Задаем пользователю вопрос с просьбой ввести табельный номер, для того чтобы использовать его в сервисах для получения данных о пользователе.
задатьПользователюВопрос("Введите свой табельный номер.").сохранитьРезультат("entered_tabNumber") +
//
// Запрос в ITSM систему на получение данных о пользователе по табельному номеру
вызвать.внешнийСервис("{get_user_url}","GET").сПараметрами(("tabNumber","{entered_tabNumber}")).сЗаголовками(("Content-Type", "application/json"),("apikey","{apikey}")).сохранитьРезультатКакСтроку("answer") +
//
// Проверка результатов запроса, в случае ошибки сценарий сообщит об ошибке, завершится и закроет диалог
если("{http_code} > 200").то(  
    комментарий("При запросе на поиск пользователя возникла ошибка {http_code}, текст ошибки {answer}")+
    сообщениеПользователю.сШаблоном("При поиске учетной записи возникла ошибка {http_code}. Обратитесь в техническую поддержку.")+ 
    завершитьИЗакрытьДиалог()  
  )+
//
// Разбор ответа от ITSM системы, получение адреса электронной почты пользователя и генерация проверочного кода
// В дальнейшем можно добавить получение и сохранение данных пользователя помимо электронной почты
выполнитьJs("""
var error = 0;
var user_email = '';

try {
    var answerParced = JSON.parse(answer);
} catch(err) {    
    var answerParced = {};
}  

if (answerParced.hasOwnProperty('email')) {
  user_email = answerParced.email;
  var splited = user_email.split('@');
  
  var firstPart = splited[0];
  if (firstPart.length > 4) {
    var tempString = firstPart.slice(2,firstPart.length-2);
    var draftString = '***************************************'.slice(0,tempString.length);
    var firstPartString = firstPart.slice(0,2) + draftString + firstPart.slice(firstPart.length-2,firstPart.length);
  }   

  if (firstPart.length == 4) {var firstPartString = firstPart.slice(0,1) + '**';}
  if (firstPart.length == 3) {var firstPartString = firstPart.slice(0,1) + '*';}
  if (firstPart.length == 2) {var firstPartString = firstPart[0] + '*';}
  if (firstPart.length < 2) {var firstPartString =  '*';}

  var res = firstPartString+'@'+splited[1];

  var pass_code = Math.floor(Math.random() * (9999 - 1000 + 1) + 1000);
} else {
  error = 1;
}
    
var exit = {'error':error, 'user_email':user_email, 'user_email_hidden':res, 'pass_code':pass_code};
exit;
""") +
//
// Если при разборе ответа от ITSM системы возникли ошибки, то сценарий сообщит пользователю, завершится и закроет диалог
если("{error} == 1").то(
  комментарий("При разборе ответа возникла ошибка, текст ответа {answer}")+
  сообщениеПользователю.сШаблоном("При поиске учетной записи возникла ошибка. Обратитесь в техническую поддержку.")+ 
  завершитьИЗакрытьДиалог()
) +
//
// Сценарий отправляет письмо с кодом на адрес полученный из ITSM системы
вызвать.внешнийСервис("{post_url}","POST").сЗаголовками(("Content-Type", "application/json")).сТеломСообщения("""{"to": "{user_email}","from":"no-reply@autofaq.ai", "subject":"Подключение к боту","body":"Кто-то пытается подключиться к боту используя ваш табельный номер. Если это сделали не Вы, то обратитесь пожалуйста в службу технической поддержки. Если это вы, то введите этот секретный код {pass_code}. <br>Внимание! Никому не сообщайте этот код!"}""").сохранитьРезультатКакСтроку("answer_email") +
//
// Проверка результатов запроса, в случае ошибки сценарий сообщит об ошибке, завершится и закроет диалог
если("{http_code} > 200").то(  
    комментарий("При отправке письма с проверочным кодом возникла ошибка {http_code}, текст ошибки {answer_email}")+
    сообщениеПользователю.сШаблоном("При отправке письма с проверочным кодом возникла ошибка {http_code}. Пожалуйста, попробуйте подключиться к боту позднее.")+ 
    завершитьИЗакрытьДиалог()  
)+
//
// Сценарий выводит отправленный пользователю пароль и адрес почты в комментарий диалога для администратора сервиса
комментарий("Пользователю на адрес {user_email} был отправлен код {pass_code}")+
//
// Метка для повторного ввода кода
установитьМетку("point_password_enter") +
//
// Сценарий просит пользователя ввести секретный код
задатьПользователюВопрос("На вашу электронную почту {user_email_hidden} был отправлен код. Пожалуйста введите его").сохранитьРезультат("entered_pass_code") +
//
// ПЕрвая проверка корректности введенного кода, если код введен неверно то сценарий переход на метку для повторного ввода, но не более 3 раз
если("{entered_pass_code} != {pass_code}").то(
  сообщениеПользователю.сШаблоном("Вы ввели неверный код. Попробуйте ввести еще раз. Максимальное число попыток - 3.")+  
  перейтиНаМетку("point_password_enter").неБольше(3)
) +
//
// Финальная проверка корректности кода, если на этом этапе код указан неверно, то сценарий сообщит об ошибке, завершится и закроет диалог
если("{entered_pass_code} != {pass_code}").то(
  сообщениеПользователю.сШаблоном("Вы три раза ввели неверный код. Обратитесь в техническую поддержку.")+  
  завершитьИЗакрытьДиалог() 
) +
//
// В случае успешного ввода кода сценарий сохраняет адрес электронной почты и табельный номер в профиле пользователя
установитьПеременнуюПользователю("userPayload.tabNumber", "{entered_tabNumber}") +
установитьПеременнуюПользователю("userEmail", "{user_email}") +
сообщениеПользователю.сШаблоном("Вы успешно подключились к боту.") +
// 
// Проверка наличия ответа на запрос пользователя в базах знаний
запросВБазыЗнаний("{platformInMessageQuery}", "botKnows")+
//
// В базах знаний есть прямой ответ, сценарий передает запрос в базы знаний
если("{botKnows} == true").то(  
  завершитьСНовымЗапросом("{platformInMessageQuery}")
)+
//
// В базах знаний нет прямого ответа на запрос пользователя, сценарий предоставляет выбор основных вариантов действий - пользователь может выбрать один из вариантов или написать запрос еще раз
задатьПользователюВопрос("Не совсем поняла, чем помочь. Вот основные варианты действий - выбери вариант или напиши свой запрос иначе.").сВариантамиОтвета("Создать заявку","Посмотреть список заявок").сохранитьРезультат("userChoice") +
//
// Сценарий передает выбор пользователя в базы знаний и завершается
завершитьСНовымЗапросом("{userChoice}")

Работа с API вызовами

Создание инцидента в ITSM системе через REST API

Классификация запроса и создание инцидента в ITSM системе через REST API

Регистрация запроса в CRM системе через REST API

Получение списка открытых инцидентов

Создание инцидента в ITSM системе через SOAP вызов

Получение данных через SQL запрос

Сценарии вызываемые операторами

Работа с таблицами Google Sheets

Простой поиск в таблице

Сценарий запрашивает у пользователя данные для поиска, ищет указанный текст по всем строкам и колонкам таблицы и сообщает о результатах поиска в формате “Да” или “Нет”

 Нажмите здесь, чтобы развернуть пример сценария
//
// Сценарий ищет текст в таблице Google Sheets по значению в любой колонке и возвращает сообщение "Да" если текст найден или "Нет" если не найден
//
// Укажите логин сервисного аккаунта Google
установитьПеременную("email", "autofaqaccount@autofaqproject.iam.gserviceaccount.com") +
// Укажите идентификатор таблицы Google Sheet
установитьПеременную("sheetId", "1UyTG1ag6kb-tKCD0Wc5nD21zE38TvYSiMMQ_vzwxWbs")+
// Укажите название листа в таблице Google Sheet
установитьПеременную("sheetName", "Sheet1")+
//
// Настройка источника текста для поиска - спросить у пользователя или взять текст изначального запроса
// запрос - изначальный запрос
// вопрос - спросить у пользователя
установитьПеременную("querySource", "вопрос")+
//
// Основной код сценария 
//
// Получение текста для поиска в таблице
если("{querySource} == запрос").то(
	установитьПеременную("searchQuery", "{platformInMessageQuery}")
)+
если("{querySource} == вопрос").то(
	задатьПользователюВопрос("Скажи номер").сохранитьРезультат("searchQuery")
)+
//
// Получение временного токена для работы с гугл таблицей
вызвать.внешнийСервис("https://denisk.autofaq.ai/gtoken","GET").сЗаголовками(("Content-Type", "application/json"),("charset", "utf-8")).сПараметрами(("email","{email}")).сохранитьРезультат(("message","message"),("token","token"),("status","status"))+
//
// Проверка результатов запроса, в случае ошибки сценарий сообщит об ошибке и завершится 
если("{http_code} > 210").то(
	комментарий("Сценарий не смог получить токен для работы с таблицей. {message}")+
	сообщениеПользователю.сШаблоном("Спасибо за участие, но что-то сломалось и я не могу связаться с Гугл.")+
	завершить
)+
если("{status} == error").то(
	комментарий("Сценарий не смог получить токен для работы с таблицей. {message}")+
	сообщениеПользователю.сШаблоном("Спасибо за опрос, но что-то сломалось и я не смог сохранить результаты.")+
	завершить
)+
//
// Отправка данных в гугл таблицу
вызвать.внешнийСервис("https://sheets.googleapis.com/v4/spreadsheets/{sheetId}/values/{sheetName}","GET").сЗаголовками(("Authorization", "Bearer {token}"),("Content-Type","application/json")).сПараметрами(("majorDimension", "COLUMNS")).сохранитьРезультатКакСтроку("result")+
если("{http_code} > 210").то(
	комментарий("Сценарий не смог отправить запрос на поиск в гугл таблице. Код {http_code}, ответ {result}")+
	сообщениеПользователю.сШаблоном("Спасибо за участие, но что-то сломалось и я не могу связаться с Google.")+
	завершить
)+
//
// Разбор ответа от гугл таблицы
выполнитьJs("""
var error = 0;
var message = '';
var rowIndex = 0;

try {
    var parsedresult = JSON.parse(result);
} catch(err) {
    var exit = {'error': 1, 'message':'Ошибка разбора ответа от Гугл'};
    var parsedresult = {};
}

if (parsedresult.hasOwnProperty('values')) {

    for (var i = 0; i < parsedresult.values.length; i++) {
        rowIndex = rowIndex + (parsedresult.values[i].indexOf(searchQuery) > -1 ? 1 : 0);
    }

    if (rowIndex > 0) { 
        var exit = {'error': 0, 'message':'Да'};
    } else {
        var exit = {'error': 0, 'message':'Нет'};
    }

} else {
    var exit = {'error': 1, 'message':'В ответе из таблицы не найдено данных'};
}

exit;
""") +
//
// В случае ошибки при поиске данных сценарий сообщит об ошибке и завершится
если("{error} == 1").то(
    сообщениеПользователю.сШаблоном("При получении данных из таблицы возникла ошибка. {message}")+
    завершить
) +
//
// Если при поиске данных ошибки не возникло, то сценарий сообщит о результате поиска и завершится 
сообщениеПользователю.сШаблоном("{message}")+
завершить

Поиск в таблице и возврашение всех данных из строки с заголовками

Сценарий запрашивает у пользователя данные для поиска, ищет указанный текст в первой колонке и возвращает данные из всей строки в формате “Заголовок колонки”: “Значение в строке”

 Нажмите здесь, чтобы развернуть пример сценария
//
// Сценарий ищет строку в таблице Google Sheets по значению в первой колонке и возвращает данные из всей строки
//
// Укажите логин сервисного аккаунта Google
установитьПеременную("email", "account_name@project_name.iam.gserviceaccount.com") +
// Укажите идентификатор таблицы Google Sheet
установитьПеременную("sheetId", "ХХХХХХ-ХХХХХХХХХХХХХ")+
// Укажите название листа в таблице Google Sheet
установитьПеременную("sheetName", "Sheet1")+
//
// Укажите источник текста для поиска - спросить у пользователя или взять текст изначального запроса
// запрос - текст запроса, с которым пользователь пришел в сценария
// вопрос - спросить у пользователя
установитьПеременную("querySource", "вопрос")+
//
// Основной код сценария 
//
// Получение текста для поиска в таблице
если("{querySource} == запрос").то(
	установитьПеременную("searchQuery", "{platformInMessageQuery}")
)+
если("{querySource} == вопрос").то(
	задатьПользователюВопрос("Скажи номер").сохранитьРезультат("searchQuery")
)+
//
// Получение временного токена для работы с гугл таблицей
вызвать.внешнийСервис("https://denisk.autofaq.ai/gtoken","GET").сЗаголовками(("Content-Type", "application/json"),("charset", "utf-8")).сПараметрами(("email","{email}")).сохранитьРезультат(("message","message"),("token","token"),("status","status"))+
//
// Проверка результатов запроса, в случае ошибки сценарий сообщит об ошибке и завершится 
если("{http_code} > 210").то(
	комментарий("Сценарий не смог получить токен для работы с таблицей. {message}")+
	сообщениеПользователю.сШаблоном("Спасибо за участие, но что-то сломалось и я не могу связаться с Гугл.")+
	завершить
)+
если("{status} == error").то(
	комментарий("Сценарий не смог получить токен для работы с таблицей. {message}")+
	сообщениеПользователю.сШаблоном("Спасибо за опрос, но что-то сломалось и я не смог сохранить результаты.")+
	завершить
)+
//
// Отправка запроса в Google Sheets
вызвать.внешнийСервис("https://sheets.googleapis.com/v4/spreadsheets/{sheetId}/values/{sheetName}","GET").сЗаголовками(("Authorization", "Bearer {token}"),("Content-Type","application/json")).сПараметрами(("majorDimension", "COLUMNS")).сохранитьРезультатКакСтроку("result")+
//
// Проверка результатов запроса, в случае ошибки сценарий сообщит об ошибке и завершится
если("{http_code} > 210").то(
	комментарий("Сценарий не смог отправить запрос на поиск в гугл таблице. Код {http_code}, ответ {result}")+
	сообщениеПользователю.сШаблоном("Спасибо за участие, но что-то сломалось и я не могу связаться с Google.")+
	завершить
)+
//
// Разбор ответа от гугл таблицы
выполнитьJs("""
var error = 0;
var message = '';
var rowIndex = 0;

try {
	var parsedresult = JSON.parse(result);
} catch(err) {
	var exit = {'error': 1, 'message':'Ошибка разбора ответа от Гугл'};
	var parsedresult = {};
}

if (parsedresult.hasOwnProperty('values') && parsedresult.values[0].length > 1) {
	var rowIndex = parsedresult.values[0].indexOf(searchQuery);
	
	if (rowIndex > 0) { 
		for (var i = 0; i < parsedresult.values.length; i++) {
			if (parsedresult.values[i].length > rowIndex) {
				message = message + parsedresult.values[i][0].toString() + ': ' + parsedresult.values[i][rowIndex] + '<br>';
			}			
		}
		var exit = {'error': 0, 'message':message};
	} else {
		var exit = {'error': 1, 'message':'Значение не найдено в первой колонке таблицы'};
	}

} else {
	var exit = {'error': 1, 'message':'В ответе из таблицы не найдено данных'};
}

exit;
""") +
//
// В случае ошибки при поиске данных сценарий сообщит об ошибке и завершится
если("{error} == 1").то(
	сообщениеПользователю.сШаблоном("При получении данных из таблицы возникла ошибка. {message}")+
	завершить
) +
//
// Если при поиске данных ошибки не возникло, то сценарий сообщит найденные данные и завершится 
сообщениеПользователю.сШаблоном("Найдены следующие данные")+
сообщениеПользователю.сШаблоном("{message}")+
завершить

Опрос пользователя и запись данных в новую строку таблицы

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

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

 Нажмите здесь, чтобы развернуть пример сценария
//
// Сценарий ищет текст в таблице Google Sheets по значению в любой колонке и возвращает сообщение "Да" если текст найден или "Нет" если не найден
//
// Укажите логин сервисного аккаунта Google
установитьПеременную("email", "account_name@project_name.iam.gserviceaccount.com") +
// Укажите идентификатор таблицы Google Sheet
установитьПеременную("sheetId", "ХХХХХХ-ХХХХХХХХХХХХХ")+
// Укажите название листа в таблице Google Sheet
установитьПеременную("sheetName", "Sheet1")+
//
// Основной код сценария 
//
//
// Получение временного токена для работы с гугл таблицей
вызвать.внешнийСервис("https://denisk.autofaq.ai/gtoken","GET").сЗаголовками(("Content-Type", "application/json"),("charset", "utf-8")).сПараметрами(("email","{email}")).сохранитьРезультат(("message","message"),("token","token"),("status","status"))+
//
// Проверка результатов запроса, в случае ошибки сценарий сообщит об ошибке и завершится 
если("{http_code} > 210").то(
	комментарий("Сценарий не смог получить токен для работы с таблицей. {message}")+
	сообщениеПользователю.сШаблоном("Спасибо за участие, но что-то сломалось и я не могу связаться с Гугл.")+
	завершить
)+
если("{status} == error").то(
	комментарий("Сценарий не смог получить токен для работы с таблицей. {message}")+
	сообщениеПользователю.сШаблоном("Спасибо за опрос, но что-то сломалось и я не смог сохранить результаты.")+
	завершить
)+
//
// Получение адреса электронной почты
установитьПеременную("enteredEmail", "{userEmail}") +
если("{enteredEmail} == ").то(
	задатьПользователюВопрос("Укажите адрес вашей электронной почты").сохранитьРезультат("enteredEmail") +
	установитьПеременнуюПользователю("userEmail", "{enteredEmail}")
) +
//
// Отправка запроса на поиск адреса в гугл таблицу
вызвать.внешнийСервис("https://sheets.googleapis.com/v4/spreadsheets/{sheetId}/values/{sheetName}","GET").сПараметрами(("majorDimension","COLUMNS")).сЗаголовками(("Authorization", "Bearer {token}"),("Content-Type","application/json")).сохранитьРезультатКакСтроку("checkLoginResult") +
//
// Проверка результатов запроса, в случае ошибки сценарий сообщит об ошибке и завершится 
если("{http_code} > 210").то(
	комментарий("Сценарий не смог отправить запрос на поиск в гугл таблице. Код ответа {http_code}, ответ {checkLoginResult}")+
	сообщениеПользователю.сШаблоном("Спасибо за участие, но что-то сломалось и я не могу связаться с центром.")+    
    завершить
)+
выполнитьJs("""
var checkLoginResultParsed = JSON.parse(checkLoginResult);
if ("values" in checkLoginResultParsed) {
	if (checkLoginResultParsed['values'][0].indexOf(userLogin) != -1) {
		var checkLoginResultData = 1;
	} else {
		var checkLoginResultData = 0;
	}
} else {
	var checkLoginResultData = 0;
}
var exit = {'checkLoginResultData':checkLoginResultData};
exit;
""") +
//
// Если адрес почты пользователя найден в таблице то сценарий сообщает об этом пользователю и завершается
если("{checkLoginResultData} == 1").то(
	комментарий("Логин пользователя {userLogin} уже найден в таблице, поэтому опрос останавливаю")+	
	сообщениеПользователю.сШаблоном("Вы уже проходили этот опрос. Второй раз спрашивать нет необходимости")+	
	завершить
)+
//
// Сценарий начинает опрос пользователя
задатьПользователюВопрос("Пожалуйста назовите ваше ФИО").сохранитьРезультат("fio") +
задатьПользователюВопрос("Пожалуйста назовите ваш отдел").сохранитьРезультат("otdel") +
задатьПользователюВопрос("Пожалуйста назовите вашу должность").сохранитьРезультат("dolznost") +
задатьПользователюВопрос("Оцените удобство нашего сервиса").сВариантамиОтвета("Все устраивает", "Возникают трудности", "Комментарий").сохранитьРезультат("udobstvo_main") +
установитьПеременную("udobstvo_add", " ")+
если("{udobstvo_main} == Возникают трудности").то(задатьПользователюВопрос("Какие у вас трудности?").сохранитьРезультат("udobstvo_add")) +
если("{udobstvo_main} == Комментарий").то(задатьПользователюВопрос("Напишите ваш комментарий").сохранитьРезультат("udobstvo_add")) +
// Открытые вопросы
задатьПользователюВопрос("Напишите какие дополнительные сервисы Вы хотели бы видеть").сохранитьРезультат("new_services") +
задатьПользователюВопрос("Напишите Ваши предложения и пожелания").сохранитьРезультат("suggestions") +
// 
выполнитьJs("""
var now = new Date();
var login = enteredEmail;
var udobstvo = udobstvo_main + udobstvo_add;

var requestBody = {"range": sheetName+"!A1:O1", "majorDimension": "ROWS", "values":[[now, login, fio, otdel, dolznost, udobstvo, new_services, suggestions]]};
var requestBodyJSON = JSON.stringify(requestBody);

var exit = {'requestBodyJSON':requestBodyJSON};
exit;
""") +
//
// Получение временного токена для работы с гугл таблицей
вызвать.внешнийСервис("https://denisk.autofaq.ai/gtoken","GET").сЗаголовками(("Content-Type", "application/json"),("charset", "utf-8")).сПараметрами(("email","{email}")).сохранитьРезультат(("message","message"),("token","token"),("status","status"))+
//
// Проверка результатов запроса, в случае ошибки сценарий сообщит об ошибке и завершится 
если("{http_code} > 210").то(
	комментарий("Сценарий не смог получить токен для работы с таблицей. {message}")+
	сообщениеПользователю.сШаблоном("Спасибо за участие, но что-то сломалось и я не могу связаться с центром.")+    
    завершить
)+
если("{status} == error").то(
	комментарий("Сценарий не смог получить токен для работы с таблицей. {message}")+
	сообщениеПользователю.сШаблоном("Спасибо за опрос, но что-то сломалось и я не смог сохранить результаты.")+    
    завершить
)+
//
// Отправка запроса на добавление строки в таблицу
вызвать.внешнийСервис("https://sheets.googleapis.com/v4/spreadsheets/{sheetId}/values/Sheet1!A1:O1:append","POST").сПараметрами(("valueInputOption","USER_ENTERED")).сЗаголовками(("Authorization", "Bearer {token}"),("Content-Type","application/json")).сТеломСообщения("{requestBodyJSON}").сохранитьРезультатКакСтроку("result")+
//
// Проверка результатов запроса, в случае ошибки сценарий сообщит об ошибке и завершится 
если("{http_code} > 210").то(
	комментарий("Сценарий не смог отправить запрос на добавление строчки в гугл таблице. Код ответа {http_code}")+
	сообщениеПользователю.сШаблоном("Спасибо за участие, но что-то сломалось и я не могу связаться с центром.")+    
    завершить
)+
комментарий("Добавил строчку в гугл таблицу.")+
сообщениеПользователю.сШаблоном("Все записал. Большое спасибо за участие!")+
завершить
  • No labels