Это сообщение от Gabrielle (Gabby) Crevecoeur, которая изначально разместила это в своем блоге Ни за что… Она кодирует?!? - другие сообщения от Габби читайте здесь. Теперь по почте!

Итак, я создал нового бота, но он немного отличается от моих обычных NodeBots. Фактически, здесь даже не было никакого оборудования! Вместо этого я использовал Microsoft Bot Framework, который используется для создания интерактивных ботов, которые предназначены для взаимодействия с пользователями на естественном языке. Ботов, созданных с помощью этого фреймворка, можно использовать в Skype, Slack и даже внедрять в ваши текстовые сообщения.

Мой коллега Кевин и я объединились и создали бота, который пригодится многим студентам! Мы создали чат-бота, который позволит вам изучить ваши флеш-карты Quizlet, и вот как:

(Имейте в виду, что вы можете следовать этому руководству, чтобы запустить и запустить любого бота; если вам не нужен бот с флэш-картой, просто игнорируйте части Quizlet).

Чат-бот Quizlet

Чат-бот, созданный Кевином и Габби, на самом деле является ботом для карточек! Если вы в пути, но хотите продолжить учебу, используйте этого бота для изучения карточек Quizlet в любое время. Итак, приступим.

Предпосылки

  1. Вам понадобится учетная запись Azure. Зарегистрируйтесь здесь, чтобы получить бесплатную пробную версию
  2. Node.js
  3. Учетная запись разработчика Quizlet

Шаг 1. Настройка в Azure

После создания учетной записи Azure пора создать веб-приложение для запуска ChatBot. Здесь создаются конечные точки для связи с вашим ботом.

  1. Перейдите на http://portal.azure.com
  2. Выберите «Новый».
  3. Затем "Интернет + мобильный"
  4. И, наконец, «Веб-приложение»
  5. Придумайте название для своего приложения
  6. Выберите вашу подписку
  7. Группа ресурсов: выберите По умолчанию
  8. План службы приложений: выберите По умолчанию
  9. Щелкните "Создать".

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

Шаг 2. Зарегистрируйте своего бота

После того, как ваше веб-приложение будет создано, вам нужно будет зарегистрировать своего бота на сайте платформы ботов.

  1. Перейдите на https://dev.botframework.com/bots/new
  2. Дайте вашему боту имя, дескриптор бота (который будет использоваться в веб-ссылке бота) и описание вашего бота.
  3. Затем вам нужно настроить конечную точку сообщений. Это URL-адрес, который вы получили из своего веб-приложения Azure. Убедитесь, что вы используете https в начале ссылки и добавляете / api / messages в конец ссылки. т.е. https://mhackschatbotnode.azurewebsites.net/api/messages
  4. Затем сгенерируйте свой идентификатор и пароль приложения Microsoft, нажав «Создать идентификатор и пароль приложения Microsoft».
  5. Ваш идентификатор приложения будет заполнен автоматически, и вам нужно будет сохранить пароль приложения где-то отдельно, потому что он будет скрыт, пока вы не создадите новый.
  6. Наконец, вам нужно будет добавить свой APP ID и APP PASSWORD в настройки Azure. Вернитесь к обзору своего веб-приложения и в панели задач перейдите к параметрам приложения.
  7. Прокрутите вниз до раздела настроек приложения и введите свой APP ID ad APP PASSWORD. В столбце Key должен быть указан MICROSOFT_APP_ID, а значение - это идентификатор приложения, полученный при регистрации бота. То же самое и с паролем приложения, за исключением того, что ключом является MICROSOFT_APP_PASSWORD, а значением является пароль приложения, который вы получили при регистрации бота.

Шаг 3. Получите код

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

  1. Инициализировать проект узла npm init
  2. Установите правильные модули узлов npm install --save botbuildernpm install --save restify
  3. Создайте файл app.js в своем каталоге
  4. Создайте еще один файл js, который будет взаимодействовать с API quizlet (в этом репозитории файл называется api.js)

В вашем файле app.js вам понадобится следующий код, необходимый для правильной настройки вашего бота:

var restify = require('restify');
    var builder = require('botbuilder');

    //=========================================================
    // Bot Setup
    //=========================================================

    // Setup Restify Server
    var server = restify.createServer();
    server.listen(process.env.port || process.env.PORT || 3978, function () {
       console.log('%s listening to %s', server.name, server.url);
    });

    // Create chat bot
    var connector = new builder.ChatConnector({
       appId: <YOUR APP ID>,
        appPassword: <YOUR APP PASSWORD>
    });

    var bot = new builder.UniversalBot(connector);
    server.post('/api/messages', connector.listen());

Это всего лишь костяк бота. Прежде чем мы добавим какие-либо диалоги, убедитесь, что ваш файл api настроен правильно.

Код API Quizlet

Чтобы этот бот заработал, нам нужно сделать два вызова API. Один для получения различных наборов, которые есть у пользователя, а другой для получения карт в наборе. Прежде чем вы сможете сделать какой-либо из вызовов, обязательно получите свой идентификатор клиента разработчика Quizlet на панели инструментов разработчика Quizlet API 2.0. Вы также можете получить код api из файла api.js в этом репозитории.

