smart-bot-factory 0.1.6__py3-none-any.whl → 0.1.8__py3-none-any.whl

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/cli.py CHANGED
@@ -408,15 +408,10 @@ def list_bots_in_bots_folder() -> list:
408
408
 
409
409
  def create_bot_template(bot_id: str) -> str:
410
410
  """Создает шаблон основного файла бота"""
411
- return f'''#!/usr/bin/env python3
412
- """
413
- Бот {bot_id} - создан с помощью Smart Bot Factory
414
- """
415
-
416
- import asyncio
411
+ return f'''import asyncio
417
412
 
418
413
  from smart_bot_factory.router import Router
419
- from smart_bot_factory.message import send_message_by_human
414
+ from smart_bot_factory.message import send_message_by_human, send_message_to_users_by_stage
420
415
  from smart_bot_factory.supabase import SupabaseClient
421
416
  from smart_bot_factory.creation import BotBuilder
422
417
 
@@ -447,7 +442,7 @@ async def handle_example_event(user_id: int, event_data: str):
447
442
  # ВРЕМЕННЫЕ ЗАДАЧИ ДЛЯ ОДНОГО ПОЛЬЗОВАТЕЛЯ
448
443
  # =============================================================================
449
444
 
450
- @router.schedule_task("send_reminder")
445
+ @router.schedule_task("send_reminder", delay="1h")
451
446
  async def send_user_reminder(user_id: int, reminder_text: str):
452
447
  """Отправляет напоминание пользователю"""
