smart-bot-factory 1.1.1__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.
- smart_bot_factory/__init__.py +3 -0
- smart_bot_factory/admin/__init__.py +18 -0
- smart_bot_factory/admin/admin_events.py +1223 -0
- smart_bot_factory/admin/admin_logic.py +553 -0
- smart_bot_factory/admin/admin_manager.py +156 -0
- smart_bot_factory/admin/admin_tester.py +157 -0
- smart_bot_factory/admin/timeout_checker.py +547 -0
- smart_bot_factory/aiogram_calendar/__init__.py +14 -0
- smart_bot_factory/aiogram_calendar/common.py +64 -0
- smart_bot_factory/aiogram_calendar/dialog_calendar.py +259 -0
- smart_bot_factory/aiogram_calendar/schemas.py +99 -0
- smart_bot_factory/aiogram_calendar/simple_calendar.py +224 -0
- smart_bot_factory/analytics/analytics_manager.py +414 -0
- smart_bot_factory/cli.py +806 -0
- smart_bot_factory/config.py +258 -0
- smart_bot_factory/configs/growthmed-october-24/prompts/1sales_context.txt +16 -0
- smart_bot_factory/configs/growthmed-october-24/prompts/2product_info.txt +582 -0
- smart_bot_factory/configs/growthmed-october-24/prompts/3objection_handling.txt +66 -0
- smart_bot_factory/configs/growthmed-october-24/prompts/final_instructions.txt +212 -0
- smart_bot_factory/configs/growthmed-october-24/prompts/help_message.txt +28 -0
- smart_bot_factory/configs/growthmed-october-24/prompts/welcome_message.txt +8 -0
- smart_bot_factory/configs/growthmed-october-24/reports/test_20250924_064229.txt +818 -0
- smart_bot_factory/configs/growthmed-october-24/reports/test_20250924_064335.txt +32 -0
- smart_bot_factory/configs/growthmed-october-24/reports/test_20250924_064638.txt +35 -0
- smart_bot_factory/configs/growthmed-october-24/tests/quick_scenarios.yaml +133 -0
- smart_bot_factory/configs/growthmed-october-24/tests/realistic_scenarios.yaml +108 -0
- smart_bot_factory/configs/growthmed-october-24/tests/scenario_examples.yaml +46 -0
- smart_bot_factory/configs/growthmed-october-24/welcome_file/welcome_file_msg.txt +16 -0
- smart_bot_factory/configs/growthmed-october-24/welcome_file//342/225/250/320/267/342/225/250/342/225/241/342/225/250/342/225/221 /342/225/250/342/225/227/342/225/250/342/225/225/342/225/244/320/221/342/225/244/320/222 /342/225/250/342/224/220/342/225/250/342/225/233 152/342/225/250/320/264/342/225/250/320/247 /342/225/250/342/225/225 323/342/225/250/320/264/342/225/250/320/247 /342/225/250/342/224/244/342/225/250/342/225/227/342/225/244/320/237 /342/225/250/342/225/235/342/225/250/342/225/241/342/225/250/342/224/244/342/225/250/342/225/225/342/225/244/320/226/342/225/250/342/225/225/342/225/250/342/225/234/342/225/244/320/233.pdf +0 -0
- smart_bot_factory/core/bot_utils.py +1108 -0
- smart_bot_factory/core/conversation_manager.py +653 -0
- smart_bot_factory/core/decorators.py +2464 -0
- smart_bot_factory/core/message_sender.py +729 -0
- smart_bot_factory/core/router.py +347 -0
- smart_bot_factory/core/router_manager.py +218 -0
- smart_bot_factory/core/states.py +27 -0
- smart_bot_factory/creation/__init__.py +7 -0
- smart_bot_factory/creation/bot_builder.py +1093 -0
- smart_bot_factory/creation/bot_testing.py +1122 -0
- smart_bot_factory/dashboard/__init__.py +3 -0
- smart_bot_factory/event/__init__.py +7 -0
- smart_bot_factory/handlers/handlers.py +2013 -0
- smart_bot_factory/integrations/langchain_openai.py +542 -0
- smart_bot_factory/integrations/openai_client.py +513 -0
- smart_bot_factory/integrations/supabase_client.py +1678 -0
- smart_bot_factory/memory/__init__.py +8 -0
- smart_bot_factory/memory/memory_manager.py +299 -0
- smart_bot_factory/memory/static_memory.py +214 -0
- smart_bot_factory/message/__init__.py +56 -0
- smart_bot_factory/rag/__init__.py +5 -0
- smart_bot_factory/rag/decorators.py +29 -0
- smart_bot_factory/rag/router.py +54 -0
- smart_bot_factory/rag/templates/__init__.py +3 -0
- smart_bot_factory/rag/templates/create_table.sql +7 -0
- smart_bot_factory/rag/templates/create_table_and_function_template.py +94 -0
- smart_bot_factory/rag/templates/match_function.sql +61 -0
- smart_bot_factory/rag/templates/match_services_template.py +82 -0
- smart_bot_factory/rag/vectorstore.py +449 -0
- smart_bot_factory/router/__init__.py +10 -0
- smart_bot_factory/setup_checker.py +512 -0
- smart_bot_factory/supabase/__init__.py +7 -0
- smart_bot_factory/supabase/client.py +631 -0
- smart_bot_factory/utils/__init__.py +11 -0
- smart_bot_factory/utils/debug_routing.py +114 -0
- smart_bot_factory/utils/prompt_loader.py +529 -0
- smart_bot_factory/utils/tool_router.py +68 -0
- smart_bot_factory/utils/user_prompt_loader.py +55 -0
- smart_bot_factory/utm_link_generator.py +123 -0
- smart_bot_factory-1.1.1.dist-info/METADATA +1135 -0
- smart_bot_factory-1.1.1.dist-info/RECORD +73 -0
- smart_bot_factory-1.1.1.dist-info/WHEEL +4 -0
- smart_bot_factory-1.1.1.dist-info/entry_points.txt +2 -0
- smart_bot_factory-1.1.1.dist-info/licenses/LICENSE +24 -0
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Модуль для проверки настройки Telegram Sales Bot v2.0 (с админской системой)
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import logging
|
|
7
|
+
import os
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import List, Optional, Tuple
|
|
11
|
+
|
|
12
|
+
from .admin.admin_manager import AdminManager
|
|
13
|
+
from .analytics.analytics_manager import AnalyticsManager
|
|
14
|
+
from .config import Config
|
|
15
|
+
from .core.bot_utils import parse_ai_response
|
|
16
|
+
from .core.conversation_manager import ConversationManager
|
|
17
|
+
from .integrations.openai_client import OpenAIClient
|
|
18
|
+
from .integrations.supabase_client import SupabaseClient
|
|
19
|
+
from .utils.prompt_loader import PromptLoader
|
|
20
|
+
|
|
21
|
+
logger = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def setup_bot_environment(bot_name: str = "growthmed-october-24") -> Optional[Path]:
|
|
25
|
+
"""
|
|
26
|
+
Настраивает окружение для указанного бота с автоопределением BOT_ID
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
bot_name: Имя бота для настройки
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
Optional[Path]: Путь к корневой директории проекта, если настройка успешна, None в случае ошибки
|
|
33
|
+
"""
|
|
34
|
+
root_dir = Path(os.getcwd()) # Используем текущую директорию как корневую
|
|
35
|
+
config_dir = root_dir / "bots" / bot_name
|
|
36
|
+
|
|
37
|
+
if not config_dir.exists():
|
|
38
|
+
logger.error(f"❌ Папка конфигурации не найдена: {config_dir}")
|
|
39
|
+
logger.info(" Доступные боты:")
|
|
40
|
+
bots_dir = root_dir / "bots"
|
|
41
|
+
if bots_dir.exists():
|
|
42
|
+
for bot_dir in bots_dir.iterdir():
|
|
43
|
+
if bot_dir.is_dir():
|
|
44
|
+
logger.info(f" - {bot_dir.name}")
|
|
45
|
+
return None
|
|
46
|
+
|
|
47
|
+
# Устанавливаем BOT_ID из имени бота
|
|
48
|
+
os.environ["BOT_ID"] = bot_name
|
|
49
|
+
logger.info(f"🤖 Автоматически установлен BOT_ID: {bot_name}")
|
|
50
|
+
|
|
51
|
+
# Загружаем .env из конфигурации бота
|
|
52
|
+
env_file = config_dir / ".env"
|
|
53
|
+
if env_file.exists():
|
|
54
|
+
logger.info(f"🔧 Загружаем .env из: {env_file}")
|
|
55
|
+
from dotenv import load_dotenv
|
|
56
|
+
|
|
57
|
+
load_dotenv(env_file)
|
|
58
|
+
else:
|
|
59
|
+
logger.error(f"❌ Файл .env не найден: {env_file}")
|
|
60
|
+
return None
|
|
61
|
+
|
|
62
|
+
# Меняем рабочую директорию
|
|
63
|
+
os.chdir(str(config_dir))
|
|
64
|
+
logger.info(f"📁 Рабочая директория: {config_dir}")
|
|
65
|
+
|
|
66
|
+
return root_dir
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
async def check_config() -> Optional[Config]:
|
|
70
|
+
"""Проверяем конфигурацию с новыми админскими настройками"""
|
|
71
|
+
try:
|
|
72
|
+
config = Config()
|
|
73
|
+
|
|
74
|
+
logger.info("✅ Конфигурация загружена успешно")
|
|
75
|
+
logger.info("📋 Сводка конфигурации:")
|
|
76
|
+
|
|
77
|
+
summary = config.get_summary()
|
|
78
|
+
for key, value in summary.items():
|
|
79
|
+
logger.info(f" • {key}: {value}")
|
|
80
|
+
|
|
81
|
+
# Проверяем админские настройки
|
|
82
|
+
logger.info("\n👑 Админские настройки:")
|
|
83
|
+
logger.info(f" • Админов настроено: {len(config.ADMIN_TELEGRAM_IDS)}")
|
|
84
|
+
if config.ADMIN_TELEGRAM_IDS:
|
|
85
|
+
logger.info(f" • ID админов: {config.ADMIN_TELEGRAM_IDS}")
|
|
86
|
+
logger.info(f" • Таймаут сессий: {config.ADMIN_SESSION_TIMEOUT_MINUTES} мин")
|
|
87
|
+
logger.info(
|
|
88
|
+
f" • Режим отладки: {'Включен' if config.DEBUG_MODE else 'Выключен'}"
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
return config
|
|
92
|
+
except Exception as e:
|
|
93
|
+
logger.error(f"❌ Ошибка конфигурации: {e}")
|
|
94
|
+
return None
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
async def check_supabase(config: Config) -> bool:
|
|
98
|
+
"""Проверяем подключение к Supabase и новые таблицы"""
|
|
99
|
+
try:
|
|
100
|
+
client = SupabaseClient(config.SUPABASE_URL, config.SUPABASE_KEY)
|
|
101
|
+
await client.initialize()
|
|
102
|
+
|
|
103
|
+
# Пробуем выполнить простой запрос к основной таблицеы
|
|
104
|
+
client.client.table("sales_users").select("id").limit(1).execute()
|
|
105
|
+
logger.info("✅ Supabase подключение успешно")
|
|
106
|
+
|
|
107
|
+
# Проверяем новые таблицы админской системы
|
|
108
|
+
admin_tables = ["sales_admins", "admin_user_conversations", "session_events"]
|
|
109
|
+
|
|
110
|
+
logger.info("🔍 Проверка админских таблиц:")
|
|
111
|
+
for table in admin_tables:
|
|
112
|
+
try:
|
|
113
|
+
client.client.table(table).select("*").limit(1).execute()
|
|
114
|
+
logger.info(f" ✅ {table}")
|
|
115
|
+
except Exception as e:
|
|
116
|
+
logger.error(f" ❌ {table}: {e}")
|
|
117
|
+
|
|
118
|
+
# Проверяем новые колонки
|
|
119
|
+
logger.info("🔍 Проверка новых колонок:")
|
|
120
|
+
try:
|
|
121
|
+
(
|
|
122
|
+
client.client.table("sales_chat_sessions")
|
|
123
|
+
.select("current_stage", "lead_quality_score")
|
|
124
|
+
.limit(1)
|
|
125
|
+
.execute()
|
|
126
|
+
)
|
|
127
|
+
logger.info(" ✅ sales_chat_sessions: current_stage, lead_quality_score")
|
|
128
|
+
except Exception as e:
|
|
129
|
+
logger.error(f" ❌ sales_chat_sessions новые колонки: {e}")
|
|
130
|
+
|
|
131
|
+
try:
|
|
132
|
+
(
|
|
133
|
+
client.client.table("sales_messages")
|
|
134
|
+
.select("ai_metadata")
|
|
135
|
+
.limit(1)
|
|
136
|
+
.execute()
|
|
137
|
+
)
|
|
138
|
+
logger.info(" ✅ sales_messages: ai_metadata")
|
|
139
|
+
except Exception as e:
|
|
140
|
+
logger.error(f" ❌ sales_messages.ai_metadata: {e}")
|
|
141
|
+
|
|
142
|
+
return True
|
|
143
|
+
except Exception as e:
|
|
144
|
+
logger.error(f"❌ Ошибка Supabase: {e}")
|
|
145
|
+
return False
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
async def check_openai(config: Config) -> bool:
|
|
149
|
+
"""Проверяем OpenAI API"""
|
|
150
|
+
try:
|
|
151
|
+
client = OpenAIClient(
|
|
152
|
+
config.OPENAI_API_KEY,
|
|
153
|
+
config.OPENAI_MODEL,
|
|
154
|
+
config.OPENAI_MAX_TOKENS,
|
|
155
|
+
config.OPENAI_TEMPERATURE,
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
health = await client.check_api_health()
|
|
159
|
+
|
|
160
|
+
if health:
|
|
161
|
+
logger.info("✅ OpenAI API доступен")
|
|
162
|
+
|
|
163
|
+
# Получаем список доступных моделей
|
|
164
|
+
models = await client.get_available_models()
|
|
165
|
+
if config.OPENAI_MODEL in models:
|
|
166
|
+
logger.info(f"✅ Модель {config.OPENAI_MODEL} доступна")
|
|
167
|
+
else:
|
|
168
|
+
logger.warning(f"⚠️ Модель {config.OPENAI_MODEL} не найдена в доступных")
|
|
169
|
+
logger.info(f" Доступные модели: {models[:5]}...")
|
|
170
|
+
|
|
171
|
+
return health
|
|
172
|
+
except Exception as e:
|
|
173
|
+
logger.error(f"❌ Ошибка OpenAI: {e}")
|
|
174
|
+
return False
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
async def check_prompts(config: Config) -> bool:
|
|
178
|
+
"""Проверяем промпты с новыми JSON инструкциями"""
|
|
179
|
+
try:
|
|
180
|
+
loader = PromptLoader(
|
|
181
|
+
prompts_dir=config.PROMT_FILES_DIR, prompt_files=config.PROMPT_FILES
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
# Проверяем доступность файлов
|
|
185
|
+
validation = await loader.validate_prompts()
|
|
186
|
+
|
|
187
|
+
logger.info("📝 Статус промптов:")
|
|
188
|
+
for filename, status in validation.items():
|
|
189
|
+
status_icon = "✅" if status else "❌"
|
|
190
|
+
logger.info(f" {status_icon} {filename}")
|
|
191
|
+
|
|
192
|
+
# Пробуем загрузить системный промпт
|
|
193
|
+
if any(validation.values()):
|
|
194
|
+
system_prompt = await loader.load_system_prompt()
|
|
195
|
+
logger.info(f"✅ Системный промпт загружен ({len(system_prompt)} символов)")
|
|
196
|
+
|
|
197
|
+
# Проверяем наличие JSON инструкций
|
|
198
|
+
if "JSON МЕТАДАННЫМ" in system_prompt:
|
|
199
|
+
logger.info("✅ JSON инструкции включены в системный промпт")
|
|
200
|
+
else:
|
|
201
|
+
logger.warning("⚠️ JSON инструкции не найдены в системном промпте")
|
|
202
|
+
|
|
203
|
+
if '"этап":' in system_prompt:
|
|
204
|
+
logger.info("✅ Примеры JSON найдены в промпте")
|
|
205
|
+
else:
|
|
206
|
+
logger.warning("⚠️ Примеры JSON не найдены в промпте")
|
|
207
|
+
|
|
208
|
+
# Проверяем приветственное сообщение
|
|
209
|
+
welcome_message = await loader.load_welcome_message()
|
|
210
|
+
logger.info(
|
|
211
|
+
f"✅ Приветственное сообщение загружено ({len(welcome_message)} символов)"
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
# Проверяем справочное сообщение
|
|
215
|
+
help_message = await loader.load_help_message()
|
|
216
|
+
logger.info(
|
|
217
|
+
f"✅ Справочное сообщение загружено ({len(help_message)} символов)"
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
return True
|
|
221
|
+
else:
|
|
222
|
+
logger.error("❌ Не удалось загрузить ни одного промпта")
|
|
223
|
+
return False
|
|
224
|
+
|
|
225
|
+
except Exception as e:
|
|
226
|
+
logger.error(f"❌ Ошибка загрузки промптов: {e}")
|
|
227
|
+
return False
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
async def check_admin_system(config: Config) -> bool:
|
|
231
|
+
"""Проверяем админскую систему"""
|
|
232
|
+
try:
|
|
233
|
+
logger.info("👑 Проверка админской системы...")
|
|
234
|
+
|
|
235
|
+
if not config.ADMIN_TELEGRAM_IDS:
|
|
236
|
+
logger.warning("⚠️ Админы не настроены (ADMIN_TELEGRAM_IDS пуст)")
|
|
237
|
+
return False
|
|
238
|
+
|
|
239
|
+
# Проверяем AdminManager
|
|
240
|
+
supabase_client = SupabaseClient(config.SUPABASE_URL, config.SUPABASE_KEY)
|
|
241
|
+
await supabase_client.initialize()
|
|
242
|
+
|
|
243
|
+
admin_manager = AdminManager(config, supabase_client)
|
|
244
|
+
logger.info(
|
|
245
|
+
f"✅ AdminManager инициализирован ({len(admin_manager.admin_ids)} админов)"
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
# Проверяем ConversationManager
|
|
249
|
+
ConversationManager(supabase_client, admin_manager)
|
|
250
|
+
logger.info("✅ ConversationManager инициализирован")
|
|
251
|
+
|
|
252
|
+
# Проверяем AnalyticsManager
|
|
253
|
+
analytics_manager = AnalyticsManager(supabase_client)
|
|
254
|
+
|
|
255
|
+
# Тестируем получение статистики
|
|
256
|
+
await analytics_manager.get_funnel_stats(1)
|
|
257
|
+
logger.info("✅ AnalyticsManager работает")
|
|
258
|
+
|
|
259
|
+
logger.info("✅ Админская система готова к работе")
|
|
260
|
+
return True
|
|
261
|
+
|
|
262
|
+
except Exception as e:
|
|
263
|
+
logger.error(f"❌ Ошибка админской системы: {e}")
|
|
264
|
+
return False
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
async def check_json_parsing() -> bool:
|
|
268
|
+
"""Проверяем парсинг JSON метаданных"""
|
|
269
|
+
try:
|
|
270
|
+
logger.info("🧪 Проверка парсинга JSON...")
|
|
271
|
+
|
|
272
|
+
# Тестовые случаи
|
|
273
|
+
test_response = """Отлично! Записал ваш номер телефона.
|
|
274
|
+
|
|
275
|
+
{
|
|
276
|
+
"этап": "contacts",
|
|
277
|
+
"качество": 9,
|
|
278
|
+
"события": [
|
|
279
|
+
{
|
|
280
|
+
"тип": "телефон",
|
|
281
|
+
"инфо": "Иван Петров +79219603144"
|
|
282
|
+
}
|
|
283
|
+
]
|
|
284
|
+
}"""
|
|
285
|
+
|
|
286
|
+
response_text, metadata = parse_ai_response(test_response)
|
|
287
|
+
|
|
288
|
+
if metadata:
|
|
289
|
+
logger.info("✅ JSON успешно распарсен")
|
|
290
|
+
logger.info(f" Этап: {metadata.get('этап')}")
|
|
291
|
+
logger.info(f" Качество: {metadata.get('качество')}")
|
|
292
|
+
logger.info(f" События: {len(metadata.get('события', []))}")
|
|
293
|
+
return True
|
|
294
|
+
else:
|
|
295
|
+
logger.error("❌ Не удалось распарсить JSON")
|
|
296
|
+
return False
|
|
297
|
+
|
|
298
|
+
except Exception as e:
|
|
299
|
+
logger.error(f"❌ Ошибка парсинга JSON: {e}")
|
|
300
|
+
return False
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
async def check_database_structure() -> bool:
|
|
304
|
+
"""Проверяем структуру базы данных"""
|
|
305
|
+
try:
|
|
306
|
+
logger.info("📊 Проверка структуры БД...")
|
|
307
|
+
|
|
308
|
+
# Проверяем наличие SQL файлов
|
|
309
|
+
root_dir = Path(os.getcwd())
|
|
310
|
+
sql_files = [
|
|
311
|
+
(
|
|
312
|
+
"database_structure.sql",
|
|
313
|
+
"smart_bot_factory/database/database_structure.sql",
|
|
314
|
+
),
|
|
315
|
+
("admin_migration.sql", "smart_bot_factory/admin/admin_migration.sql"),
|
|
316
|
+
]
|
|
317
|
+
|
|
318
|
+
for sql_name, sql_path in sql_files:
|
|
319
|
+
full_path = root_dir / sql_path
|
|
320
|
+
if full_path.exists():
|
|
321
|
+
logger.info(f"✅ {sql_name} найден: {sql_path}")
|
|
322
|
+
else:
|
|
323
|
+
logger.error(f"❌ {sql_name} не найден: {sql_path}")
|
|
324
|
+
|
|
325
|
+
logger.info("ℹ️ Для проверки таблиц в БД запустите SQL скрипты в Supabase")
|
|
326
|
+
return True
|
|
327
|
+
|
|
328
|
+
except Exception as e:
|
|
329
|
+
logger.error(f"❌ Ошибка проверки БД: {e}")
|
|
330
|
+
return False
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
async def check_environment() -> None:
|
|
334
|
+
"""Проверяем окружение"""
|
|
335
|
+
logger.info("🔧 Проверка окружения...")
|
|
336
|
+
|
|
337
|
+
# Проверяем Python зависимости
|
|
338
|
+
dependencies = [
|
|
339
|
+
("aiogram", "aiogram"),
|
|
340
|
+
("supabase", "supabase"),
|
|
341
|
+
("openai", "openai"),
|
|
342
|
+
("python-dotenv", "dotenv"),
|
|
343
|
+
("aiofiles", "aiofiles"),
|
|
344
|
+
]
|
|
345
|
+
|
|
346
|
+
for dep_name, import_name in dependencies:
|
|
347
|
+
try:
|
|
348
|
+
if import_name == "aiogram":
|
|
349
|
+
import aiogram
|
|
350
|
+
|
|
351
|
+
logger.info(f"✅ {dep_name} {aiogram.__version__}")
|
|
352
|
+
elif import_name == "openai":
|
|
353
|
+
import openai
|
|
354
|
+
|
|
355
|
+
logger.info(f"✅ {dep_name} {openai.version.VERSION}")
|
|
356
|
+
else:
|
|
357
|
+
__import__(import_name)
|
|
358
|
+
logger.info(f"✅ {dep_name} установлен")
|
|
359
|
+
except ImportError:
|
|
360
|
+
logger.error(f"❌ {dep_name} не установлен")
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
async def run_quick_test() -> bool:
|
|
364
|
+
"""Быстрый тест основного функционала"""
|
|
365
|
+
try:
|
|
366
|
+
logger.info("⚡ Быстрый тест компонентов...")
|
|
367
|
+
|
|
368
|
+
config = Config()
|
|
369
|
+
|
|
370
|
+
if config.ADMIN_TELEGRAM_IDS:
|
|
371
|
+
logger.info(f"✅ {len(config.ADMIN_TELEGRAM_IDS)} админов настроено")
|
|
372
|
+
else:
|
|
373
|
+
logger.warning("⚠️ Админы не настроены")
|
|
374
|
+
|
|
375
|
+
# Тест парсинга JSON
|
|
376
|
+
await check_json_parsing()
|
|
377
|
+
|
|
378
|
+
return True
|
|
379
|
+
|
|
380
|
+
except Exception as e:
|
|
381
|
+
logger.error(f"❌ Ошибка быстрого теста: {e}")
|
|
382
|
+
return False
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
async def check_setup(bot_name: str = "growthmed-october-24") -> bool:
|
|
386
|
+
"""
|
|
387
|
+
Проверяет настройку бота
|
|
388
|
+
|
|
389
|
+
Args:
|
|
390
|
+
bot_name: Имя бота для проверки
|
|
391
|
+
|
|
392
|
+
Returns:
|
|
393
|
+
bool: True если все критические проверки пройдены, False если есть критические ошибки
|
|
394
|
+
"""
|
|
395
|
+
logger.info(f"🚀 Проверка настройки Telegram Sales Bot v2.0: {bot_name}")
|
|
396
|
+
logger.info(f"🤖 Bot ID будет автоопределен как: {bot_name}\n")
|
|
397
|
+
|
|
398
|
+
# Настраиваем окружение для бота (автоматически устанавливает BOT_ID)
|
|
399
|
+
config_dir = setup_bot_environment(bot_name)
|
|
400
|
+
if not config_dir:
|
|
401
|
+
return False
|
|
402
|
+
|
|
403
|
+
# Проверяем окружение
|
|
404
|
+
await check_environment()
|
|
405
|
+
logger.info("")
|
|
406
|
+
|
|
407
|
+
# Проверяем конфигурацию
|
|
408
|
+
config = await check_config()
|
|
409
|
+
if not config:
|
|
410
|
+
logger.error("\n❌ Невозможно продолжить без правильной конфигурации")
|
|
411
|
+
return False
|
|
412
|
+
logger.info("")
|
|
413
|
+
|
|
414
|
+
# Основные проверки
|
|
415
|
+
checks: List[Tuple[str, bool]] = []
|
|
416
|
+
for name, check_coro in [
|
|
417
|
+
("База данных", check_database_structure()),
|
|
418
|
+
("Supabase", check_supabase(config)),
|
|
419
|
+
("OpenAI", check_openai(config)),
|
|
420
|
+
("Промпты", check_prompts(config)),
|
|
421
|
+
("Админская система", check_admin_system(config)),
|
|
422
|
+
("JSON парсинг", check_json_parsing()),
|
|
423
|
+
("Быстрый тест", run_quick_test()),
|
|
424
|
+
]:
|
|
425
|
+
logger.info(f"\n🔍 Проверка: {name}")
|
|
426
|
+
result = await check_coro
|
|
427
|
+
checks.append((name, result))
|
|
428
|
+
|
|
429
|
+
# Итоговый результат
|
|
430
|
+
logger.info(f"\n{'='*60}")
|
|
431
|
+
logger.info(f"📋 ИТОГОВЫЙ ОТЧЕТ для {bot_name}:")
|
|
432
|
+
|
|
433
|
+
all_passed = True
|
|
434
|
+
critical_failed = False
|
|
435
|
+
|
|
436
|
+
# Критические компоненты
|
|
437
|
+
critical_checks = ["Supabase", "OpenAI", "Промпты"]
|
|
438
|
+
|
|
439
|
+
for name, passed in checks:
|
|
440
|
+
if name in critical_checks:
|
|
441
|
+
status = "✅ ПРОЙДЕНА" if passed else "❌ КРИТИЧЕСКАЯ ОШИБКА"
|
|
442
|
+
if not passed:
|
|
443
|
+
critical_failed = True
|
|
444
|
+
else:
|
|
445
|
+
status = "✅ ПРОЙДЕНА" if passed else "⚠️ ПРЕДУПРЕЖДЕНИЕ"
|
|
446
|
+
|
|
447
|
+
logger.info(f" {name}: {status}")
|
|
448
|
+
if not passed:
|
|
449
|
+
all_passed = False
|
|
450
|
+
|
|
451
|
+
passed_count = sum(1 for _, passed in checks if passed)
|
|
452
|
+
logger.info(f"\n📊 Результат: {passed_count}/{len(checks)} проверок пройдено")
|
|
453
|
+
|
|
454
|
+
if critical_failed:
|
|
455
|
+
logger.error("\n🚨 КРИТИЧЕСКИЕ ОШИБКИ! Бот не может быть запущен.")
|
|
456
|
+
logger.error(" Исправьте критические ошибки перед запуском.")
|
|
457
|
+
elif all_passed:
|
|
458
|
+
logger.info("\n🎉 Все проверки пройдены! Бот готов к запуску.")
|
|
459
|
+
logger.info(f" Запустите: python {bot_name}.py")
|
|
460
|
+
if config.ADMIN_TELEGRAM_IDS:
|
|
461
|
+
logger.info(
|
|
462
|
+
f" 👑 Админский доступ настроен для: {config.ADMIN_TELEGRAM_IDS}"
|
|
463
|
+
)
|
|
464
|
+
else:
|
|
465
|
+
logger.warning("\n⚠️ Есть предупреждения, но бот может работать.")
|
|
466
|
+
logger.warning(
|
|
467
|
+
" Рекомендуется исправить предупреждения для полного функционала."
|
|
468
|
+
)
|
|
469
|
+
|
|
470
|
+
if config and config.DEBUG_MODE:
|
|
471
|
+
logger.warning(
|
|
472
|
+
"\n🐛 РЕЖИМ ОТЛАДКИ ВКЛЮЧЕН - JSON будет показываться пользователям"
|
|
473
|
+
)
|
|
474
|
+
|
|
475
|
+
logger.info(f"{'='*60}")
|
|
476
|
+
|
|
477
|
+
return not critical_failed
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
def main():
|
|
481
|
+
"""Точка входа для запуска из командной строки"""
|
|
482
|
+
# Настройка логирования
|
|
483
|
+
logging.basicConfig(level=logging.INFO, format="%(message)s")
|
|
484
|
+
|
|
485
|
+
logger.info("🔍 Утилита проверки настройки бота")
|
|
486
|
+
logger.info("Использование:")
|
|
487
|
+
logger.info(" python -m smart_bot_factory.setup_checker [bot_name]")
|
|
488
|
+
logger.info(" python -m smart_bot_factory.setup_checker growthmed-october-24")
|
|
489
|
+
logger.info("")
|
|
490
|
+
|
|
491
|
+
if len(sys.argv) > 1 and sys.argv[1] in ["-h", "--help", "help"]:
|
|
492
|
+
return
|
|
493
|
+
|
|
494
|
+
# Определяем какого бота проверять
|
|
495
|
+
bot_name = "growthmed-october-24" # по умолчанию
|
|
496
|
+
if len(sys.argv) > 1:
|
|
497
|
+
bot_name = sys.argv[1]
|
|
498
|
+
|
|
499
|
+
try:
|
|
500
|
+
success = asyncio.run(check_setup(bot_name))
|
|
501
|
+
if not success:
|
|
502
|
+
sys.exit(1)
|
|
503
|
+
except KeyboardInterrupt:
|
|
504
|
+
logger.info("\n⏹️ Прервано пользователем")
|
|
505
|
+
except Exception as e:
|
|
506
|
+
logger.error(f"\n💥 Критическая ошибка: {e}")
|
|
507
|
+
logger.exception("Стек ошибки:")
|
|
508
|
+
sys.exit(1)
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
if __name__ == "__main__":
|
|
512
|
+
main()
|