Перейти к основному содержимому

Как сохранять информацию о пользователе | Викторина | База данных

Потребность

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

Решение

Для примера сделаем небольшую игру «Логические концовки». Вы можете поговорить с этим ботом в Telegram по адресу @Logic_check_bot. Посмотреть на сценарий вы можете здесь.

Как это работает

  1. Запрашиваем данные об игроке

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

В сценарии создайте первый экран, добавьте на него блок HTTP-запрос:

  • метод — GET * в поле URL вставьте данный адрес: https://tools.aimylogic.com/api/data/${userId}
  • На вкладке RESPONSE нажмите на + и в поле Имя переменной вставьте: history, а в поле Значение вставьте: $httpResponse
  • Вкладки BODY и HEADERS заполнять не нужно.
  • Нажмите Сохранить.

  • Для удобства добавим на этот экран метку ЕСТЬ ЛИ ИСТОРИЯ?

Если данные об игроке будут, то они сохранятся в переменную $history, запрос завершится успешно, и мы сможем оперировать этой переменной. Если же данных нет, то запрос завершится с ошибкой — это будет значить что пользователь к нам пришел первый раз.

  1. Если пользователь у нас впервые
  • От блока http-запрос Завершен с ошибкой сделаем новый экран с блоком Текст: Привет! Это игра логические концовки. Вооружись логическим мышлением! В этой игре нужно правильно закончить фразы. Ну что, начнем?

  • Назовем этот экран ЕСЛИ НЕТ ИСТОРИИ

  1. Добавим варианты ответов пользователя
  • Добавим на экран «ЕСЛИ НЕТ ИСТОРИИ» блок Интенты.
  • Добавим готовый интент Согласие.
  • Сохраним блок

к сведению

Узнать больше о блоке Интенты вы можете здесь, а о готовых интентах — здесь.

Вот что у нас получилось:

  1. Оформим таблицу, в которой будем хранить содержание игры

Пример таблицы вы можете посмотреть здесь. Можете просто скопировать эту таблицу.

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

Выглядеть таблица будет следующим образом:

  • В таблице должно быть 4 столбца с названиями:
    • question
    • answer
    • level
    • score
предупреждение
Копируйте и вставляйте эти названия в таблицу. Если вы напишете названия столбцов неправильно, измените одну букву, добавите пробел или сделаете иную опечатку, сценарий, предложенный в этом уроке, не будет работать.
  • Заполните таблицу следующим содержанием, как видно на скриншоте выше:
questionanswerlevelscore
Если стол выше стула, то стул…ниже стола110
Если два больше одного, то один…меньше двух1220
Если сестра старше брата, то брат…младше сестры330
Если правая рука справа, то левая…слева440
Если река глубже ручейка, то ручеек…мельче реки550
  • Колонки Level и Score помогут нам возвращать пользователя к тому месту, где мы остановились, и также выводить счет, так что они должны содержать соответствующие числовые значения.
  1. Обязательно опубликуйте вашу таблицу:

    Файл → Опубликовать в интернете → Опубликовать → Ок → Закройте всплывающее окно.Путь из всплывающего окна копировать не нужно.

  • Откройте блокнот и скопируйте в него строку:

    https://tools.aimylogic.com/api/googlesheet2json?sheet=1&id=

  • Затем найдите в пути вашей таблицы данный элемент:

Этот элемент находится между /d/ и /edit. Это идентификатор страницы.

Скопируйте его:

И вставьте в блокнот сразу после строки, которую вы скопировали раньше:

У вас получилась ссылка, которая понадобится нам позже.

  1. Получаем данные из таблицы
  • Кликните на интент Согласие и от него создайте новый HTTP-запрос.

  • Метод — GET

  • В поле URL нужно вставить ссылку, которая получилась у вас в блокноте шагом ранее:

  • На вкладке RESPONSE нажмите на + и в поле Имя переменной вставьте: items
  • а в поле Значение вставьте: $httpResponse
  • Вкладки BODY и HEADERS заполнять не нужно

В итоге получится такой запрос:

  • Нажмите Сохранить.

  • Назовем этот экран ПОЛУЧАЕМ ВОПРОС

Вот что у нас получилось:

  1. Получаем первый вопрос

Ранее мы добавили в HTTP-запрос переменную $items:

В переменной $items находится весь массив с фразами. Далее нам нужно взять из этого массива только первую фразу. Для этого будем использовать встроенные функции Aimylogic.

От варианта блока http-запрос Завершен успешно создаем новый блок Условия, в который пишем $items.first()

Назовем этот экран ПЕРВЫЙ ВОПРОС

Вот что у нас получилось:

Таким образом получаем первый элемент массива, а теперь нам нужно его вывести.

  1. Выводим первый вопрос
  • Чтобы вывести текст первого вопроса, соедините условие $items.first() с новым блоком Текст. В блоке Текст напишите: Дополни такую фразу:

  • Назовем этот экран ВЫВОДИМ ВОПРОС

  • На этот же экран «ВЫВОДИМ ВОПРОС» добавьте еще один блок Текст

