Skip to content

badhitman/DesignerApp

Repository files navigation

Blazor NET.8 + Telegram Bot + СЭД/HelpDesk/ServiceDesk

  • Blazor NET.81 + TelegramBot2: подойдёт как стартовый кейс web решения с поддержкой Telegram бота.
  • Связь между службами через RabbitMQ3 в режиме запрос-ответ: при отправке сообщения в очередь, отправитель дожидается ответ (в границах таймаута) и возвращает результат вызывающему. При использовании вызова такой команды удалённого сервиса проходит так, как если бы это был обычный await запрос к базе данных или rest/api.rabbitmq
  • ServiceDesk/HelpDesk подсистема оказания консультаций и обратной связи. Пользовательский доступ возможен прямо из Telegram (WebApp) без ввода логина/пароля и вообще регистрации. Управление документами: изменение статусов заявок, журналирование/протоколирование событий и другая универсальная функциональность.
  • Подсистема электронной коммерции: на базе СЭД функционирует простой учёт заказов. Справочник номенклатуры и офферов с настраиваемыми правилами ценообразования. Клиенты ведут свой перечень юридических лиц с разбивкой по филиалам, для которых можно формировать заказы. Документы после создания сразу попадают в основную СЭД, где с ними можно работать: менять статус, вести диалог с клиентом и т.д.
  • Интерфейс rest API для внешних информационных систем (например с 1С). Упрощённая авторизация: использование постоянного токена в заголовке запроса (ключ доступа)
  • Установлен/используется пакет MudBlazor 7

Зависимости решения между проектами:

---
title: Структура (зависимости) проектов в решении
---
classDiagram
note for DbPostgreLib "Если используется другая СУБД, тогда
указатели  от [ServerLib] [Telegram.Bot.Polling], [HelpdeskService] и [RemoteCallLib]
должны ссылаться на соответсвующую библиотеку: [DbPostgreLib] или [DbMySQLLib]"
    SharedLib <|-- CodegeneratorLib
    SharedLib <|-- IdentityLib
    SharedLib <|-- DbLayerLib
    SharedLib : Общие модели
    IdentityLib <|-- ServerLib
    DbPostgreLib <|-- ServerLib
    RemoteCallLib <|-- ServerLib
    RemoteCallLib <|-- CommerceService
    RemoteCallLib <|-- ApiRestService
    CodegeneratorLib <|-- BlazorLib
    HtmlGenerator <|-- CodegeneratorLib
    DbLayerLib <|-- DbPostgreLib
    DbLayerLib <|-- DbPostgreLib
    DbLayerLib <|-- DbMySQLLib
	DbPostgreLib <|-- RemoteCallLib
    BlankBlazorApp_Client  <|-- BlankBlazorApp
	BlazorWebLib  <|-- BlankBlazorApp
	ServerLib  <|-- BlankBlazorApp
    RemoteCallLib <|-- Telegram_Bot_Polling
	DbPostgreLib <|-- Telegram_Bot_Polling
    RemoteCallLib <|-- StorageService
    RemoteCallLib <|-- HelpdeskService
	DbPostgreLib <|-- HelpdeskService
    BlazorLib <|-- BlazorWebLib
    BlazorLib <|-- BlankBlazorApp_Client
    	
    class CodegeneratorLib{
        Генератор исходников для Web конструктора
    }
    class IdentityLib{
        Контекст пакета Identity (авторизация)
    }
    class DbLayerLib{
        Абстракция над Мульти-СУБД
    }
    class ServerLib{
        Backend для BlankBlazorApp
    }
    class BlazorLib{
        Blazor UI Компоненты
    }
    class DbPostgreLib{
        PSG
    }
    class DbPostgreLib{
        PostgreSQL
    }
    class DbMySQLLib{
        MySQL
    }
    class RemoteCallLib{
        Трансмиссия
    }
    class StorageService{
        @Микросервис
    }
    class HtmlGenerator{
        Внешний репозиторий
    }
    class BlankBlazorApp{
        @Микросервис
    }
    class BlankBlazorApp_Client["BlankBlazorApp.Client"]{
        CSR Blazor WebAssembly
    }
    class Telegram_Bot_Polling["Telegram.Bot.Polling"]{
        @Микросервис
    }
    class BlazorWebLib{
        SSR Blazor Server
    }
    class HelpdeskService{
        @Микросервис        
    }
    class CommerceService{
        @Микросервис        
    }
    class ApiRestService{
        @Микросервис        
    }
Loading

Службы (активные/запускаемые):

Пример того как может быть настроено в VS: пример состава и порядка запуска проектов

1. TelegramBot

Telegram.Bot.Polling - сохраняет все входящие сообщения и позволяет в последствии работать с чатами HelpDesk или другим сервисам решения.

  • В оригинальном исполнении Worker Service2.
  • Ответы на входящие Telegram сообщения обрабатывает реализация интерфейса ITelegramDialogService4. Пользователям можно индивидуально устанавливать имя автоответчика5. Это касается как простых текстовых Message, так и CallbackQuery.
  • Через RabbitMQ служба получает команды от внешних систем, выполняет их, а результат возвращает ответом отправителю (например команда: отправка сообщения Telegram клиенту от имени бота)3.
  • Для обеспечения работы HelpDesk предусмотрен командный режим работы бота. В этом режиме простые текстовые сообщения в бота не обрабатываются автоответчиком (равно как и отправка файлов, документов и т.п.). Сообщения сохраняются, но ответ не формируется если это не команда или CallbackQuery. Команды в TelegramBot начинаются с косой черты (/). Таким образом в командном режиме бот будет пытаться выполнить/бработать входящее сообщение только если текст сообщения является командой: начинается с косой черты (/) либо в случае если это CallbackQuery, а в остальных случаях клиент будет в свободной форме вести чат с ботом, а операторы HelpDesk должны будут ему отвечать от имени бота через WEB интерфейс.