453
448
  await send_message_by_human(
@@ -464,61 +459,15 @@ async def send_user_reminder(user_id: int, reminder_text: str):
464
459
  # ГЛОБАЛЬНЫЕ ОБРАБОТЧИКИ (для всех пользователей)
465
460
  # =============================================================================
466
461
 
467
- @router.global_handler("mass_notification", notify=True)
462
+ @router.global_handler("mass_notification", delay="1h", notify=True)
468
463
  async def send_global_announcement(announcement_text: str):
469
464
  """Отправляет анонс всем пользователям бота"""
470
- import logging
471
- logger = logging.getLogger(__name__)
472
-
473
- logger.info(f"🚀 Начинаем глобальную рассылку: '{{announcement_text[:50]}}...'")
474
-
475
- # Проверяем доступность клиента
476
- if not supabase_client:
477
- logger.error("❌ Supabase клиент не найден для глобальной рассылки")
478
- return {{"status": "error", "message": "Supabase клиент не найден"}}
479
-
480
- try:
481
- # Получаем всех пользователей из БД с учетом bot_id (изоляция данных)
482
- users_response = supabase_client.client.table('sales_users').select(
483
- 'telegram_id'
484
- ).eq('bot_id', supabase_client.bot_id).execute()
485
-
486
- if not users_response.data:
487
- logger.warning("⚠️ Пользователи не найдены для глобальной рассылки")
488
- return {{"status": "no_users", "message": "Пользователи не найдены"}}
489
-
490
- total_users = len(users_response.data)
491
- logger.info(f"👥 Найдено {{total_users}} пользователей для рассылки")
492
-
493
- # Отправляем сообщение каждому пользователю
494
- sent_count = 0
495
- failed_count = 0
496
-
497
- for user in users_response.data:
498
- try:
499
- await send_message_by_human(
500
- user_id=user['telegram_id'],
501
- message_text=f"📢 {{announcement_text}}"
502
- )
503
- sent_count += 1
504
- # Небольшая задержка между отправками
505
- await asyncio.sleep(0.1)
506
-
507
- except Exception as e:
508
- logger.error(f"❌ Ошибка отправки пользователю {{user['telegram_id']}}: {{e}}")
509
- failed_count += 1
510
-
511
- return {{
512
- "status": "completed",
513
- "sent_count": sent_count,
514
- "failed_count": failed_count,
515
- "total_users": total_users,
516
- "message": f"Рассылка завершена: {{sent_count}} отправлено, {{failed_count}} ошибок"
517
- }}
518
-
519
- except Exception as e:
520
- logger.error(f"❌ Критическая ошибка глобальной рассылки: {{e}}")
521
- return {{"status": "error", "message": str(e)}}
465
+
466
+ await send_message_to_users_by_stage(
467
+ stage="introduction",
468
+ message_text=announcement_text,
469
+ bot_id="{bot_id}"
470
+ )
522
471
 
523
472
  # =============================================================================
524
473
  # ОСНОВНАЯ ФУНКЦИЯ
@@ -73,8 +73,6 @@ id этапа бери из stages
73
73
  ТРЕБОВАНИЯ К формату:
74
74
  - Всегда используй кавычки для строк
75
75
  - Если в инструкциях явно не указано, что надо выслать какое-то событие, отсылай пустой массив []
76
- - Если надо выслать какое либо событие и в инструкции написано запустить через какое то время, то в поле инфо нужно вывести число в СЕКУНДАХ
77
- - Также в событиях связанных со временем может быть дополнительная информация, например инфо='30|Привет пользователь!' - 30 это время в секундах после | доп информация
78
76
  - Если в инструкциях явно не указано, что надо вставить в служебную информацию какой-то файл(ы) или каталоги, отсылай пустой массив
79
77
 
80
78
  ФАЙЛЫ:
@@ -19,6 +19,8 @@ from ..core.decorators import (
19
19
  save_immediate_event,
20
20
  schedule_task_for_later_with_db,
21
21
  schedule_global_handler_for_later_with_db,
22
+ execute_scheduled_task_from_event,
23
+ execute_global_handler_from_event,
22
24
  update_event_result
23
25
  )
24
26
 
@@ -205,12 +207,14 @@ async def process_events(session_id: str, events: list, user_id: int):
205
207
  event_handlers = router_manager.get_event_handlers()
206
208
  scheduled_tasks = router_manager.get_scheduled_tasks()
207
209
  global_handlers = router_manager.get_global_handlers()
208
- logger.debug(f"🔍 RouterManager найден: {len(global_handlers)} глобальных обработчиков")
210
+ logger.debug(f"🔍 RouterManager найден: {len(event_handlers)} событий, {len(scheduled_tasks)} задач, {len(global_handlers)} глобальных обработчиков")
211
+ logger.debug(f"🔍 Доступные scheduled_tasks: {list(scheduled_tasks.keys())}")
209
212
  else:
210
213
  event_handlers = _event_handlers
211
214
  scheduled_tasks = _scheduled_tasks
212
215
  global_handlers = _global_handlers
213
216
  logger.warning("⚠️ RouterManager не найден, используем старые декораторы")
217
+ logger.debug(f"🔍 Старые scheduled_tasks: {list(scheduled_tasks.keys())}")
214
218
 
215
219
  # Сначала пробуем как обычное событие
216
220
  if event_type in event_handlers:
@@ -229,19 +233,12 @@ async def process_events(session_id: str, events: list, user_id: int):
229
233
  # Если не user_event, пробуем как запланированную задачу
230
234
  elif event_type in scheduled_tasks:
231
235
  try:
232
- # Извлекаем время из event_info (AI должен передавать число секунд)
233
- try:
234
- delay_seconds = int(event_info)
235
- except ValueError:
236
- # Если не число, используем значение по умолчанию
237
- delay_seconds = 3600
238
- logger.warning(f" ⚠️ Не удалось извлечь время из '{event_info}', используем 3600с")
239
-
240
- logger.info(f" ⏰ Сохраняем как scheduled_task: '{event_type}' через {delay_seconds}с")
241
- result = await schedule_task_for_later_with_db(event_type, user_id, event_info, delay_seconds, session_id)
242
- event_id = result['event_id']
236
+ # Используем новую логику - время берется из декоратора
237
+ logger.info(f" ⏰ Планируем scheduled_task: '{event_type}' с данными: '{event_info}'")
238
+ result = await execute_scheduled_task_from_event(user_id, event_type, event_info, session_id)
239
+ event_id = result.get('event_id', 'unknown')
243
240
  should_notify = result.get('notify', False)
244
- logger.info(f" 💾 Задача сохранена в БД: {event_id}")
241
+ logger.info(f" 💾 Задача запланирована: {event_id}")
245
242
 
246
243
  except Exception as e:
247
244
  if "once_only=True" in str(e):
@@ -254,19 +251,12 @@ async def process_events(session_id: str, events: list, user_id: int):
254
251
  # Если не scheduled_task, пробуем как глобальный обработчик
255
252
  elif event_type in global_handlers:
256
253
  try:
257
- # Извлекаем время из event_info (AI должен передавать число секунд)
258
- try:
259
- delay_seconds = int(event_info)
260
- except ValueError:
261
- # Если не число, используем значение по умолчанию
262
- delay_seconds = 3600
263
- logger.warning(f" ⚠️ Не удалось извлечь время из '{event_info}', используем 3600с")
264
-
265
- logger.info(f" 🌍 Сохраняем как global_handler: '{event_type}' через {delay_seconds}с")
266
- result = await schedule_global_handler_for_later_with_db(event_type, delay_seconds, event_info)
267
- event_id = result['event_id']
254
+ # Используем новую логику - время берется из декоратора
255
+ logger.info(f" 🌍 Планируем global_handler: '{event_type}' с данными: '{event_info}'")
256
+ result = await execute_global_handler_from_event(event_type, event_info)
257
+ event_id = result.get('event_id', 'unknown')
268
258
  should_notify = result.get('notify', False)
269
- logger.info(f" 💾 Глобальное событие сохранено в БД: {event_id}")
259
+ logger.info(f" 💾 Глобальное событие запланировано: {event_id}")
270
260
 
271
261
  except Exception as e:
272
262
  if "once_only=True" in str(e):