- Blazor NET.81 + TelegramBot2: подойдёт как стартовый кейс web решения с поддержкой Telegram бота.
- Связь между службами через RabbitMQ3 в режиме
запрос-ответ
: при отправке сообщения в очередь, отправитель дожидается ответ (в границах таймаута) и возвращает результат вызывающему. При использовании вызова такой команды удалённого сервиса проходит так, как если бы это был обычныйawait
запрос к базе данных или rest/api. - 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{
@Микросервис
}
Пример того как может быть настроено в VS:
Telegram.Bot.Polling - сохраняет все входящие сообщения и позволяет в последствии работать с чатами HelpDesk или другим сервисам решения.
- В оригинальном исполнении
Worker Service
2. - Ответы на входящие Telegram сообщения обрабатывает реализация интерфейса
ITelegramDialogService
4. Пользователям можно индивидуально устанавливать имя автоответчика5. Это касается как простых текстовыхMessage
, так иCallbackQuery
. - Через RabbitMQ служба получает команды от внешних систем, выполняет их, а результат возвращает ответом отправителю (например команда: отправка сообщения Telegram клиенту от имени бота)3.
- Для обеспечения работы HelpDesk предусмотрен командный режим работы бота. В этом режиме простые текстовые сообщения в бота не обрабатываются автоответчиком (равно как и отправка файлов, документов и т.п.). Сообщения сохраняются, но ответ не формируется если это не команда или CallbackQuery. Команды в TelegramBot начинаются с косой черты (/). Таким образом в командном режиме бот будет пытаться выполнить/бработать входящее сообщение только если текст сообщения является командой: начинается с косой черты (/) либо в случае если это CallbackQuery, а в остальных случаях клиент будет в свободной форме вести чат с ботом, а операторы HelpDesk должны будут ему отвечать от имени бота через WEB интерфейс.
BlankBlazorApp - Blazor вэб сервер.
- Рендеринг:
InteractiveServerRenderMode(prerender: false)
- Авторизация типовая
Microsoft.AspNetCore.Identity
. - В Frontend добавлен базовый функционал для работы с Пользователями, Ролями, Claims и Telegram1.
- Служба равно как и другие службы использует RabbitMQ для обслуживания входящих команд, на которые она зарегистрировала свои обработчики3. Кроме того, Web служба обрабатывает запросы для Identity. У Identity свой автономный контекст БД.
HelpdeskService - система документоооборота со своим собственным контекстом: HelpdeskContext
.
StorageService - общее пространство хранения параметров со своим контекстом: StorageContext
. Позволяет разным службам обращаться к параметрам друг друга. Например в Web интерфейсе HelpDesk можно изменить режим работы TelegramBot (бот читает этот параметр при каждом входящем сообщении).
CommerceService - подсистема формирования заказов.
ApiRestService - внешний доступ к системе.
все службы должны быть настроены, запущены вместе и соединены общим RabbitMQ. В противном случае в MQ очередях будут копиться запросы без ответов и функционал местами будет недоступен если ответственная служба не будет обрабатывать запросы.
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
У службы BlazorWebApp
можно настроить Email адреса клиентов таким образом, что бы закрепить за ними любые произвольные роли. Это полезно, для первого старта приложения: администратор прописывает свой Email под которым он будет авторизовываться с необходимой ему ролью admin
, тогда при каждом входе будут проверяться наличие требуемой роли у пользователя. Если необходимых ролей не окажется в системе, то они будут автоматически созданы. Клиент обязательно получит роли, которые ему были прописаны в конфигурации. Пример настроек:
{
"UserManage": {
"UpdatesUsersRoles": [
{
"EmailUser": "ваш_email@сайт.ru",
"SetRoles": [ "admin" ]
},
{
"EmailUser": "другой_email@домен.com",
"SetRoles": [ "manager" ]
}
]
}
}
прописать можно любые роли любым клиентам. после этого им нужно залогиниться - нужные роли обязательно окажутся у клиента. после того как требуемые роли назначены - эти настройки рекомендуется удалить. наличие таких конфигов делает невозможными попытки лишить пользователей этих ролей в связи с тем что они будут проверяться и выдаваться при каждом входе клиента.
Footnotes
-
Стандартная ASP служба Blazor WebApp. За основу взята эта работа. ↩ ↩2 ↩3
-
WorkerService служба Telegram.Bot.Polling сделана на основе Telegram.Bot.Examples.Polling. ↩ ↩2
-
Подробнее про реализацию MQ транспорта можно узнать тут. ↩ ↩2 ↩3
-
Свой обработчик ответа на входящее сообщение Telegram реализуется через интерфейс и регистрации его в Program.cs службы TelegramBot. ↩
-
Имя обработчика ответов храниться в контексте пользователя. Подробнее тут ↩