Давайте посмотрим на функцию GetSets:

exports.GetSets = function (user, callback) {
        request.get({
            uri: 'https://api.quizlet.com/2.0/users/' + user + '/sets?client_id=<ENTER CLIENT ID here>',

        },
            function (error, response, body) {
                if (error)
                    callback(error);
                else {
                    body = JSON.parse(body);
                    for (var x = 0; x < body.length; x++) {
                        if ((x + 1) == body.length) {
                            // last set
                            sets = sets + body[x].title;
                        } else {
                            sets = sets + body[x].title + ', ';
                        }
                        table[body[x].title] = body[x].id; //creating a hash table to store set names and IDs
                    }
                    console.log('Got sets');
                    exports.Sets = sets;

                }
            })
    }

Поскольку файл api.js будет использоваться в качестве модуля узла в других файлах, все переменные и функции, необходимые вне этого файла, будут экспортированы. Функция GetSets выполняет вызов Get к uri Quizlet, специфичному для получения наборов исследований пользователей, с переданным в него именем пользователя и идентификатором клиента, полученным от Quizlet (имя пользователя передается из внешних файлов, вызывающих функцию, поэтому это не так. переменную, которую необходимо создать в этом файле.) Тело, полученное обратно от API, будет содержать различные наборы исследований и другую информацию, связанную с ними. Остальная часть этой функции будет манипулировать телом, чтобы мы могли хранить имена наборов (в массиве наборов) и идентификаторы наборов (которые потребуются в следующей функции) с помощью хеш-таблицы. Давайте посмотрим на функцию GetTerms.

exports.GetTerms = function (key, callback) {
        request.get({
            uri: 'https://api.quizlet.com/2.0/sets/' + table[key] + '?client_id=<ENTER CLIENT ID here>',
        },
            function (error, response, body) {
                if (error)
                    console.log(error);
                else {
                    body = JSON.parse(body);
                    for (var x = 0; x < body.terms.length; x++) {
                        terms.push(body.terms[x].term)
                        def.push(body.terms[x].definition);
                    }
                    console.log('Got terms');
                    exports.Terms = terms;
                    exports.Def = def;
                }
            })
    }

Функция GetTerms выполняет вызов Get к uri Quizlet, специфичному для получения карточек из указанного набора, с использованием хэш-таблицы идентификаторов наборов и идентификатора клиента. Ключевым параметром будет имя набора, которое пользователь выберет в диалоговом окне бота (в котором мы обсудим позже). Остальная часть этой функции будет управлять телом, чтобы мы могли хранить термины карточек (в массиве терминов) и определения в другом массиве.

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

var username; 
    var quiz = require('./api.js');
    var index = 0;



    (function () {
        if (username)
            quiz.GetSets(username);   // I will invoke myself
    })();

Код, который мы добавили, создал экземпляр переменной имени пользователя, которая будет использоваться для определения имени пользователя, модуля API, который будет называться викториной, и значения индекса, которое будет использоваться позже. Под новыми переменными вы увидите самозапускающуюся функцию (в которой вам никогда не нужно явно вызывать ее, она будет запускаться автоматически). Функция автозапуска предназначена на тот случай, если вы хотите жестко запрограммировать имя пользователя и пропустить некоторые шаги в диалогах бота, которые мы собираемся обсудить дальше; если имя пользователя жестко запрограммировано, оно вызовет функцию GetSets в API, поэтому оно готово для пользователя.

Диалоги используются для управления диалогом ботов с пользователем. Они вызываются так же, как если бы вы вызывали веб-страницу на веб-сайте, маршрутизацию. т.е. «/» - это корневой диалог - это первое, что бот скажет, когда пользователь вызовет его. «/ Test» - это диалог с именем test

Раздел Dialog для app.js находится ниже:

//=========================================================
    // Bots Dialogs
    //=========================================================

    bot.dialog('/',

        function (session) {
            session.send("Hello! Welcome to the Mhacks Quiz Bot. Would you like to study today?")
            session.beginDialog('/user');
        });

    bot.dialog('/user', new builder.IntentDialog()
        .matches(/^yes/i, [
            function (session) {
            // setTimeout(function () {
            if (username)
                session.beginDialog('/subject')
            else {
                builder.Prompts.text(session, "What is your quizlet username?")
            }
            //  }, 3000)
        },
        function (session, results) {
            quiz.GetSets(results.response);
            session.beginDialog('/subject')
        }])
        .matches(/^no/i, function(session){
            session.send("Ok see ya later!")
            session.endConversation;
        }));


    bot.dialog('/subject', [
            function (session) {
               setTimeout(function(){
                builder.Prompts.text(session, "What study set would you like today?" + quiz.Sets);
                }, 2000)
            },
            function (session, results) {
                quiz.GetTerms(results.response);
                session.send("Ok! I got your flashcards! Send 'ready' to begin. Send 'flip' for definition. Send 'next' for the next card. Send 'exit' when you are done")
                session.beginDialog('/study')
            }]
    );

    bot.dialog('/study', new builder.IntentDialog()
        .matches(/^ready/i, [
            function (session) {
                session.send(quiz.Terms[index])
            }])
        .matches(/^flip/i, [
            function (session) {
                session.send(quiz.Def[index])
            }]
        )
        .matches(/^next/i, [
            function (session) {
                if (++index == quiz.Terms.length)
                    session.send("You are all out of cards! Hope you had fun studying! :)")
                else
                    session.send(quiz.Terms[index])
            }])
         .matches(/^exit/i, [
            function (session) {
                session.send("Hope you had fun studying. See ya later :)")
            }]
        )

    );