2. WEB: BlazorWebApp

BlankBlazorApp - Blazor вэб сервер.

  • Рендеринг: InteractiveServerRenderMode(prerender: false)
  • Авторизация типовая Microsoft.AspNetCore.Identity.
  • В Frontend добавлен базовый функционал для работы с Пользователями, Ролями, Claims и Telegram1.
  • Служба равно как и другие службы использует RabbitMQ для обслуживания входящих команд, на которые она зарегистрировала свои обработчики3. Кроме того, Web служба обрабатывает запросы для Identity. У Identity свой автономный контекст БД.

3. Helpdesk

HelpdeskService - система документоооборота со своим собственным контекстом: HelpdeskContext.

4. StorageService

StorageService - общее пространство хранения параметров со своим контекстом: StorageContext. Позволяет разным службам обращаться к параметрам друг друга. Например в Web интерфейсе HelpDesk можно изменить режим работы TelegramBot (бот читает этот параметр при каждом входящем сообщении).

5. Коммерция

CommerceService - подсистема формирования заказов.

6. API

ApiRestService - внешний доступ к системе.

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

Логирование (Nlog)

Nlog пишет и в файлы и в базу данных. Строка подключения к БД в конфигах 'nlog.config'

Настройка

  • Перед запуском служб в Blazor1 потребуются конфиги Email (отправка писем SMTP. в. т.ч. для Identity), а в TelegramBot потребуется токен. MQ настройки потребуются всем сервисам. База данных может быть как SQLite, так и PostgreSQL/MySQL.
  • Помимо стандартных настроек appsettings.json потребуется отдельная папка где будут храниться приватные данные: логины и пароли к внешним системам. В всех службах поиск/загрузка секретов происходит оинаково:
// Secrets
string secretPath = Path.Combine("..", "secrets");
for (int i = 0; i < 5 && !Directory.Exists(secretPath); i++)
  secretPath = Path.Combine("..", secretPath);
if (Directory.Exists(secretPath))
  foreach (string secret in Directory.GetFiles(secretPath, $"*.json"))
    configHost.AddJsonFile(Path.GetFullPath(secret), optional: true, reloadOnChange: true);
else
  logger.Warn("Секреты не найдены");

Приложение ищет папку с именем secret на уровне выше текущей директории приложения, а если не находит нужной папки, то пытается искать её ещё выше и выше в иерархии папок пути относительно исполняемого файла пока не найдёт её. На этапе разработки эти файлы могут лежать например тут: C:\Users\ ИмяПользователя \source\repos\secrets или выше в иерархии папок.

В папке секретов secrets предполагается наличие следующих настроек (одним *.json файлом или разными это не важно. загрузятся все *.json файлы из папки секретов):

  • RabbitMQ подключение потребуется для всех четырёх служб (Telegram.Bot.Polling и BlazorWebApp):
{
  "RabbitMQConfig": {
    "UserName": "ваш_логин_от_rabbitmq",
    "Password": "ваш_пароль_от_rabbitmq",
    "VirtualHost": "/"
  }
}
  • Email (SMTP) потребуется только для службы BlazorWebApp (В том числе для отправки уведомлений подсистемой авторизации Microsoft.AspNetCore.Identity):
{
  "SmtpConfig": {
    "Email": "ваш-email@домен",
    "Login": "логин-для-smtp",
    "Password": "ваш-пароль-для-smtp",
    "Host": "smtp-адрес-хоста",
    "Port": 465
  }
}

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

  • MongoDB:
{
  "MongoDB": {
    "Sheme": "mongodb",
    "Host": "localhost",
    "Port": 27017,
    "Login": "",
    "Password": ""
  }
}

Используется для хранения файлов (вложения в документы и т.п.)

  • Токен TelegramBot нужен только для соответствующей службы Telegram.Bot.Polling:
{
  "BotConfiguration": {
    "BotToken": "ваш-токен-для-бота"
  }
}

Создать бота и получить свой токен можно у @BotFather

Роль Admin (полные права) можно назначить через *.json конфигурацию

У службы BlazorWebApp можно настроить Email адреса клиентов таким образом, что бы закрепить за ними любые произвольные роли. Это полезно, для первого старта приложения: администратор прописывает свой Email под которым он будет авторизовываться с необходимой ему ролью admin, тогда при каждом входе будут проверяться наличие требуемой роли у пользователя. Если необходимых ролей не окажется в системе, то они будут автоматически созданы. Клиент обязательно получит роли, которые ему были прописаны в конфигурации. Пример настроек:

{
  "UserManage": {
    "UpdatesUsersRoles": [
      {
        "EmailUser": "ваш_email@сайт.ru",
        "SetRoles": [ "admin" ]
      },
      {
        "EmailUser": "другой_email@домен.com",
        "SetRoles": [ "manager" ]
      }
    ]
  }
}

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

Footnotes

  1. Стандартная ASP служба Blazor WebApp. За основу взята эта работа. 2 3

  2. WorkerService служба Telegram.Bot.Polling сделана на основе Telegram.Bot.Examples.Polling. 2

  3. Подробнее про реализацию MQ транспорта можно узнать тут. 2 3

  4. Свой обработчик ответа на входящее сообщение Telegram реализуется через интерфейс и регистрации его в Program.cs службы TelegramBot.

  5. Имя обработчика ответов храниться в контексте пользователя. Подробнее тут