Диплом: Разработка чат-бота как сервиса для прохождения тестов

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам
52
Для хранения связи ответ-вопрос создается класс UserAnswer
(рисунок 36), который включается в себя идентификатор вопроса
(QuestionId) и идентификатор ответа (AnswerId). Для инициализации полей
используется конструктор с аналогичными входящими параметрами.
Рисунок 36 – Класс UserAnswer
Для фиксирования действий пользователя создается публичный
класс UserAction (рисунок 37), в котором содержатся поля: ChatId
идентификатор чата, в котором происходит беседа (именно по этому
идентификатору определяется кому и когда отправлять необходимые
данные), LastShange – время фиксации последнего действия пользователя,
Answers – коллекция ответов на вопросы типа UserAnswer. Поле
LastShange является приватным для установки значения, это сделано для
фиксации только про инициализации, либо изменении коллекции ответов.
Рисунок 37 – Класс UserAction
53
Для добавления ответов полученных от пользователя в коллекцию
ответов в классе UserAction создается вспомогательный метод AddAnswer
(рисунок 38) с входящими параметрами questionId (идентификатор
вопроса) и answerId (идентификатор ответа). Также при добавлении
изменяется время фиксации изменения.
Рисунок 38 – Метод добавления ответов
Далее создается статический класс Storage (рисунок 39)
непосредственно для хранения всех результатов от всех пользователей. В
классе содержится коллекция типа UserAction, т.е. всех действий по
идентификаторам чатов.
Рисунок 39 – Класс Storage
Для добавления новых данных из чатов в классе Storage создается
вспомогательный статический метод AddData (рисунок 40), с входящими
параметрами: идентификатор чата – chatId, идентификатор вопроса –
questionId и идентификатор ответа – answerId. В методе реализован поиск
по идентификатору чата данных этого чата. Если данные найдены, то
добавляется новый ответ на вопрос. Если данные по пользователю не
найдены, сначала создается новые UserAction для контекстного чата, а уже
после добавляется новый ответ на вопрос.
54
Рисунок 40 – Метод добавления действий пользователя
Также внутри класса добавляются еще 3 вспомогательных метода.
Метод получения по идентификатору чата данных по этому чата GetData
(рисунок 41).
Рисунок 41 – Метод получения данных по идентификатору чата
Для очистки устаревшей информации (нет действий более одного
часа) создается метод ClearOldData (рисунок 42), который по
идентификатору чата убирает все данные по этому чату из коллекции Data
класса Storage.
Рисунок 42 – Метод удаления устаревших данных
Также для очистки данных создается метод удаления данных по
идентификатору чата ClearDataByChatId (рисунок 43). В данном методе
55
коллекция данных Data перезаписывается без учета данных выбранного
чата.
Рисунок 43 – Метод удаления данных по идентификатору чата
3.2.4. Логика проекта
Основной частью проекта является класс Program. Внутри данного
класса объявяляется приватная статическая переменная _bot (рисунок 44) с
типом TelegramBotClient, в которую при первом запуске программы
присвается подключенный бот.
Рисунок 44 – Объявление бота
Старт программы начинается с метода Main. Внутри данного класса
создается объект клиента бота и передается в него токен, полученный в
результате регистрации бота непосредственно в Telegram. Объект клиента
записывается в переменную _bot. Также проверяется подключение и в
случае успешной проверки обозначается название консольного
приложения как название бота, которое уже берется непосредственно из
переменной _bot (рисунок 45).
Рисунок 45 – Инициализация бота
56
Далее в основном методе Main регистрируются все события (рисунок
46), которые могут происходить в процессе выполнения работы бота, а
именно OnMessage – получение текстового сообщения, OnMessageEdited –
получение отредактированного сообщения, OnCallbackQuery – получение
ответной реакции от какого-либо действия (например, нажатие кнопки),
OnInlineResultChosen – получения действия на специальной клавиатуре,
OnReceiveError – получение какой-либо ошибки в ходе работы бота. Все
события инкрементируются.
Рисунок 46 – Регистрация событий
Также внутри метода Main необходимо указать боту получение
информации методом StartReceiving и завершение получения информации
методом StopReveinving (рисунок 47).
Рисунок 47 – Запуск/завершение получения информации
После первого запуска видно, что бот подключился успешно и
название консольного приложения приняло название бота (рисунок 48).
Рисунок 48 – Первый запуск
57
После настройки в методе Main необходимо настроить обработчики
событий пользователя. Для обработки текстовых сообщений существует
асинхронный метод BotOnMessageReceived, который принимает
сообщение пользователя в результате его действия. Внутри метода
изначально проверяется сообщение на null и на тип сообщения, т.к. оно
обязательно должно быть текстовое. Само сообщение записывается в
переменную text в уже отформатированном формате (рисунок 49).
Рисунок 49 – Обработка текстовых событий
В случае, если пользователь ввел команду «/start» выполняются
следующие действия (рисунок 50): в консольное приложения записывается
пользователь, который начал проходить тестирование; происходит очистка
всех данных из памяти по конкретному чату, используя заранее
написанный вспомогательный метод в классе Storage; отправляется
сообщение в чат пользователю о количестве вопросах и способе ответа на
них; далее ищется первый вопрос из коллекции вопросов класса
TemperamentTest; если вопрос пустой, в чате пользователя выводится
сообщение об ошибке, если вопрос не пустой, то выводится в чате
пользователя специальная клавиатура с вариантами ответа на вопрос.
Вывод клавиатуры обеспечен специальным вспомогательным методом
SendInlineKeyBoardbyQuestion, который принимает идентификатор чата,
куда нужно отправить клавиатуру, и вопрос, на основе которого будет
строиться клавиатура. Метод специально отдельно венесен для
уменьшения дублирования кода. Данный метод используется повсеместно
по всему проекту.
58
Рисунок 50 – Обработка команды «/start»
Вспомогательный метод SendInlineKeyBoardbyQuestion (рисунок 51)
отправляет название вопроса и сгенерированную другим вспомогательным
методом GetInlineKeyboardMurkup клавиатуру.
Рисунок 51 – Отправка клавиатуры и названия вопроса
Вспомогательный метод GetInlineKeyboardMurkup (рисунок 52)
основываясь на поступившем вопросе проверяет наличие ответов к этому
вопросу, если они есть, то последовательно каждый ответ добавляется в
клавиатуру с фиксацией идентификатора ответа. Таким образом, при
нажатии ответа на клавиатуре сработает обработчик событий
OnCallbackQuery, который получит данные в виде идентификатора ответа,
исходя из которого есть возможность идентифицировать конкретный ответ
и вопрос, и записать эти данные для контекстного чата.
59
Рисунок 52 – Генерация клавиатуры по вопросу
При нажатии кнопки срабатывает обработчик событий
OnCallbackQuery по средствам асинхронного метода
BotOnCallbackQueryReceived (рисунок 53). В метод приходят данные ил
клавиатуры и записываются в переменную callbackQuery. Затем по
идентификатору ответа из пришедших данных определяется вопрос, по
которому пришел ответ, для этого используется сравнение с коллекией
вопросов в классе TemperamentTest. Если вопрос пустой, обработчик
закрывается, если нет, то в userData сохраняются все данные по
контекстному чату. Данные берутся по средствам заранее написанного
вспомогательного метода в классе Storage.
Рисунок 53 – Обработчик событий OnCallbackQuery
Далее происходит ряд проверок входящих данных. Если данные чата
не пустые и уже был получен ранее ответ на контекстный вопрос, то в чат
контекстному пользователю отправляется соответствующее сообщение
(рисунок 54).
60
Рисунок 54 – Проверка на дублирование ответа
Также происходит проверка на порядковый номер вопроса (рисунок
55). Если пришел ответ на вопрос, который не следовал за предыдущими,
то обработчик закрывается. Это сделано из-за сохранения истории
переписки, то есть если пользователь нажимает на старую клавиатуру
ничего не должно происходить.
Рисунок 55 – Проверка на порядковый номер вопроса
Дополнительная проверка на порядковый номер вопроса (рисунок
56) делается в случае, если контекстный вопрос не первый и данных по
чату нет.
Рисунок 56 – Дополнительная проверка на порядковый номер вопроса
Если все проверки пройдены, то отправляется сообщение в чат
контекстному пользователю о том, что его ответ принят. А также в данные
пользователя добавляется идентификатор ответа и идентификатор вопроса,
на который был дан ответ (рисунок 57). Добавление происходит по
средствам заранее написанного вспомогательного метода AddData класса
Storage, в который также передается идентификатор чата.
61
Рисунок 57 – Принятие ответа и добавление данных
Далее если контекстный вопрос не последний, то находится
следующий вопрос и если он не пустой, то на основе его строится
клавиатура (рисунок 58) так же как и ранее по средствам метода
SendInlineKeyBoardbyQuestion. Построенная клавиатура отправляется в
контекстный чат.
Рисунок 58 – Построение клавиатуры ответов для следующего вопроса
Если контекстный вопрос последний, то определяются все ответы на
вопросы данные контекстным пользователем. В чат на основе всех ответов
отправляются результаты тестирования, после чего данные по чату
обнуляются для возможности прохождения теста повторно (рисунок 59).
Рисунок 59 – Отправка результата тестирования

Смотрите также:

"Автоматизация обработки заявок ООО "Проектно-Строительная Компания"
"Автоматизация процесса аттестации персонала для ООО "Нэт Бай Нэт Холдинг"
"Анализ интернет-активности конкурентов ( на примере конкурентов "Газпром нефть")
"Бухгалтерский учёт и аудит расчётов с подотчётними лицами в организации на примере ООО "ЛОЦ 10""
«Психологическое сопровождение персонала в организации на примере ООО «Крокус»
Cовершенствование деловой оценки персонала в организации (на примере ООО "Даймонд кейтеринг развитие")
PR как средство продвижения организации (на примере ПАО "Тамбовский завод "Комсомолец им. Н.С. Артемова")
PR-коммуникации в сфере общественного питания (на примере кафе-кондитерской «Cream Cheese»)
SMM как средство повышения эффективности работы учреждений социокультурной сферы (на примере Малого театра)
Value-based education: ценности в системе образования и способы их реализации на уроке английского языка. Опыт Европейских стран