Глядя на этот код, вы видите, что диалог начинается с корневой функции. Просто спросите пользователя, действительно ли он запускает программу. В следующем диалоговом окне «/ user» проверяется, хочет ли пользователь учиться; если они выберут «да», он затем проверит, есть ли жестко заданное имя пользователя или нам нужно попросить его указать. Если имя пользователя было жестко запрограммировано, оно просто перейдет к диалоговому окну '/ subject', потому что наборы для изучения пользователей уже были найдены в функции самозапуска, описанной ранее, в противном случае она запросит имя пользователя, вызовите функцию GetSets с новым именем пользователя. а затем вызовите диалог «/ тема». В диалоговом окне «/ предмет» пользователю предлагается выбрать, какой набор исследований он хотел бы изучить. Как только они выберут, GetTerms будет вызван на основании их решения, а затем бот перейдет к диалоговому окну «/ учеба». В диалоговом окне «/ study» возможен просмотр терминов, «переворачивание» карточки для определения, переход к следующей карточке и, возможно, ранний выход. Мы используем индексную переменную, чтобы отслеживать, в какой карточке мы находимся, как для массивов term, так и def.

Давайте разберем некоторые компоненты этого диалога.

Сессии

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

ex:

bot.dialog('/', function (session) {
                    session.send("Hello! Welcome to the Mhacks Quiz Bot. Would you like to study today?")
                    session.beginDialog('/user');

    });

Водопады

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

ex:

bot.dialog('/subject', [
            function (session) {
               setTimeout(function(){
                builder.Prompts.text(session, "What study set would you like today?" + quiz.Sets);
                }, 2000)
            },
            function (session, results) {
                quiz.GetTerms(results.response);
                session.send("Ok! I got your flashcards! Send 'ready' to begin. Send 'flip' for definition. Send                            'next' for the next card. Send 'exit' when you are done")
                session.beginDialog('/study')
            }]
    );

Подсказки

Как вы заметили в примере «/ subject» и других функциях, много раз пользователей просят дать ответ, в котором нам нужны данные, в строке указано builder.Prompts.text(). Фреймворк ботов имеет встроенные доступные подсказки, которые можно использовать для сбора данных от пользователя.

Доступны различные типы возврата подсказок: builder.Prompts.text(session, "What's your name?");builder.Prompts.number(session, "How many do you want?"); builder.Prompts.time(session, "When is your appointment?"); builder.Prompts.choice(session, "Which color?", "red|green|blue");

Намерения

Так что, если вы хотите знать, как пользователь отвечает на вопрос, но вам не нужен доступ к данным ответа? Есть намерения! Класс IntentDialog позволяет вам слушать, как пользователь произносит определенное ключевое слово или фразу. После того, как пользователь отправит ответ, вы можете увидеть, «совпадает» ли его ответ с определенными словами / фразами:

ex:

bot.dialog('/study', new builder.IntentDialog()
        .matches(/^ready/i, [
            function (session) {
                session.send(quiz.Terms[index])
            }])
        .matches(/^flip/i, [
            function (session) {
                session.send(quiz.Def[index])
            }]
        )
        .matches(/^next/i, [
            function (session) {
                if (++index == quiz.Terms.length)
                    session.send("You are all out of cards! Hope you had fun studying! :)")
                else
                    session.send(quiz.Terms[index])
            }])
         .matches(/^exit/i, [
            function (session) {
                session.send("Hope you had fun studying. See ya later :)")
            }]
        )

    );

Шаг 4: непрерывная интеграция

Если вы заметили, в вашем веб-приложении нет кода, который бы знал, что именно запускать. Сначала в каталоге кода создайте файл index.html, в котором вы просто напечатаете «Hello World!»

<html>
    <head>
        <title>Mhacks Bot</title>
    </head>
    <body>
        Hello world! This is the Bots home page :)
    </body> 
    </html>

После этого разместите весь каталог на Github! Затем вам нужно будет настроить непрерывную интеграцию через Github в своем веб-приложении Azure. Вот пошаговая инструкция, как это сделать:

Https://azure.microsoft.com/en-us/documentation/articles/app-service-continuous-deployment/

Шаг 5: Тестирование вашего бота

Если у вас есть Windows Machine! Вы можете протестировать своего бота на эмуляторе бота. Вы можете установить его здесь https://docs.botframework.com/en-us/tools/bot-framework-emulator/! Вам понадобится ваш идентификатор приложения и пароль приложения, чтобы ввести его в эмулятор и приступить к тестированию.