smart-bot-factory 0.1.9__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of smart-bot-factory might be problematic. Click here for more details.
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/PKG-INFO +210 -23
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/README.md +209 -22
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/best-valera.py +42 -10
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/pyproject.toml +1 -1
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/core/router.py +6 -6
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/core/router_manager.py +11 -11
- smart_bot_factory-0.2.0/smart_bot_factory/core/telegram_router.py +58 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/creation/bot_builder.py +67 -6
- smart_bot_factory-0.2.0/smart_bot_factory/router/__init__.py +11 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/uv.lock +1 -1
- smart_bot_factory-0.1.9/smart_bot_factory/router/__init__.py +0 -9
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/.github/ISSUE_TEMPLATE//342/234/250-/320/267/320/260/320/277/321/200/320/276/321/201-/321/204/321/203/320/275/320/272/321/206/320/270/320/270.md" +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/.github/ISSUE_TEMPLATE//360/237/220/233-/320/261/320/260/320/263-/321/200/320/265/320/277/320/276/321/200/321/202.md" +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/.github/workflows/ci.yml +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/.github/workflows/publish-private.yml +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/.github/workflows/publish.yml +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/.gitignore +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/.python-version +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/CLIENTS_USAGE.md +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/Dockerfile +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/LICENSE +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/best-valera/prompts/1sales_context.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/best-valera/prompts/2product_info.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/best-valera/prompts/3objection_handling.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/best-valera/prompts/final_instructions.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/best-valera/prompts/help_message.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/best-valera/prompts/welcome_message.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/best-valera/tests/quick_scenarios.yaml +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/best-valera/tests/realistic_scenarios.yaml +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/best-valera/tests/scenario_examples.yaml +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/best-valera/welcome_files/welcome_file_msg.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/best-valera/welcome_files//320/247/320/265/320/272 /320/273/320/270/321/201/321/202 /320/277/320/276 152/320/244/320/227 /320/270 323/320/244/320/227 /320/264/320/273/321/217 /320/274/320/265/320/264/320/270/321/206/320/270/320/275/321/213.pdf" +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/valera/prompts/2product_info.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/valera/prompts/3objection_handling.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/valera/prompts/final_instructions.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/valera/prompts/help_message.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/valera/prompts/welcome_message.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/valera/tests/quick_scenarios.yaml +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/valera/tests/realistic_scenarios.yaml +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/valera/tests/scenario_examples.yaml +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/valera/welcome_files/welcome_file_msg.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/bots/valera/welcome_files//320/247/320/265/320/272 /320/273/320/270/321/201/321/202 /320/277/320/276 152/320/244/320/227 /320/270 323/320/244/320/227 /320/264/320/273/321/217 /320/274/320/265/320/264/320/270/321/206/320/270/320/275/321/213.pdf" +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/configs/valera/cats//320/224/320/276/320/263/320/276/320/262/320/276/321/200.pdf" +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/configs/valera/cats//320/272/320/276/320/275/320/270.jpg" +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/configs/valera/cats//320/272/320/276/321/202.jpg" +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/configs/valera/cats//320/273/320/265/321/201.jpg" +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/configs/valera/tests/fixes_elina.yaml +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/configs/valera/welcome_file//320/247/320/265/320/272 /320/273/320/270/321/201/321/202 /320/277/320/276 152/320/244/320/227 /320/270 323/320/244/320/227 /320/264/320/273/321/217 /320/274/320/265/320/264/320/270/321/206/320/270/320/275/321/213.pdf" +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/create_tag.sh +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/docker-compose.yml +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/env.example +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/requirements.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/save_backup.sh +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/save_fixes.sh +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/__init__.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/admin/__init__.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/admin/admin_logic.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/admin/admin_manager.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/admin/admin_migration.sql +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/admin/admin_tester.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/admin/timeout_checker.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/analytics/analytics_manager.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/cli.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/config.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/configs/growthmed-october-24/prompts/1sales_context.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/configs/growthmed-october-24/prompts/2product_info.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/configs/growthmed-october-24/prompts/3objection_handling.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/configs/growthmed-october-24/prompts/final_instructions.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/configs/growthmed-october-24/prompts/help_message.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/configs/growthmed-october-24/prompts/welcome_message.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/configs/growthmed-october-24/reports/test_20250924_064229.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/configs/growthmed-october-24/reports/test_20250924_064335.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/configs/growthmed-october-24/reports/test_20250924_064638.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/configs/growthmed-october-24/tests/quick_scenarios.yaml +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/configs/growthmed-october-24/tests/realistic_scenarios.yaml +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/configs/growthmed-october-24/tests/scenario_examples.yaml +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/configs/growthmed-october-24/welcome_file/welcome_file_msg.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/configs/growthmed-october-24/welcome_file//320/247/320/265/320/272 /320/273/320/270/321/201/321/202 /320/277/320/276 152/320/244/320/227 /320/270 323/320/244/320/227 /320/264/320/273/321/217 /320/274/320/265/320/264/320/270/321/206/320/270/320/275/321/213.pdf" +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/core/bot_utils.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/core/conversation_manager.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/core/decorators.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/core/message_sender.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/core/states.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/creation/__init__.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/creation/bot_testing.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/database/database_structure.sql +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/database/schema.sql +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/event/__init__.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/handlers/handlers.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/integrations/openai_client.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/integrations/supabase_client.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/message/__init__.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/setup_checker.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/supabase/__init__.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/supabase/client.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/utils/__init__.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/utils/debug_routing.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/utils/prompt_loader.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/smart_bot_factory/utm_link_generator.py +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/system_prompt_example.txt +0 -0
- {smart_bot_factory-0.1.9 → smart_bot_factory-0.2.0}/valera.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: smart-bot-factory
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Библиотека для создания умных чат-ботов
|
|
5
5
|
Author-email: Kopatych <kopatych@example.com>
|
|
6
6
|
License: MIT
|
|
@@ -163,18 +163,24 @@ sbf run my-bot
|
|
|
163
163
|
|
|
164
164
|
### Router System
|
|
165
165
|
|
|
166
|
-
Smart Bot Factory использует
|
|
166
|
+
Smart Bot Factory использует **два типа роутеров** для организации обработчиков:
|
|
167
|
+
|
|
168
|
+
1. **EventRouter** - для бизнес-логики (события, задачи, глобальные обработчики)
|
|
169
|
+
2. **TelegramRouter** - для Telegram команд, сообщений и callback'ов
|
|
167
170
|
|
|
168
171
|
```python
|
|
169
|
-
from smart_bot_factory.router import
|
|
172
|
+
from smart_bot_factory.router import EventRouter, TelegramRouter
|
|
170
173
|
from smart_bot_factory.message import send_message_by_human
|
|
171
174
|
from smart_bot_factory.creation import BotBuilder
|
|
175
|
+
from aiogram import F
|
|
176
|
+
from aiogram.filters import Command
|
|
177
|
+
from aiogram.types import Message
|
|
178
|
+
from aiogram.fsm.context import FSMContext
|
|
172
179
|
|
|
173
|
-
#
|
|
174
|
-
|
|
180
|
+
# EventRouter - для бизнес-логики
|
|
181
|
+
event_router = EventRouter("my_bot_events")
|
|
175
182
|
|
|
176
|
-
|
|
177
|
-
@router.event_handler("appointment_booking", notify=True)
|
|
183
|
+
@event_router.event_handler("appointment_booking", notify=True)
|
|
178
184
|
async def handle_booking(user_id: int, event_data: str):
|
|
179
185
|
"""Обработчик записи на прием"""
|
|
180
186
|
await send_message_by_human(
|
|
@@ -183,15 +189,114 @@ async def handle_booking(user_id: int, event_data: str):
|
|
|
183
189
|
)
|
|
184
190
|
return {"status": "success"}
|
|
185
191
|
|
|
192
|
+
# TelegramRouter - для Telegram команд и сообщений
|
|
193
|
+
telegram_router = TelegramRouter("my_bot_telegram")
|
|
194
|
+
|
|
195
|
+
@telegram_router.router.message(Command("price", "цена"))
|
|
196
|
+
async def handle_price(message: Message, state: FSMContext):
|
|
197
|
+
"""Обработчик команды /price"""
|
|
198
|
+
await message.answer("💰 Наши цены...")
|
|
199
|
+
|
|
200
|
+
@telegram_router.router.message(F.text.contains("помощь"))
|
|
201
|
+
async def handle_help(message: Message, state: FSMContext):
|
|
202
|
+
"""Обработчик запросов помощи"""
|
|
203
|
+
await message.answer("📖 Чем могу помочь?")
|
|
204
|
+
|
|
186
205
|
# Запуск бота
|
|
187
206
|
async def main():
|
|
188
207
|
bot = BotBuilder("my-bot")
|
|
189
|
-
|
|
208
|
+
|
|
209
|
+
# Регистрируем роутеры (можно по одному или несколько сразу)
|
|
210
|
+
bot.register_routers(event_router) # EventRouter
|
|
211
|
+
bot.register_telegram_routers(telegram_router) # TelegramRouter
|
|
212
|
+
|
|
190
213
|
await bot.build()
|
|
191
214
|
await bot.start()
|
|
192
215
|
```
|
|
193
216
|
|
|
194
|
-
###
|
|
217
|
+
### TelegramRouter - Обработчики Telegram
|
|
218
|
+
|
|
219
|
+
**TelegramRouter** позволяет добавлять пользовательские команды и обработчики сообщений в Telegram бота, используя стандартный aiogram API:
|
|
220
|
+
|
|
221
|
+
#### Команды
|
|
222
|
+
|
|
223
|
+
```python
|
|
224
|
+
from smart_bot_factory.router import TelegramRouter
|
|
225
|
+
from aiogram.filters import Command
|
|
226
|
+
from aiogram.types import Message
|
|
227
|
+
from aiogram.fsm.context import FSMContext
|
|
228
|
+
|
|
229
|
+
telegram_router = TelegramRouter("my_commands")
|
|
230
|
+
|
|
231
|
+
@telegram_router.router.message(Command("start", "старт"))
|
|
232
|
+
async def cmd_start(message: Message, state: FSMContext):
|
|
233
|
+
"""Обработчик команды /start"""
|
|
234
|
+
await message.answer("👋 Привет!")
|
|
235
|
+
|
|
236
|
+
@telegram_router.router.message(Command("price"))
|
|
237
|
+
async def cmd_price(message: Message, state: FSMContext):
|
|
238
|
+
"""Обработчик команды /price"""
|
|
239
|
+
await message.answer("💰 Цены:\n1. Базовый - 1000₽\n2. Премиум - 5000₽")
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
#### Фильтры по тексту
|
|
243
|
+
|
|
244
|
+
```python
|
|
245
|
+
from aiogram import F
|
|
246
|
+
|
|
247
|
+
@telegram_router.router.message(F.text.lower().contains("цена"))
|
|
248
|
+
async def handle_price_question(message: Message, state: FSMContext):
|
|
249
|
+
"""Когда пользователь спрашивает о цене"""
|
|
250
|
+
await message.answer("💡 Используйте /price для просмотра цен")
|
|
251
|
+
|
|
252
|
+
@telegram_router.router.message(F.text.startswith("!"))
|
|
253
|
+
async def handle_commands(message: Message, state: FSMContext):
|
|
254
|
+
"""Обработка кастомных команд с !"""
|
|
255
|
+
command = message.text[1:]
|
|
256
|
+
await message.answer(f"Выполняю команду: {command}")
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
#### Callback Query
|
|
260
|
+
|
|
261
|
+
```python
|
|
262
|
+
from aiogram.types import CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton
|
|
263
|
+
|
|
264
|
+
@telegram_router.router.callback_query(F.data.startswith("buy_"))
|
|
265
|
+
async def handle_buy(callback: CallbackQuery, state: FSMContext):
|
|
266
|
+
"""Обработка покупки"""
|
|
267
|
+
product_id = callback.data.split("_")[1]
|
|
268
|
+
await callback.answer("Оформляем...")
|
|
269
|
+
await callback.message.answer(f"✅ Товар {product_id} добавлен в корзину")
|
|
270
|
+
|
|
271
|
+
@telegram_router.router.message(Command("catalog"))
|
|
272
|
+
async def show_catalog(message: Message, state: FSMContext):
|
|
273
|
+
"""Показывает каталог с кнопками"""
|
|
274
|
+
keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
|
275
|
+
[InlineKeyboardButton(text="Купить товар 1", callback_data="buy_1")],
|
|
276
|
+
[InlineKeyboardButton(text="Купить товар 2", callback_data="buy_2")]
|
|
277
|
+
])
|
|
278
|
+
await message.answer("🛍️ Каталог товаров:", reply_markup=keyboard)
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
#### Регистрация нескольких роутеров
|
|
282
|
+
|
|
283
|
+
```python
|
|
284
|
+
# Создаем несколько TelegramRouter для разных модулей
|
|
285
|
+
commands_router = TelegramRouter("commands")
|
|
286
|
+
admin_router = TelegramRouter("admin_commands")
|
|
287
|
+
callbacks_router = TelegramRouter("callbacks")
|
|
288
|
+
|
|
289
|
+
# Регистрируем все сразу
|
|
290
|
+
bot_builder.register_telegram_routers(
|
|
291
|
+
commands_router,
|
|
292
|
+
admin_router,
|
|
293
|
+
callbacks_router
|
|
294
|
+
)
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
**Важно:** TelegramRouter - это обертка над aiogram Router, предоставляющая доступ к полному функционалу aiogram через свойство `.router`.
|
|
298
|
+
|
|
299
|
+
### EventRouter - Типы обработчиков событий
|
|
195
300
|
|
|
196
301
|
#### 1. Event Handlers - Обработчики событий
|
|
197
302
|
|
|
@@ -423,24 +528,81 @@ ADMIN_SESSION_TIMEOUT_MINUTES=30
|
|
|
423
528
|
|
|
424
529
|
### Множественные роутеры
|
|
425
530
|
|
|
531
|
+
#### Регистрация нескольких EventRouter
|
|
532
|
+
|
|
426
533
|
```python
|
|
427
534
|
# handlers/main.py
|
|
428
|
-
main_router =
|
|
535
|
+
main_router = EventRouter("main")
|
|
429
536
|
|
|
430
537
|
# handlers/admin.py
|
|
431
|
-
admin_router =
|
|
538
|
+
admin_router = EventRouter("admin")
|
|
539
|
+
|
|
540
|
+
# handlers/payments.py
|
|
541
|
+
payments_router = EventRouter("payments")
|
|
432
542
|
|
|
433
543
|
# app.py
|
|
434
544
|
bot = BotBuilder("my-bot")
|
|
545
|
+
|
|
546
|
+
# Можно по одному
|
|
435
547
|
bot.register_router(main_router)
|
|
436
548
|
bot.register_router(admin_router)
|
|
549
|
+
|
|
550
|
+
# Или все сразу
|
|
551
|
+
bot.register_routers(main_router, admin_router, payments_router)
|
|
437
552
|
```
|
|
438
553
|
|
|
439
|
-
|
|
554
|
+
#### Регистрация нескольких TelegramRouter
|
|
440
555
|
|
|
441
556
|
```python
|
|
442
|
-
|
|
443
|
-
|
|
557
|
+
# telegram/commands.py
|
|
558
|
+
commands_router = TelegramRouter("commands")
|
|
559
|
+
|
|
560
|
+
@commands_router.router.message(Command("start"))
|
|
561
|
+
async def start(message: Message, state: FSMContext):
|
|
562
|
+
await message.answer("Привет!")
|
|
563
|
+
|
|
564
|
+
# telegram/callbacks.py
|
|
565
|
+
callbacks_router = TelegramRouter("callbacks")
|
|
566
|
+
|
|
567
|
+
@callbacks_router.router.callback_query(F.data.startswith("action_"))
|
|
568
|
+
async def handle_action(callback: CallbackQuery, state: FSMContext):
|
|
569
|
+
await callback.answer("Выполнено!")
|
|
570
|
+
|
|
571
|
+
# app.py
|
|
572
|
+
bot = BotBuilder("my-bot")
|
|
573
|
+
|
|
574
|
+
# Регистрируем несколько Telegram роутеров сразу
|
|
575
|
+
bot.register_telegram_routers(commands_router, callbacks_router)
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
#### Комбинирование EventRouter и TelegramRouter
|
|
579
|
+
|
|
580
|
+
```python
|
|
581
|
+
# Создаем роутеры для разных целей
|
|
582
|
+
event_router = EventRouter("events")
|
|
583
|
+
telegram_router = TelegramRouter("telegram_handlers")
|
|
584
|
+
|
|
585
|
+
# EventRouter - бизнес-логика
|
|
586
|
+
@event_router.event_handler("payment_success")
|
|
587
|
+
async def handle_payment(user_id: int, event_data: str):
|
|
588
|
+
await send_message_by_human(user_id, "✅ Оплата получена!")
|
|
589
|
+
return {"status": "success"}
|
|
590
|
+
|
|
591
|
+
# TelegramRouter - пользовательские команды
|
|
592
|
+
@telegram_router.router.message(Command("balance"))
|
|
593
|
+
async def check_balance(message: Message, state: FSMContext):
|
|
594
|
+
await message.answer("💰 Ваш баланс: 1000₽")
|
|
595
|
+
|
|
596
|
+
# Регистрируем оба типа роутеров
|
|
597
|
+
bot_builder.register_routers(event_router)
|
|
598
|
+
bot_builder.register_telegram_routers(telegram_router)
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
### Вложенные роутеры (EventRouter)
|
|
602
|
+
|
|
603
|
+
```python
|
|
604
|
+
main_router = EventRouter("main")
|
|
605
|
+
payments_router = EventRouter("payments")
|
|
444
606
|
|
|
445
607
|
# Включаем роутер платежей в основной
|
|
446
608
|
main_router.include_router(payments_router)
|
|
@@ -486,17 +648,38 @@ my-project/
|
|
|
486
648
|
```python
|
|
487
649
|
import asyncio
|
|
488
650
|
|
|
489
|
-
from smart_bot_factory.router import
|
|
651
|
+
from smart_bot_factory.router import EventRouter, TelegramRouter
|
|
490
652
|
from smart_bot_factory.message import send_message_by_human, send_message_to_users_by_stage
|
|
491
653
|
from smart_bot_factory.supabase import SupabaseClient
|
|
492
654
|
from smart_bot_factory.creation import BotBuilder
|
|
655
|
+
from aiogram import F
|
|
656
|
+
from aiogram.filters import Command
|
|
657
|
+
from aiogram.types import Message
|
|
658
|
+
from aiogram.fsm.context import FSMContext
|
|
493
659
|
|
|
494
660
|
# Инициализация
|
|
495
|
-
|
|
661
|
+
event_router = EventRouter("medical_bot_events")
|
|
662
|
+
telegram_router = TelegramRouter("medical_bot_telegram")
|
|
496
663
|
supabase_client = SupabaseClient("medical-bot")
|
|
497
664
|
|
|
498
|
-
#
|
|
499
|
-
@router.
|
|
665
|
+
# Пользовательские команды (TelegramRouter)
|
|
666
|
+
@telegram_router.router.message(Command("appointment", "запись"))
|
|
667
|
+
async def cmd_appointment(message: Message, state: FSMContext):
|
|
668
|
+
"""Команда для записи на прием"""
|
|
669
|
+
await message.answer(
|
|
670
|
+
"📅 Для записи на прием укажите:\n"
|
|
671
|
+
"- Ваше имя\n"
|
|
672
|
+
"- Телефон\n"
|
|
673
|
+
"- Желаемая дата и время"
|
|
674
|
+
)
|
|
675
|
+
|
|
676
|
+
@telegram_router.router.message(F.text.lower().contains("цена"))
|
|
677
|
+
async def handle_price_question(message: Message, state: FSMContext):
|
|
678
|
+
"""Вопросы о ценах"""
|
|
679
|
+
await message.answer("💰 Используйте /appointment для записи и уточнения стоимости")
|
|
680
|
+
|
|
681
|
+
# Обработчик записи на прием (EventRouter)
|
|
682
|
+
@event_router.event_handler("appointment_booking", notify=True)
|
|
500
683
|
async def handle_appointment(user_id: int, event_data: str):
|
|
501
684
|
"""Обрабатывает запись на прием к врачу"""
|
|
502
685
|
# event_data: "имя: Иван, телефон: +79991234567, дата: 2025-10-15, время: 14:00"
|
|
@@ -508,8 +691,8 @@ async def handle_appointment(user_id: int, event_data: str):
|
|
|
508
691
|
|
|
509
692
|
return {"status": "success", "data": event_data}
|
|
510
693
|
|
|
511
|
-
# Напоминание за 2 часа до приема
|
|
512
|
-
@
|
|
694
|
+
# Напоминание за 2 часа до приема (EventRouter)
|
|
695
|
+
@event_router.schedule_task(
|
|
513
696
|
"appointment_reminder",
|
|
514
697
|
delay="2h",
|
|
515
698
|
event_type="appointment_booking"
|
|
@@ -522,8 +705,8 @@ async def remind_before_appointment(user_id: int, reminder_text: str):
|
|
|
522
705
|
)
|
|
523
706
|
return {"status": "sent"}
|
|
524
707
|
|
|
525
|
-
# Ночной дайджест для всех
|
|
526
|
-
@
|
|
708
|
+
# Ночной дайджест для всех (EventRouter)
|
|
709
|
+
@event_router.global_handler("daily_digest", delay="24h")
|
|
527
710
|
async def send_daily_digest(digest_text: str):
|
|
528
711
|
"""Отправляет ежедневный дайджест всем активным пользователям"""
|
|
529
712
|
await send_message_to_users_by_stage(
|
|
@@ -535,7 +718,11 @@ async def send_daily_digest(digest_text: str):
|
|
|
535
718
|
# Запуск
|
|
536
719
|
async def main():
|
|
537
720
|
bot = BotBuilder("medical-bot")
|
|
538
|
-
|
|
721
|
+
|
|
722
|
+
# Регистрируем роутеры
|
|
723
|
+
bot.register_routers(event_router) # EventRouter
|
|
724
|
+
bot.register_telegram_routers(telegram_router) # TelegramRouter
|
|
725
|
+
|
|
539
726
|
await bot.build()
|
|
540
727
|
await bot.start()
|
|
541
728
|
|
|
@@ -130,18 +130,24 @@ sbf run my-bot
|
|
|
130
130
|
|
|
131
131
|
### Router System
|
|
132
132
|
|
|
133
|
-
Smart Bot Factory использует
|
|
133
|
+
Smart Bot Factory использует **два типа роутеров** для организации обработчиков:
|
|
134
|
+
|
|
135
|
+
1. **EventRouter** - для бизнес-логики (события, задачи, глобальные обработчики)
|
|
136
|
+
2. **TelegramRouter** - для Telegram команд, сообщений и callback'ов
|
|
134
137
|
|
|
135
138
|
```python
|
|
136
|
-
from smart_bot_factory.router import
|
|
139
|
+
from smart_bot_factory.router import EventRouter, TelegramRouter
|
|
137
140
|
from smart_bot_factory.message import send_message_by_human
|
|
138
141
|
from smart_bot_factory.creation import BotBuilder
|
|
142
|
+
from aiogram import F
|
|
143
|
+
from aiogram.filters import Command
|
|
144
|
+
from aiogram.types import Message
|
|
145
|
+
from aiogram.fsm.context import FSMContext
|
|
139
146
|
|
|
140
|
-
#
|
|
141
|
-
|
|
147
|
+
# EventRouter - для бизнес-логики
|
|
148
|
+
event_router = EventRouter("my_bot_events")
|
|
142
149
|
|
|
143
|
-
|
|
144
|
-
@router.event_handler("appointment_booking", notify=True)
|
|
150
|
+
@event_router.event_handler("appointment_booking", notify=True)
|
|
145
151
|
async def handle_booking(user_id: int, event_data: str):
|
|
146
152
|
"""Обработчик записи на прием"""
|
|
147
153
|
await send_message_by_human(
|
|
@@ -150,15 +156,114 @@ async def handle_booking(user_id: int, event_data: str):
|
|
|
150
156
|
)
|
|
151
157
|
return {"status": "success"}
|
|
152
158
|
|
|
159
|
+
# TelegramRouter - для Telegram команд и сообщений
|
|
160
|
+
telegram_router = TelegramRouter("my_bot_telegram")
|
|
161
|
+
|
|
162
|
+
@telegram_router.router.message(Command("price", "цена"))
|
|
163
|
+
async def handle_price(message: Message, state: FSMContext):
|
|
164
|
+
"""Обработчик команды /price"""
|
|
165
|
+
await message.answer("💰 Наши цены...")
|
|
166
|
+
|
|
167
|
+
@telegram_router.router.message(F.text.contains("помощь"))
|
|
168
|
+
async def handle_help(message: Message, state: FSMContext):
|
|
169
|
+
"""Обработчик запросов помощи"""
|
|
170
|
+
await message.answer("📖 Чем могу помочь?")
|
|
171
|
+
|
|
153
172
|
# Запуск бота
|
|
154
173
|
async def main():
|
|
155
174
|
bot = BotBuilder("my-bot")
|
|
156
|
-
|
|
175
|
+
|
|
176
|
+
# Регистрируем роутеры (можно по одному или несколько сразу)
|
|
177
|
+
bot.register_routers(event_router) # EventRouter
|
|
178
|
+
bot.register_telegram_routers(telegram_router) # TelegramRouter
|
|
179
|
+
|
|
157
180
|
await bot.build()
|
|
158
181
|
await bot.start()
|
|
159
182
|
```
|
|
160
183
|
|
|
161
|
-
###
|
|
184
|
+
### TelegramRouter - Обработчики Telegram
|
|
185
|
+
|
|
186
|
+
**TelegramRouter** позволяет добавлять пользовательские команды и обработчики сообщений в Telegram бота, используя стандартный aiogram API:
|
|
187
|
+
|
|
188
|
+
#### Команды
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
from smart_bot_factory.router import TelegramRouter
|
|
192
|
+
from aiogram.filters import Command
|
|
193
|
+
from aiogram.types import Message
|
|
194
|
+
from aiogram.fsm.context import FSMContext
|
|
195
|
+
|
|
196
|
+
telegram_router = TelegramRouter("my_commands")
|
|
197
|
+
|
|
198
|
+
@telegram_router.router.message(Command("start", "старт"))
|
|
199
|
+
async def cmd_start(message: Message, state: FSMContext):
|
|
200
|
+
"""Обработчик команды /start"""
|
|
201
|
+
await message.answer("👋 Привет!")
|
|
202
|
+
|
|
203
|
+
@telegram_router.router.message(Command("price"))
|
|
204
|
+
async def cmd_price(message: Message, state: FSMContext):
|
|
205
|
+
"""Обработчик команды /price"""
|
|
206
|
+
await message.answer("💰 Цены:\n1. Базовый - 1000₽\n2. Премиум - 5000₽")
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
#### Фильтры по тексту
|
|
210
|
+
|
|
211
|
+
```python
|
|
212
|
+
from aiogram import F
|
|
213
|
+
|
|
214
|
+
@telegram_router.router.message(F.text.lower().contains("цена"))
|
|
215
|
+
async def handle_price_question(message: Message, state: FSMContext):
|
|
216
|
+
"""Когда пользователь спрашивает о цене"""
|
|
217
|
+
await message.answer("💡 Используйте /price для просмотра цен")
|
|
218
|
+
|
|
219
|
+
@telegram_router.router.message(F.text.startswith("!"))
|
|
220
|
+
async def handle_commands(message: Message, state: FSMContext):
|
|
221
|
+
"""Обработка кастомных команд с !"""
|
|
222
|
+
command = message.text[1:]
|
|
223
|
+
await message.answer(f"Выполняю команду: {command}")
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
#### Callback Query
|
|
227
|
+
|
|
228
|
+
```python
|
|
229
|
+
from aiogram.types import CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton
|
|
230
|
+
|
|
231
|
+
@telegram_router.router.callback_query(F.data.startswith("buy_"))
|
|
232
|
+
async def handle_buy(callback: CallbackQuery, state: FSMContext):
|
|
233
|
+
"""Обработка покупки"""
|
|
234
|
+
product_id = callback.data.split("_")[1]
|
|
235
|
+
await callback.answer("Оформляем...")
|
|
236
|
+
await callback.message.answer(f"✅ Товар {product_id} добавлен в корзину")
|
|
237
|
+
|
|
238
|
+
@telegram_router.router.message(Command("catalog"))
|
|
239
|
+
async def show_catalog(message: Message, state: FSMContext):
|
|
240
|
+
"""Показывает каталог с кнопками"""
|
|
241
|
+
keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
|
242
|
+
[InlineKeyboardButton(text="Купить товар 1", callback_data="buy_1")],
|
|
243
|
+
[InlineKeyboardButton(text="Купить товар 2", callback_data="buy_2")]
|
|
244
|
+
])
|
|
245
|
+
await message.answer("🛍️ Каталог товаров:", reply_markup=keyboard)
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
#### Регистрация нескольких роутеров
|
|
249
|
+
|
|
250
|
+
```python
|
|
251
|
+
# Создаем несколько TelegramRouter для разных модулей
|
|
252
|
+
commands_router = TelegramRouter("commands")
|
|
253
|
+
admin_router = TelegramRouter("admin_commands")
|
|
254
|
+
callbacks_router = TelegramRouter("callbacks")
|
|
255
|
+
|
|
256
|
+
# Регистрируем все сразу
|
|
257
|
+
bot_builder.register_telegram_routers(
|
|
258
|
+
commands_router,
|
|
259
|
+
admin_router,
|
|
260
|
+
callbacks_router
|
|
261
|
+
)
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
**Важно:** TelegramRouter - это обертка над aiogram Router, предоставляющая доступ к полному функционалу aiogram через свойство `.router`.
|
|
265
|
+
|
|
266
|
+
### EventRouter - Типы обработчиков событий
|
|
162
267
|
|
|
163
268
|
#### 1. Event Handlers - Обработчики событий
|
|
164
269
|
|
|
@@ -390,24 +495,81 @@ ADMIN_SESSION_TIMEOUT_MINUTES=30
|
|
|
390
495
|
|
|
391
496
|
### Множественные роутеры
|
|
392
497
|
|
|
498
|
+
#### Регистрация нескольких EventRouter
|
|
499
|
+
|
|
393
500
|
```python
|
|
394
501
|
# handlers/main.py
|
|
395
|
-
main_router =
|
|
502
|
+
main_router = EventRouter("main")
|
|
396
503
|
|
|
397
504
|
# handlers/admin.py
|
|
398
|
-
admin_router =
|
|
505
|
+
admin_router = EventRouter("admin")
|
|
506
|
+
|
|
507
|
+
# handlers/payments.py
|
|
508
|
+
payments_router = EventRouter("payments")
|
|
399
509
|
|
|
400
510
|
# app.py
|
|
401
511
|
bot = BotBuilder("my-bot")
|
|
512
|
+
|
|
513
|
+
# Можно по одному
|
|
402
514
|
bot.register_router(main_router)
|
|
403
515
|
bot.register_router(admin_router)
|
|
516
|
+
|
|
517
|
+
# Или все сразу
|
|
518
|
+
bot.register_routers(main_router, admin_router, payments_router)
|
|
404
519
|
```
|
|
405
520
|
|
|
406
|
-
|
|
521
|
+
#### Регистрация нескольких TelegramRouter
|
|
407
522
|
|
|
408
523
|
```python
|
|
409
|
-
|
|
410
|
-
|
|
524
|
+
# telegram/commands.py
|
|
525
|
+
commands_router = TelegramRouter("commands")
|
|
526
|
+
|
|
527
|
+
@commands_router.router.message(Command("start"))
|
|
528
|
+
async def start(message: Message, state: FSMContext):
|
|
529
|
+
await message.answer("Привет!")
|
|
530
|
+
|
|
531
|
+
# telegram/callbacks.py
|
|
532
|
+
callbacks_router = TelegramRouter("callbacks")
|
|
533
|
+
|
|
534
|
+
@callbacks_router.router.callback_query(F.data.startswith("action_"))
|
|
535
|
+
async def handle_action(callback: CallbackQuery, state: FSMContext):
|
|
536
|
+
await callback.answer("Выполнено!")
|
|
537
|
+
|
|
538
|
+
# app.py
|
|
539
|
+
bot = BotBuilder("my-bot")
|
|
540
|
+
|
|
541
|
+
# Регистрируем несколько Telegram роутеров сразу
|
|
542
|
+
bot.register_telegram_routers(commands_router, callbacks_router)
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
#### Комбинирование EventRouter и TelegramRouter
|
|
546
|
+
|
|
547
|
+
```python
|
|
548
|
+
# Создаем роутеры для разных целей
|
|
549
|
+
event_router = EventRouter("events")
|
|
550
|
+
telegram_router = TelegramRouter("telegram_handlers")
|
|
551
|
+
|
|
552
|
+
# EventRouter - бизнес-логика
|
|
553
|
+
@event_router.event_handler("payment_success")
|
|
554
|
+
async def handle_payment(user_id: int, event_data: str):
|
|
555
|
+
await send_message_by_human(user_id, "✅ Оплата получена!")
|
|
556
|
+
return {"status": "success"}
|
|
557
|
+
|
|
558
|
+
# TelegramRouter - пользовательские команды
|
|
559
|
+
@telegram_router.router.message(Command("balance"))
|
|
560
|
+
async def check_balance(message: Message, state: FSMContext):
|
|
561
|
+
await message.answer("💰 Ваш баланс: 1000₽")
|
|
562
|
+
|
|
563
|
+
# Регистрируем оба типа роутеров
|
|
564
|
+
bot_builder.register_routers(event_router)
|
|
565
|
+
bot_builder.register_telegram_routers(telegram_router)
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
### Вложенные роутеры (EventRouter)
|
|
569
|
+
|
|
570
|
+
```python
|
|
571
|
+
main_router = EventRouter("main")
|
|
572
|
+
payments_router = EventRouter("payments")
|
|
411
573
|
|
|
412
574
|
# Включаем роутер платежей в основной
|
|
413
575
|
main_router.include_router(payments_router)
|
|
@@ -453,17 +615,38 @@ my-project/
|
|
|
453
615
|
```python
|
|
454
616
|
import asyncio
|
|
455
617
|
|
|
456
|
-
from smart_bot_factory.router import
|
|
618
|
+
from smart_bot_factory.router import EventRouter, TelegramRouter
|
|
457
619
|
from smart_bot_factory.message import send_message_by_human, send_message_to_users_by_stage
|
|
458
620
|
from smart_bot_factory.supabase import SupabaseClient
|
|
459
621
|
from smart_bot_factory.creation import BotBuilder
|
|
622
|
+
from aiogram import F
|
|
623
|
+
from aiogram.filters import Command
|
|
624
|
+
from aiogram.types import Message
|
|
625
|
+
from aiogram.fsm.context import FSMContext
|
|
460
626
|
|
|
461
627
|
# Инициализация
|
|
462
|
-
|
|
628
|
+
event_router = EventRouter("medical_bot_events")
|
|
629
|
+
telegram_router = TelegramRouter("medical_bot_telegram")
|
|
463
630
|
supabase_client = SupabaseClient("medical-bot")
|
|
464
631
|
|
|
465
|
-
#
|
|
466
|
-
@router.
|
|
632
|
+
# Пользовательские команды (TelegramRouter)
|
|
633
|
+
@telegram_router.router.message(Command("appointment", "запись"))
|
|
634
|
+
async def cmd_appointment(message: Message, state: FSMContext):
|
|
635
|
+
"""Команда для записи на прием"""
|
|
636
|
+
await message.answer(
|
|
637
|
+
"📅 Для записи на прием укажите:\n"
|
|
638
|
+
"- Ваше имя\n"
|
|
639
|
+
"- Телефон\n"
|
|
640
|
+
"- Желаемая дата и время"
|
|
641
|
+
)
|
|
642
|
+
|
|
643
|
+
@telegram_router.router.message(F.text.lower().contains("цена"))
|
|
644
|
+
async def handle_price_question(message: Message, state: FSMContext):
|
|
645
|
+
"""Вопросы о ценах"""
|
|
646
|
+
await message.answer("💰 Используйте /appointment для записи и уточнения стоимости")
|
|
647
|
+
|
|
648
|
+
# Обработчик записи на прием (EventRouter)
|
|
649
|
+
@event_router.event_handler("appointment_booking", notify=True)
|
|
467
650
|
async def handle_appointment(user_id: int, event_data: str):
|
|
468
651
|
"""Обрабатывает запись на прием к врачу"""
|
|
469
652
|
# event_data: "имя: Иван, телефон: +79991234567, дата: 2025-10-15, время: 14:00"
|
|
@@ -475,8 +658,8 @@ async def handle_appointment(user_id: int, event_data: str):
|
|
|
475
658
|
|
|
476
659
|
return {"status": "success", "data": event_data}
|
|
477
660
|
|
|
478
|
-
# Напоминание за 2 часа до приема
|
|
479
|
-
@
|
|
661
|
+
# Напоминание за 2 часа до приема (EventRouter)
|
|
662
|
+
@event_router.schedule_task(
|
|
480
663
|
"appointment_reminder",
|
|
481
664
|
delay="2h",
|
|
482
665
|
event_type="appointment_booking"
|
|
@@ -489,8 +672,8 @@ async def remind_before_appointment(user_id: int, reminder_text: str):
|
|
|
489
672
|
)
|
|
490
673
|
return {"status": "sent"}
|
|
491
674
|
|
|
492
|
-
# Ночной дайджест для всех
|
|
493
|
-
@
|
|
675
|
+
# Ночной дайджест для всех (EventRouter)
|
|
676
|
+
@event_router.global_handler("daily_digest", delay="24h")
|
|
494
677
|
async def send_daily_digest(digest_text: str):
|
|
495
678
|
"""Отправляет ежедневный дайджест всем активным пользователям"""
|
|
496
679
|
await send_message_to_users_by_stage(
|
|
@@ -502,7 +685,11 @@ async def send_daily_digest(digest_text: str):
|
|
|
502
685
|
# Запуск
|
|
503
686
|
async def main():
|
|
504
687
|
bot = BotBuilder("medical-bot")
|
|
505
|
-
|
|
688
|
+
|
|
689
|
+
# Регистрируем роутеры
|
|
690
|
+
bot.register_routers(event_router) # EventRouter
|
|
691
|
+
bot.register_telegram_routers(telegram_router) # TelegramRouter
|
|
692
|
+
|
|
506
693
|
await bot.build()
|
|
507
694
|
await bot.start()
|
|
508
695
|
|