и напишите в нем: `$items.current().question``

  1. Теперь мы можем протестировать, выводится ли первый вопрос. Для этого нажмите Тестировать и напишите боту «да». Должно получиться так:

предупреждение
  1. Если вопрос не выводится, вернитесь к шагу 5 и убедитесь, что вы опубликовали страницу.
  2. Если появляется ошибка или бот выводит не то, что в таблице, то убедитесь, что вы нигде не допустили опечатку.
  1. Принимаем варианты ответов

Остановите тестирование.

Добавьте на экран «ВЫВОДИМ ВОПРОС» блок Интенты. Создайте интент $answer

подсказка
Этот интент будет принимать ответы, которые мы пропишем в справочнике сущностей.
  1. Создадим справочник
  • Сохраните сценарий.

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

Кликните «Создать справочник»:

Назовите справочник answer

Это название соответствует названию, которое мы ранее указали в интентах, это очень важно:

  • Нажмите Продолжить.

  • Перенесите в колонку «Сущность» содержание столбца answer вашей Google Таблицы (можно копировать и вставлять).

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

Подробнее о сущностях вы можете почитать здесь.

  • Нажмите Сохранить изменения.

  1. Сравниваем ответ пользователя с правильным ответом
  • Вернитесь на вкладку «Сценарий».

  • От интента $answer создайте новый блок Условия

скопируйте и вставьте в этот блок Условия:

$answer === $items.current().answer

примечание

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

  • Назовем этот экран

СРАВНИВАЕМ ОТВЕТ

  1. Объявим, что ответ правильный.
  • От блока Условия создайте новый блок Текст:

Да, это правильный ответ!

  • Назовем этот экран:

ПРАВИЛЬНЫЙ ОТВЕТ

  • Добавьте экран «ПРАВИЛЬНЫЙ ОТВЕТ» блок Переход:

Теперь от экрана «ВЫВОДИМ ВОПРОС» от варианта Любая другая фраза создайте новый экран с блоком Текст, содержащим:

А вот и неправильно!

  • Назовем этот экран:

НЕПРАВИЛЬНЫЙ ОТВЕТ

  • На экран «НЕПРАВИЛЬНЫЙ ОТВЕТ» добавьте еще один блок текст:

Попробуй еще раз!

И блок Переход.

Свяжите блок «Переход» с экрана «Неправильный ответ» с экраном «Выводим вопрос»:

Соедините вариант else экрана «Сравниваем ответ» с экраном «Неправильный ответ»:

  1. Можем протестировать созданную часть сценария.

Нажмите Тестировать:

Скажите боту «да», затем введите правильный ответ — «ниже стола». Бот должен сказать, что ответ верный:

Перезапустите тестирование.

Скажите боту «да», затем введите неправильный ответ. Бот должен сказать, что ответ неверный:

Пока это все, что бот умеет делать. Продолжим работать над сценарием.

  1. Сохраним информацию об игроке

Когда пользователь ответил верно, нужно дать ему следующую фразу. Но перед тем, как выводить следующую фразу, от блока Переход с экрана «Правильный ответ» создадим блок HTTP-запрос

С помощью этого запроса отправим текущую информацию об игроке, его текущий уровень и счет.

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

  • метод POST URL: https://tools.aimylogic.com/api/data/${userId}

  • на вкладке BODY передаем нужные данные в таком формате (скопируйте и вставьте):

    { "level": "$items.current().level", "score": "$items.current().score"}

  • Вкладки RESPONSE и HEADERS заполнять не нужно.

  • Нажмите Сохранить.

  • Назовем этот экран:

    СОХРАНИМ ПРОГРЕСС

  1. Выводим следующий вопрос.

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

От варианта Завершен успешно создайте блок Условия.

Делаем условие $items.next(), которое возьмет вопрос из массива $items

  • Назовем этот экран ВЫВОДИМ СЛЕДУЮЩИЙ ВОПРОС

От экрана «ВЫВОДИМ СЛЕДУЮЩИЙ ВОПРОС» делаем связь на экран «ВЫВОДИМ ВОПРОС»:

  1. Добавляем действие на случай, если есть история о пользователе

Теперь нужно сделать так, чтобы на следующей сессии (например, при следующем запуске навыка в Алисе) мы узнавали пользователей и возвращали их на то место, где они остановились в последний раз.

  • Вернемся в начало сценария. На экране «ЕСТЬ ЛИ ИСТОРИЯ?» от варианта Завершен успешно создайте новый блок Текст:

С возвращением! В прошлый раз мы дошли до уровня $history.level. Твой счет: $history.score. Продолжим?

  • Назовем этот экран ЕСЛИ ЕСТЬ ИСТОРИЯ

  • Добавим на экран «ЕСЛИ ЕСТЬ ИСТОРИЯ» блок Интенты. Добавим варианты реакций пользователя — готовые интенты Согласие и Отказ:

  1. Получаем неотвеченные вопросы

От интента Отказ экрана «ЕСЛИ ЕСТЬ ИСТОРИЯ» создадим блок http-запрос.

Здесь нам снова нужно получить данные из Google Таблицы, как обычно.

  • метод GET

  • URL может быть таким же, как в блоке HTTP-запрос «Получаем вопрос»

  • на вкладке RESPONSE нажмите на + и в поле Имя переменной вставьте: items, а в поле Значение вставьте: $httpResponse.slice(parseInt($history.level))

Давайте разберемся, что значит это выражение в блоке Значение:

slice — возвращает новый массив, содержащий копию части исходного массива, parseInt — преобразует строку в число.

$history.level — уровень, на котором остановился пользователь. Получится, что мы откинем часть массива, а значит, выведем пользователю только те фразы, на которые он еще не давал ответ.

Нажмите Сохранить.

  • Назовем этот экран НЕОТВЕЧЕННЫЕ ВОПРОСЫ

  • Связываем вариант Завершен успешно экрана «НЕОТВЕЧЕННЫЕ ВОПРОСЫ» с экраном «Первый вопрос».

  1. Добавим распознавание желания начать новую игру

Осталось дать возможность пользователю начать новую игру.

Добавим блок Интенты в любое место сценария:

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

Добавим интент * нов* игр* *

Этот интент будет ловить такой ввод, как «новая игра», «новую игру», «начать новую игру», «хочу новую игру», «новую игру давай» и т. д. Подробнее читайте в статье о синтаксисе шаблонов.

  • Назовем экран ГЛОБАЛЬНЫЙ ИНТЕНТ

  1. От интента * нов* игр* * создадим новый блок http-запрос, с помощью которого будем удалять данные о пользователе:
  • выберите метод DELETE и в поле URL скопируйте ссылку: https://tools.aimylogic.com/api/data/${userId}

  • нажмите Сохранить.

  • Назовем этот экран УДАЛЯЕМ

    Так мы очистим все данные об этом игроке.

От варианта Завершен успешно экрана «УДАЛЯЕМ» делаем связь с экраном «ЕСЛИ НЕТ ИСТОРИИ»

  1. Добавим сообщение об успешном завершении игры

Найдите экран «ВЫВОДИМ СЛЕДУЮЩИЙ ВОПРОС». От варианта else создайте блок Текст:

Поздравляю, игра пройдена! Хочешь сыграть еще?

Это сообщение будет выводиться, если вопросов больше не осталось.

Назовем этот экран:

ИГРА ОКОНЧЕНА

  • На экран «ИГРА ОКОНЧЕНА» добавьте блок Интенты и добавьте возможные варианты ответа, например, готовые интенты «Согласие» и «Отказ»:

  1. Свяжите интент «Согласие» с блоком HTTP-запрос «Получаем вопрос», на котором обращаемся к Google Таблице.

  2. С экрана «ПЕРВЫЙ ВОПРОС» свяжите вариант else с экраном «ИГРА ОКОНЧЕНА»

Игра готова!

Вот что у нас получилось. Скачайте изображение, чтобы увидеть крупнее.

Можете нажать кнопку Тестировать и проверить, как это работает:

Что дальше?

Мы составили набросок сценария. Можно сделать бота более работоспособным и «живым».

Дополните сценарий:

  • везде, где есть вариант «любая другая фраза» свяжите этот вариант либо с этим же экраном, либо с текстовым блоком, в котором дайте пользователям инструкцию на тот случай, если они вводят не то, что вы от них ожидаете. Если не связать вариант «Любая другая фраза» ни с чем, то бот будет отвечать «Извините, непонятно» на ввод, который не попадает в варианты Интентов.* дополните примеры интентов другими возможными словами, которые пользователи могут написать на соответствующем этапе сценария* добавьте кнопки* дополните речь бота другими репликами;

  • добавьте кнопку Новая игра на экран «С возвращением!»

  • В некоторых HTTP-запросах вариант «Завершен с ошибкой» на имеет связи с текстовыми блоками. Свяжите варианты «Завершен с ошибкой» с текстовым блоком, содержащим текст: Ошибка $httpStatus

  • можете добавить обращение к пользователю по имени, как описано в этой статье.

  • В каждом текстовом блоке вы можете добавить другие варианты текста, нажав на «Добавить другую реплику». Тогда бот будет выдавать разные варианты фраз в случайном порядке и не будет повторяться.

  • Можете добавить в реплики бота смайлики, скопировав их отсюда.* Можете добавить экран, на котором бот будет прощаться с пользователем, если пользователь отказался играть, написал «хватит» или «пока».

  • Вы также можете добавить в начало сценария еще один блок условий, который будет проверять, не на последнем ли уровне остановился пользователь в прошлый раз. $history.level == 5

else свяжите с экраном «ЕСЛИ ЕСТЬ ИСТОРИЯ»

А само условие свяжите с экраном «ИГРА ОКОНЧЕНА»

Возникли сложности?

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

Также можете попросить совета в нашем сообществе в Telegram: https://t.me/aimylogic