Skip to content

TGladysheva/telegram-bot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

70 Commits
 
 
 
 
 
 
 
 

Repository files navigation

CookBot

Описание

Бот - кулинарная книга для Telegram Найти в Telegram - @CookingHelperBot

Авторы

Ишин Данил, Гладышева Татьяна, Немцев Евгений

План презентации

Суть проекта

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

  • /recipe - найти рецепт по названию.
  • /ingr - получить список рецептов, в которых содержится указанный ингридиент.
  • /all - отобразить список всех рецептов.
  • /help - информация о поддерживаемых командах.

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

Example

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

Расширяемость команд продемонстрирована выше. Для баз данных - ArrayDatabase (используется массив, который изначально засериализован). Для демонстрации IBot как точки расширения помимо CookBot, был написан HelloBot (который здоровается с вами в ответ на любое сообщение).

Точки расширения

  1. Команды.

    Для того, чтобы создать новую команду достаточно реализовать интерфейс IBotCommand. У команды должно быть имя(свойство Name), описание(свойство Description), а также метод Execute, в который передается ссылка на базу данных и аргументы команды. Примеры реализации можно посмотреть в этой папке .

  2. База данных.

    Для того, чтобы добавить новую базу данных, нужно реализовать дженерик интерфейс IDatabase. Этот интерфейс декларирует два метода GetAllSuitable, GetAnySuitable, в которые передается лямбда-выражение, которому должен удовлетворять искомый объект.

  3. Интерфейс IBot

    Для реализации этого интерфейса необходимо реализовать метод HandleCommand, который возвращает ответ на полученное сообщение. Благодаря этому интерфейсу при работе с TelgramAPI(или другим API), мы можем не привязываться к конкретному боту. В нашем проекте есть две реализации этого интерфейса CookBot и HelloBot. Так же есть класс TelegramHandler, который работает с TelegramAPI и ему в конструктор передается реализация интерфейса IBot. Тем самым, создав нового бота, мы можем просто передать его в конструктор TelegramHandler и не думать снова о том, как работать с TelegramAPI.

Общая структура приложения:

Имеем три слоя:

  1. Инфраструктура Содержит всю работу с базами данных. Не взаимодействует с двумя остальными слоями. Пример использования базы данных в слое приложения при выполнении команды:
      try
      {
           var result = Database
               .GetAnySuitable(x => string.Equals(x.Name, recipeName, StringComparison.CurrentCultureIgnoreCase))
               .GetPrintableView();
           return new BotCommandResult(BotCode.Good, result);
      }
      catch (InvalidOperationException)
      {
           return new BotCommandResult(BotCode.Bad, "К сожалению, ничего подходящего не найдено :(");
      }
    
  1. Предметный слой В нем описана модель рецепта. Главный класс - класс рецепта Он использует несколько вспомогательных классов, например, класс, отвечающий за количество и единицу измерения ингредиента и сам ингредиент. Все они расположены тут

  2. Слой приложения Содержит непосредственно работу с Telegram API и команды бота. Не используется двумя предыдущими слоями, но использует их. Демонстрация работы с БД была выше. Работа с предметным слоем происходит при обработке команд (Получили рецепт и попросили у него отдаваемый пользователю вид):

public BotCommandResult Execute(string[] arguments)
        {
            var suitableRecipes = Database.GetAllSuitable(x => arguments
                        .All(z => x.Components.Keys.Select(y => y.Name.ToLower()).Contains(z.ToLower())));

            if (!suitableRecipes.Any())
                return new BotCommandResult(BotCode.Bad, "К сожалению, ничего подходящего не найдено: (");

            return new BotCommandResult(BotCode.Good,
                string.Join("\n", suitableRecipes.Select(res => res.GetPrintableView())));
        }

Один из наиболее важных классов слоя приложения - класс TelegramHandler.cs Содержит всю работу с Телеграм АПИ и использует интерфейс IBot

Использование DI-контейнера.

Для создания DI-контейнера была выбрала библиотека Ninject. Итоговая сборка осуществляется в классе Program.cs Наиболее неочевидные моменты:

  1. Циклическая зависимость. Команда хелп должна знать обо всех зарегистрированных командах.
      container.Bind<Lazy<List<IBotCommand>>>().ToConstant(new Lazy<List<IBotCommand>>(() => container
                                                                           .GetAll<IBotCommand>()
                                                                           .ToList()))

Для этого нам приходится воспользоваться классом Lazy<T> в классе команды Help:

  private readonly Lazy<List<IBotCommand>> commands;
  1. Cигнлтоны
            container.Bind<IBotCommand>().To<RecipeByNameCommand>().InSingletonScope();
            container.Bind<IBotCommand>().To<RecipeByIngredientsCommand>().InSingletonScope();
            container.Bind<IBotCommand>().To<RecipeListCommand>().InSingletonScope();

Данные класс сделаны сигнлтонами для того, чтобы не создавалось несколько их экземпляров (при создании команды Help ей необходимы и другие зарегистрированные команды, экземпляры которых DI-контейнер создаст еще раз)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published