Initial commit: TrueConf Chatbot КЛЕВЕР

This commit is contained in:
2026-07-15 12:00:27 +07:00
commit fc0288d13d
42 changed files with 7818 additions and 0 deletions
View File
+49
View File
@@ -0,0 +1,49 @@
import logging
import os
import sys
from ldap3 import Server, Connection, ALL, MODIFY_REPLACE
# Подтягиваем конфиг
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from config.config import AD_SERVER, AD_USER, AD_PASSWORD, AD_BASE
logger = logging.getLogger(__name__)
def upload_photo_to_ad(target_user: str, photo_path: str) -> dict:
"""
Читает готовое фото с диска и записывает его в атрибут thumbnailPhoto в AD.
"""
try:
# Читаем сырые байты картинки
with open(photo_path, "rb") as f:
photo_bytes = f.read()
# Формируем фильтр для поиска
if '@' in target_user:
ldap_filter = f"(mail={target_user})"
else:
ldap_filter = f"(sAMAccountName={target_user})"
# Подключаемся к AD
server = Server(AD_SERVER, get_info=ALL)
conn = Connection(server, user=AD_USER, password=AD_PASSWORD, auto_bind=True)
# Находим пользователя в дереве (нам нужен его точный путь - DN)
conn.search(search_base=AD_BASE, search_filter=ldap_filter, attributes=["cn"])
if not conn.entries:
return {"success": False, "error": f"Пользователь {target_user} не найден в AD."}
user_dn = conn.entries[0].entry_dn
# 🪄 МАГИЯ: Перезаписываем атрибут thumbnailPhoto нашими байтами
conn.modify(user_dn, {'thumbnailPhoto': [(MODIFY_REPLACE, [photo_bytes])]})
if conn.result['result'] == 0:
return {"success": True}
else:
return {"success": False, "error": str(conn.result['description'])}
except Exception as e:
logger.error(f"Ошибка загрузки в AD для {target_user}: {e}")
return {"success": False, "error": "Сбой при связи с сервером Active Directory."}
+181
View File
@@ -0,0 +1,181 @@
import os
import asyncio
import logging
import sys
# Добавляем путь к корню проекта
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from trueconf import Bot, Dispatcher, Router, Message
from trueconf.types import FSInputFile
# Наши обработчики
from photo_processor import prepare_ad_photo
from ad_helper import upload_photo_to_ad
# Настройки
from config.config import *
# --- НАСТРОЙКА ЛОГИРОВАНИЯ ---
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
handlers=[
logging.FileHandler("photo_bot_log.txt", encoding="utf-8"),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
router = Router()
tc_bot = None
# 🧠 ПАМЯТЬ БОТА: Храним пути к фото, ожидающим подтверждения
# Пример: {'ds.krivochenko': '/tmp/ready_ds.krivochenko.jpg'}
pending_photos = {}
@router.message()
async def handle_message(msg: Message):
global tc_bot
# Определяем логин пользователя
user_login = msg.from_user.id.split('@')[0] if '@' in msg.from_user.id else msg.from_user.id
# Проверяем, вложение ли это
is_attachment = hasattr(msg.type, "name") and msg.type.name == "ATTACHMENT"
# =====================================================================
# СЦЕНАРИЙ 1: Бот ждет ответа, и пользователь написал текст (Да/Нет)
# =====================================================================
if not is_attachment and user_login in pending_photos and msg.text:
answer = msg.text.strip().lower()
# Если согласен
if answer in ["да", "yes", "+", "загрузить", "давай", "конечно"]:
photo_path = pending_photos[user_login]
await msg.answer("⏳ Подключаюсь к Active Directory и загружаю фото...")
# Запускаем скрипт загрузки в AD
upload_result = await asyncio.to_thread(upload_photo_to_ad, user_login, photo_path)
if upload_result["success"]:
await msg.answer(
"🎉 **Ура! Фото успешно установлено в Active Directory!**\n\n"
"Оно появится в Outlook, TrueConf и других системах в течение нескольких часов (после синхронизации серверов)."
)
else:
await msg.answer(f"❌ **Ошибка при загрузке:** {upload_result.get('error')}")
# Убираем за собой файл и стираем пользователя из памяти
if os.path.exists(photo_path):
os.remove(photo_path)
del pending_photos[user_login]
return
# Если отказался
elif answer in ["нет", "no", "-", "отмена"]:
photo_path = pending_photos[user_login]
await msg.answer("🚫 Загрузка отменена. Можете прислать мне другую фотографию!")
if os.path.exists(photo_path):
os.remove(photo_path)
del pending_photos[user_login]
return
# Если написал что-то непонятное, но мы ждем ответа
else:
await msg.answer("❓ Пожалуйста, напишите **Да** (чтобы загрузить фото в AD) или **Нет** (чтобы отменить). Либо просто пришлите новую фотографию.")
return
# =====================================================================
# СЦЕНАРИЙ 2: Пользователь прислал новую фотографию
# =====================================================================
if is_attachment:
file_id = getattr(msg.content, "file_id", None)
if not file_id:
await msg.answer("❌ Не удалось получить файл. Попробуйте еще раз.")
return
ready_path = f"/tmp/ready_{user_login}.jpg"
raw_path = None
await msg.answer("⏳ Обрабатываю ваше фото, пожалуйста, подождите...")
try:
downloaded_file = await tc_bot.download_file_by_id(file_id)
raw_path = downloaded_file
# Обрабатываем фото (с новым разрешением 240x240)
result = await asyncio.to_thread(prepare_ad_photo, raw_path, ready_path, 240)
if result["success"]:
photo_document = FSInputFile(ready_path, filename=f"AD_{user_login}.jpg")
# Отправляем фото и СРАЗУ задаем вопрос
await msg.answer_photo(
photo_document,
photo_document,
caption=(
f"✅ **Фото готово!**\n\n"
f"📐 Размер: 240x240 px\n"
f"⚖️ Вес: {result['size_kb']} KB\n\n"
f"❓ **Вам нравится результат? Загружаем в Active Directory?**\n"
f"Напишите мне в ответ **Да** или **Нет**."
)
)
# 🧠 ЗАПОМИНАЕМ, что этот пользователь теперь в режиме ожидания ответа
pending_photos[user_login] = ready_path
logger.info(f"Фото подготовлено для {user_login}, ждем подтверждения.")
else:
await msg.answer(f"❌ Ошибка обработки: {result.get('error')}")
except Exception as e:
logger.error(f"Ошибка при работе с фото для {user_login}: {e}")
await msg.answer("❌ Произошла системная ошибка при обработке.")
finally:
# ВАЖНО: Удаляем ТОЛЬКО оригинал от TrueConf (raw_path).
# Готовое фото (ready_path) оставляем на диске, оно ждет ответа "Да"!
if raw_path and os.path.exists(raw_path):
try: os.remove(raw_path)
except: pass
return
# =====================================================================
# СЦЕНАРИЙ 3: Дефолтное приветствие (если просто написали текст)
# =====================================================================
await msg.answer(
"👋 Привет! Я корпоративный фотограф для Active Directory.\n\n"
"📸 **Просто отправь мне фото**, и я автоматически:\n"
"1. Найду лицо на снимке и сделаю правильный кадр.\n"
"2. Улучшу резкость и сожму до стандарта 240x240 px.\n"
"3. Предложу загрузить результат прямо в твой профиль!"
)
async def main():
global tc_bot
logger.info(f"Запуск фото-бота на сервере {TC_SERVER}...")
dp = Dispatcher()
dp.include_router(router)
tc_bot = Bot.from_credentials(
server=TC_SERVER,
username=TC_LOGIN,
password=TC_PASSWORD,
dispatcher=dp,
verify_ssl=False
)
await tc_bot.run()
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
logger.info("Бот остановлен пользователем.")
+83
View File
@@ -0,0 +1,83 @@
import sys
import os
import io
import logging
from ldap3 import Server, Connection, ALL
from PIL import Image
# Подтягиваем ваши настройки из конфига
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from config.config import AD_SERVER, AD_USER, AD_PASSWORD, AD_BASE
logging.basicConfig(level=logging.INFO, format="%(message)s")
def check_user_photo(target_user: str):
print(f"🔍 Ищем пользователя: {target_user}...")
# Если передали email, ищем по почте. Если просто логин — по sAMAccountName
if '@' in target_user:
ldap_filter = f"(mail={target_user})"
else:
ldap_filter = f"(sAMAccountName={target_user})"
try:
# Подключаемся к AD
server = Server(AD_SERVER, get_info=ALL)
conn = Connection(server, user=AD_USER, password=AD_PASSWORD, auto_bind=True)
# Ищем пользователя и просим вернуть атрибуты: имя (cn) и фото (thumbnailPhoto)
conn.search(
search_base=AD_BASE,
search_filter=ldap_filter,
attributes=["cn", "thumbnailPhoto"]
)
if not conn.entries:
print("❌ Пользователь с такими данными не найден в AD.")
return
user = conn.entries[0]
user_name = user.cn.value if 'cn' in user else target_user
print(f"👤 Найден сотрудник: {user_name}")
# Проверяем, есть ли вообще фото
if 'thumbnailPhoto' not in user or not user.thumbnailPhoto.value:
print("⚠️ У этого пользователя НЕТ фотографии в Active Directory.")
return
# Достаем байты фотографии
photo_bytes = user.thumbnailPhoto.value
size_kb = len(photo_bytes) / 1024
# Читаем картинку прямо из памяти (без сохранения на диск) с помощью Pillow
image = Image.open(io.BytesIO(photo_bytes))
width, height = image.size
print("\n📊 --- ИНФОРМАЦИЯ О ФОТО В AD ---")
print(f"📐 Разрешение : {width}x{height} пикселей")
print(f"⚖️ Вес : {size_kb:.1f} KB")
print(f"🗂 Формат : {image.format}")
print("----------------------------------\n")
# Бонус: сохраняем фото во временную папку, чтобы вы могли на него взглянуть
safe_name = target_user.replace('@', '_').replace('.', '_')
save_path = f"/tmp/{safe_name}_ad.jpg"
with open(save_path, "wb") as f:
f.write(photo_bytes)
print(f"💾 Оригинал из AD сохранен сюда: {save_path}")
print("Вы можете скачать его через WinSCP или открыть в TrueConf, чтобы оценить качество глазами.")
except Exception as e:
print(f"❌ Ошибка при подключении к AD: {e}")
if __name__ == "__main__":
# Замените на нужный email или логин (например, 'n.shmargalova' или 'n.shmargalova@sibcem.ru')
target = "n.shmargalova@sibcem.ru"
# Если скрипт запущен с аргументом (python check_ad_photo.py логин), берем аргумент
if len(sys.argv) > 1:
target = sys.argv[1]
check_user_photo(target)
+242
View File
@@ -0,0 +1,242 @@
# /opt/trueconf_bot/photo_bot/handlers.py
import os
import asyncio
import logging
import httpx
import smtplib
import time
from datetime import datetime
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from PIL import Image
from trueconf import Router, Message
from trueconf.types import FSInputFile
import config.config as config
from utils import states
from utils.menu import MENU_TEXT
from photo_bot.photo_processor import prepare_ad_photo
from utils.texts import (
EMOJI_DIGITS,
PHOTO_MAIN_MENU_TEXT,
PHOTO_UNKNOWN_CMD_TEXT,
photo_error_handling,
PHOTO_UPLOADING_TEXT,
photo_success_sent,
photo_cancel_text,
PHOTO_PROCESSING_TEXT,
photo_preview_ready,
photo_error_processing,
)
# 🔌 Импортируем централизованную функцию сбора статистики из main
from utils.stats_logger import log_menu_stats
logger = logging.getLogger(__name__)
router = Router()
# Словарь для временного хранения путей к фото пользователей
pending_photos = {}
# =========================================================
# СИСТЕМА ОБРАБОТКИ ОШИБОК И ЛОГИРОВАНИЯ
# =========================================================
EMAIL_COOLDOWN_SEC = 10.0
last_email_time = 0.0
def log_and_notify_photo_error(user_id: str, action: str, error_details: str):
"""Записывает системную ошибку в лог-файл и отправляет email-алерт администраторам"""
global last_email_time
log_dir = os.path.dirname(os.path.abspath(__file__))
os.makedirs(log_dir, exist_ok=True)
log_file = os.path.join(log_dir, "photo_errors.log")
current_time = time.time()
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_entry = f"[{timestamp}] User: {user_id} | Action: {action} | Error: {error_details}\n"
with open(log_file, "a", encoding="utf-8") as f:
f.write(log_entry)
if current_time - last_email_time < EMAIL_COOLDOWN_SEC:
with open(log_file, "a", encoding="utf-8") as f:
f.write(f"[{timestamp}] ALERT: Email suppressed due to rate limiting.\n")
return
last_email_time = current_time
try:
msg = MIMEMultipart()
msg['From'] = str(getattr(config, 'DEFAULT_EMAIL_FROM', 'bot@noreply.com'))
to_emails = getattr(config, 'ALERTS_SUPPORT_EMAILS', 'admin@example.com')
msg['To'] = ", ".join(to_emails) if isinstance(to_emails, list) else str(to_emails)
msg['Subject'] = f"TrueConf Bot Error: Фото Профиль - {action}"
body = (
f"Обнаружена системная ошибка в модуле загрузки фото профиля.\n\n"
f"Время: {timestamp}\n"
f"Пользователь (ID): {user_id}\n"
f"Действие: {action}\n\n"
f"Детали ошибки:\n{error_details}\n\n"
f"(Уведомления об ошибках ограничены: не чаще 1 раза в {EMAIL_COOLDOWN_SEC} сек.)"
)
msg.attach(MIMEText(body, 'plain', 'utf-8'))
smtp_server = getattr(config, 'SMTP_SERVER', 'localhost')
smtp_port = int(getattr(config, 'SMTP_PORT', 25))
with smtplib.SMTP(smtp_server, smtp_port) as server:
smtp_user = getattr(config, 'SMTP_USER', None)
smtp_pass = getattr(config, 'SMTP_PASSWORD', None)
if smtp_user and smtp_pass:
server.login(smtp_user, smtp_pass)
server.send_message(msg)
except Exception as e:
with open(log_file, "a", encoding="utf-8") as f:
f.write(f"[{timestamp}] СБОЙ ОТПРАВКИ EMAIL: {e}\n")
async def handle_photo_error(msg: Message, user_id: str, action: str, error_details: str):
"""Вызывает системное логирование и выдает заглушку пользователю"""
await asyncio.to_thread(log_and_notify_photo_error, user_id, action, error_details)
await msg.answer(photo_error_handling(), parse_mode="html")
# =========================================================
# ОСНОВНОЙ ОБРАБОТЧИК
# =========================================================
@router.message()
async def photo_module_handler(msg: Message):
user_id = msg.from_user.id
if states.get_state(user_id) != "PHOTO_MODE":
return
# Помечаем сообщение как обработанное
msg.handled = True
user_login = user_id.split('@')[0] if '@' in user_id else user_id
msg_text = getattr(msg.content, "text", "").strip() if hasattr(msg.content, "text") else ""
is_attachment = hasattr(msg.type, "name") and msg.type.name == "ATTACHMENT"
cmd = msg_text.lower()
# 🔄 НОРМАЛИЗАЦИЯ КНОПОК ВК-ЭМОДЗИ
for raw_num, emoji_num in EMOJI_DIGITS.items():
if cmd == emoji_num:
cmd = raw_num
break
# --- ВЫХОД (Кнопки 0 и 9 возвращают в общее меню с очисткой кэша) ---
if cmd in ["0", "9", "/start", "меню"]:
log_menu_stats(user_id, "Photo Bot", "Выход в главное меню")
states.clear_state(user_id)
if user_id in pending_photos:
if os.path.exists(pending_photos[user_id]):
os.remove(pending_photos[user_id])
del pending_photos[user_id]
await msg.answer(MENU_TEXT, parse_mode="html")
return
# --- ПОДТВЕРЖДЕНИЕ ОТПРАВКИ (Кнопка 1 или 2) ---
if not is_attachment and user_id in pending_photos:
if cmd == "1":
photo_path = pending_photos[user_id]
final_filename = f"{user_login}.bmp"
await msg.answer(PHOTO_UPLOADING_TEXT, parse_mode="html")
try:
async with httpx.AsyncClient(timeout=10.0) as client:
with open(photo_path, "rb") as f:
files = {'file': (final_filename, f, 'image/bmp')}
response = await client.post(config.TRASH_API_URL, files=files)
if response.status_code == 200:
# ФИКСАЦИЯ СТАТИСТИКИ: Успешная выгрузка фото на утверждение
log_menu_stats(user_id, "Photo Bot", "Отправка фото на утверждение")
await msg.answer(photo_success_sent(), parse_mode="html")
states.clear_state(user_id)
if os.path.exists(photo_path):
os.remove(photo_path)
del pending_photos[user_id]
await asyncio.sleep(0.5)
await msg.answer(MENU_TEXT, parse_mode="html")
else:
error_msg = f"API вернул статус-код {response.status_code}"
await handle_photo_error(msg, user_id, "Отправка фото по API", error_msg)
except Exception as e:
await handle_photo_error(msg, user_id, "Подключение к API загрузки", str(e))
return
# --- ОТМЕНА ФОТО (Кнопка 2) ---
elif cmd == "2":
log_menu_stats(user_id, "Photo Bot", "Отмена загруженного фото")
photo_path = pending_photos[user_id]
if os.path.exists(photo_path):
os.remove(photo_path)
del pending_photos[user_id]
await msg.answer(photo_cancel_text(), parse_mode="html")
return
# --- ИСПРАВЛЕНО: Защита от мусорного ввода при висящем превью ---
else:
await msg.answer(PHOTO_UNKNOWN_CMD_TEXT, parse_mode="html")
return
# --- ПРИЕМ НОВОГО ФОТО ---
if is_attachment:
file_id = getattr(msg.content, "file_id", None)
ready_path = f"/tmp/{user_login}.bmp"
raw_path = None
await msg.answer(PHOTO_PROCESSING_TEXT, parse_mode="html")
try:
downloaded_file = await states.tc_bot.download_file_by_id(file_id)
raw_path = downloaded_file
result = await asyncio.to_thread(prepare_ad_photo, raw_path, ready_path, 96)
if result["success"]:
# ФИКСАЦИЯ СТАТИСТИКИ: Факт успешной загрузки и обработки нового фото
log_menu_stats(user_id, "Photo Bot", "Загрузка и конвертация нового фото")
pending_photos[user_id] = ready_path
preview_path = f"/tmp/prev_{user_login}.jpg"
try:
Image.open(ready_path).save(preview_path, format="JPEG")
p_main = FSInputFile(preview_path, filename="preview.jpg")
p_thumb = FSInputFile(preview_path, filename="preview_thumb.jpg")
await msg.answer_photo(p_main, p_thumb)
except Exception as lib_err:
await asyncio.to_thread(log_and_notify_photo_error, user_id, "Генерация превью", str(lib_err))
finally:
if os.path.exists(preview_path):
os.remove(preview_path)
await asyncio.sleep(0.5)
await msg.answer(
photo_preview_ready(),
parse_mode="html"
)
else:
error_text = result.get('error', 'Не удалось обработать фото.')
await msg.answer(
photo_error_processing(error_text),
parse_mode="html"
)
except Exception as e:
await handle_photo_error(msg, user_id, "Скачивание и обработка файла", str(e))
finally:
if raw_path and os.path.exists(raw_path):
try:
os.remove(raw_path)
except Exception as cleanup_err:
await asyncio.to_thread(log_and_notify_photo_error, user_id, "Очистка временных файлов", str(cleanup_err))
return
+317
View File
@@ -0,0 +1,317 @@
2026-04-23 23:39:51,315 [INFO] Запуск фото-бота на сервере tcs.sibcem.ru...
2026-04-23 23:39:51,930 [INFO] HTTP Request: POST https://tcs.sibcem.ru/bridge/api/client/v1/oauth/token "HTTP/1.1 201 Created"
2026-04-23 23:39:51,969 [INFO] HTTP Request: GET https://tcs.sibcem.ru/api/v4/server "HTTP/1.1 200 OK"
2026-04-23 23:39:51,970 [INFO] ⏳ Attempting WebSocket connection...
2026-04-23 23:39:52,055 [INFO] ✅ WebSocket connected
2026-04-23 23:39:52,055 [INFO] 🚀 Starting authorization
2026-04-23 23:39:52,055 [INFO] 🛠 Created AuthMethod with id=1
2026-04-23 23:39:52,129 [INFO] 🔐 Authenticated as bot_tcs@tcs.sibcem.ru/43099233
2026-04-23 23:40:09,861 [INFO] 📥 Incoming event: Message(timestamp=1776962409746, type=<MessageType.PLAIN_MESSAGE: 200>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=60, position='0'), content=TextContent(text='Hdd', parse_mode='html'), message_id='35d354ed-b6f2-41cc-b3a5-b7691342ccad', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-23 23:40:09,861 [INFO] [router:0x77d568978a90] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-23 23:40:09,861 [ERROR] Handler async_wrapper failed: handle_photo() missing 1 required positional argument: 'bot'
Traceback (most recent call last):
File "/home/tpxk-03/bot_env/lib/python3.10/site-packages/trueconf/dispatcher/router.py", line 133, in _run
await handler(event, **kwargs)
File "/home/tpxk-03/bot_env/lib/python3.10/site-packages/trueconf/dispatcher/router.py", line 83, in async_wrapper
await func(evt, **filtered_kwargs)
TypeError: handle_photo() missing 1 required positional argument: 'bot'
2026-04-23 23:40:17,711 [INFO] 📥 Incoming event: Message(timestamp=1776962417624, type=<MessageType.PLAIN_MESSAGE: 200>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=61, position='0'), content=TextContent(text='Ddd', parse_mode='html'), message_id='a50e58bb-0924-4875-a6cc-5bcefcd34c1d', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-23 23:40:17,711 [INFO] [router:0x77d568978a90] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-23 23:40:17,712 [ERROR] Handler async_wrapper failed: handle_photo() missing 1 required positional argument: 'bot'
Traceback (most recent call last):
File "/home/tpxk-03/bot_env/lib/python3.10/site-packages/trueconf/dispatcher/router.py", line 133, in _run
await handler(event, **kwargs)
File "/home/tpxk-03/bot_env/lib/python3.10/site-packages/trueconf/dispatcher/router.py", line 83, in async_wrapper
await func(evt, **filtered_kwargs)
TypeError: handle_photo() missing 1 required positional argument: 'bot'
2026-04-23 23:41:19,825 [INFO] 📥 Incoming event: Message(timestamp=1776962477100, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=62, position='0'), content=AttachmentContent(file_name='image_2026.04.23_23-41-16_7720.webp', file_size=31428, file_id='b9002e074a4774d35ecf1f8cef29b8a737c4f1d2', mimetype='image/webp', ready_state=None), message_id='74faff33-a25d-4aa6-bcaa-cfc510c4ed97', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-23 23:41:19,825 [INFO] [router:0x77d568978a90] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-23 23:41:19,825 [ERROR] Handler async_wrapper failed: handle_photo() missing 1 required positional argument: 'bot'
Traceback (most recent call last):
File "/home/tpxk-03/bot_env/lib/python3.10/site-packages/trueconf/dispatcher/router.py", line 133, in _run
await handler(event, **kwargs)
File "/home/tpxk-03/bot_env/lib/python3.10/site-packages/trueconf/dispatcher/router.py", line 83, in async_wrapper
await func(evt, **filtered_kwargs)
TypeError: handle_photo() missing 1 required positional argument: 'bot'
2026-04-23 23:41:33,296 [INFO] 🛑 Connect loop cancelled, performing cleanup.
2026-04-23 23:41:33,297 [INFO] 🛑 ChatBot stopped
2026-04-23 23:41:35,735 [INFO] Запуск фото-бота на сервере tcs.sibcem.ru...
2026-04-23 23:41:35,967 [INFO] HTTP Request: POST https://tcs.sibcem.ru/bridge/api/client/v1/oauth/token "HTTP/1.1 201 Created"
2026-04-23 23:41:35,985 [INFO] HTTP Request: GET https://tcs.sibcem.ru/api/v4/server "HTTP/1.1 200 OK"
2026-04-23 23:41:35,986 [INFO] ⏳ Attempting WebSocket connection...
2026-04-23 23:41:35,998 [INFO] ✅ WebSocket connected
2026-04-23 23:41:35,998 [INFO] 🚀 Starting authorization
2026-04-23 23:41:35,998 [INFO] 🛠 Created AuthMethod with id=1
2026-04-23 23:41:36,067 [INFO] 🔐 Authenticated as bot_tcs@tcs.sibcem.ru/2ee10857
2026-04-23 23:41:46,197 [INFO] 📥 Incoming event: Message(timestamp=1776962503542, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=63, position='0'), content=AttachmentContent(file_name='image_2026.04.23_23-41-43_2380.webp', file_size=33566, file_id='79e26db73915e1eddea88a79646ca9cbfa71c87c', mimetype='image/webp', ready_state=None), message_id='3246d0e7-5721-42e2-952f-d5891f56ccf2', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-23 23:41:46,197 [INFO] [router:0x7d0b32188940] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-23 23:41:46,197 [ERROR] Handler async_wrapper failed: handle_photo() missing 1 required positional argument: 'bot'
Traceback (most recent call last):
File "/home/tpxk-03/bot_env/lib/python3.10/site-packages/trueconf/dispatcher/router.py", line 133, in _run
await handler(event, **kwargs)
File "/home/tpxk-03/bot_env/lib/python3.10/site-packages/trueconf/dispatcher/router.py", line 83, in async_wrapper
await func(evt, **filtered_kwargs)
TypeError: handle_photo() missing 1 required positional argument: 'bot'
2026-04-23 23:44:41,946 [INFO] 🛑 Connect loop cancelled, performing cleanup.
2026-04-23 23:44:41,947 [INFO] 🛑 ChatBot stopped
2026-04-23 23:44:44,556 [INFO] Запуск фото-бота на сервере tcs.sibcem.ru...
2026-04-23 23:44:44,775 [INFO] HTTP Request: POST https://tcs.sibcem.ru/bridge/api/client/v1/oauth/token "HTTP/1.1 201 Created"
2026-04-23 23:44:44,797 [INFO] HTTP Request: GET https://tcs.sibcem.ru/api/v4/server "HTTP/1.1 200 OK"
2026-04-23 23:44:44,798 [INFO] ⏳ Attempting WebSocket connection...
2026-04-23 23:44:44,816 [INFO] ✅ WebSocket connected
2026-04-23 23:44:44,817 [INFO] 🚀 Starting authorization
2026-04-23 23:44:44,817 [INFO] 🛠 Created AuthMethod with id=1
2026-04-23 23:44:44,893 [INFO] 🔐 Authenticated as bot_tcs@tcs.sibcem.ru/ca26821d
2026-04-23 23:45:03,929 [INFO] 📥 Incoming event: Message(timestamp=1776962701339, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=64, position='0'), content=AttachmentContent(file_name='image_2026.04.23_23-45-01_0330.webp', file_size=34734, file_id='b7a33d9f17f2fd8c20e2f89ada14bb543ccd80a3', mimetype='image/webp', ready_state=None), message_id='a3c09710-24fc-4460-987b-7e747542fb89', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-23 23:45:03,929 [INFO] [router:0x7e0f72d68b20] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-23 23:45:03,929 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:45:04,992 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/b7a33d9f17f2fd8c20e2f89ada14bb543ccd80a3 "HTTP/1.1 200 OK"
2026-04-23 23:45:04,995 [ERROR] Ошибка при работе с фото для ds.krivochenko: a bytes-like object is required, not 'PosixPath'
2026-04-23 23:45:04,995 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:46:02,036 [INFO] 🛑 Connect loop cancelled, performing cleanup.
2026-04-23 23:46:02,037 [INFO] 🛑 ChatBot stopped
2026-04-23 23:47:20,892 [INFO] Запуск фото-бота на сервере tcs.sibcem.ru...
2026-04-23 23:47:21,125 [INFO] HTTP Request: POST https://tcs.sibcem.ru/bridge/api/client/v1/oauth/token "HTTP/1.1 201 Created"
2026-04-23 23:47:21,142 [INFO] HTTP Request: GET https://tcs.sibcem.ru/api/v4/server "HTTP/1.1 200 OK"
2026-04-23 23:47:21,143 [INFO] ⏳ Attempting WebSocket connection...
2026-04-23 23:47:21,158 [INFO] ✅ WebSocket connected
2026-04-23 23:47:21,158 [INFO] 🚀 Starting authorization
2026-04-23 23:47:21,158 [INFO] 🛠 Created AuthMethod with id=1
2026-04-23 23:47:21,233 [INFO] 🔐 Authenticated as bot_tcs@tcs.sibcem.ru/c35e07f3
2026-04-23 23:47:33,755 [INFO] 📥 Incoming event: Message(timestamp=1776962851136, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=67, position='0'), content=AttachmentContent(file_name='image_2026.04.23_23-47-30_8460.webp', file_size=37408, file_id='5d8e96f6752a2affd774703ef203b78ff982a9fd', mimetype='image/webp', ready_state=None), message_id='784b7f5a-5d32-4eb6-8656-b43016d5c5a7', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-23 23:47:33,755 [INFO] [router:0x7fb664b70af0] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-23 23:47:33,756 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:47:34,992 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/5d8e96f6752a2affd774703ef203b78ff982a9fd "HTTP/1.1 200 OK"
2026-04-23 23:47:35,114 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:47:58,711 [INFO] 📥 Incoming event: Message(timestamp=1776962875889, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=70, position='0'), content=AttachmentContent(file_name='image_2026.04.23_23-47-55_6050.webp', file_size=33936, file_id='dd85f0b2bc7245d872c19dfa8dbc333772e76c6e', mimetype='image/webp', ready_state=None), message_id='4251845f-f133-4ea0-9165-d10e7ef3707e', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-23 23:47:58,711 [INFO] [router:0x7fb664b70af0] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-23 23:47:58,712 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:47:59,997 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/dd85f0b2bc7245d872c19dfa8dbc333772e76c6e "HTTP/1.1 200 OK"
2026-04-23 23:48:00,316 [ERROR] Ошибка при работе с фото для ds.krivochenko: Message.answer_document() got an unexpected keyword argument 'document'
2026-04-23 23:48:00,316 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:50:34,153 [INFO] 🛑 Connect loop cancelled, performing cleanup.
2026-04-23 23:50:34,153 [INFO] 🛑 ChatBot stopped
2026-04-23 23:50:37,003 [INFO] Запуск фото-бота на сервере tcs.sibcem.ru...
2026-04-23 23:50:37,225 [INFO] HTTP Request: POST https://tcs.sibcem.ru/bridge/api/client/v1/oauth/token "HTTP/1.1 201 Created"
2026-04-23 23:50:37,245 [INFO] HTTP Request: GET https://tcs.sibcem.ru/api/v4/server "HTTP/1.1 200 OK"
2026-04-23 23:50:37,247 [INFO] ⏳ Attempting WebSocket connection...
2026-04-23 23:50:37,263 [INFO] ✅ WebSocket connected
2026-04-23 23:50:37,263 [INFO] 🚀 Starting authorization
2026-04-23 23:50:37,263 [INFO] 🛠 Created AuthMethod with id=1
2026-04-23 23:50:37,338 [INFO] 🔐 Authenticated as bot_tcs@tcs.sibcem.ru/df72df35
2026-04-23 23:50:52,450 [INFO] 📥 Incoming event: Message(timestamp=1776963049877, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=73, position='0'), content=AttachmentContent(file_name='image_2026.04.23_23-50-49_5490.webp', file_size=55568, file_id='2225e5a353a97ca067863db453377cbe8163ebea', mimetype='image/webp', ready_state=None), message_id='faec2f35-2dd3-40d2-bdd1-8f7954873cf2', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-23 23:50:52,451 [INFO] [router:0x73c06af80b50] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-23 23:50:52,451 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:50:53,531 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/2225e5a353a97ca067863db453377cbe8163ebea "HTTP/1.1 200 OK"
2026-04-23 23:50:53,683 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:51:09,117 [INFO] 📥 Incoming event: Message(timestamp=1776963066361, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=76, position='0'), content=AttachmentContent(file_name='image_2026.04.23_23-51-06_0440.webp', file_size=62052, file_id='72dbcf140bd407daf3dc8e564658615fc9aa00dd', mimetype='image/webp', ready_state=None), message_id='81b66791-daa2-447c-ab98-187d243c86a3', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-23 23:51:09,117 [INFO] [router:0x73c06af80b50] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-23 23:51:09,117 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:51:10,538 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/72dbcf140bd407daf3dc8e564658615fc9aa00dd "HTTP/1.1 200 OK"
2026-04-23 23:51:10,774 [INFO] ✉️ Sending file to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:51:10,959 [INFO] Успешно обработано фото для ds.krivochenko
2026-04-23 23:51:37,361 [INFO] 📥 Incoming event: Message(timestamp=1776963094641, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=80, position='0'), content=AttachmentContent(file_name='image_2026.04.23_23-51-34_3470.webp', file_size=51088, file_id='363fe9a06d9962d9a08b67639f601de3f705ed74', mimetype='image/webp', ready_state=None), message_id='2f50a004-1d03-4b3d-babd-21b20ffbcbab', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-23 23:51:37,361 [INFO] [router:0x73c06af80b50] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-23 23:51:37,361 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:51:38,541 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/363fe9a06d9962d9a08b67639f601de3f705ed74 "HTTP/1.1 200 OK"
2026-04-23 23:51:38,668 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:51:59,710 [INFO] 📥 Incoming event: Message(timestamp=1776963116930, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=83, position='0'), content=AttachmentContent(file_name='image_2026.04.23_23-51-56_6400.webp', file_size=51134, file_id='0aca112ece96137cf7ccef3a1f2aa0e2e7ac6716', mimetype='image/webp', ready_state=None), message_id='ee34d07b-c738-4953-851e-b2bb462f7188', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-23 23:51:59,711 [INFO] [router:0x73c06af80b50] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-23 23:51:59,712 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:52:00,543 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/0aca112ece96137cf7ccef3a1f2aa0e2e7ac6716 "HTTP/1.1 200 OK"
2026-04-23 23:52:00,673 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:52:11,373 [INFO] 📥 Incoming event: Message(timestamp=1776963131192, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=86, position='0'), content=AttachmentContent(file_name='image_2026.04.23_23-52-10_9050.webp', file_size=70874, file_id='55b8822f54d91c9de4fc826a510c537befd4ebd5', mimetype='image/webp', ready_state=None), message_id='35ee4f25-d715-48ac-840d-cfbe5b27530d', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-23 23:52:11,373 [INFO] [router:0x73c06af80b50] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-23 23:52:11,374 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:52:12,543 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/55b8822f54d91c9de4fc826a510c537befd4ebd5 "HTTP/1.1 200 OK"
2026-04-23 23:52:12,660 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:52:26,048 [INFO] 📥 Incoming event: Message(timestamp=1776963143388, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=89, position='0'), content=AttachmentContent(file_name='image_2026.04.23_23-52-23_0840.webp', file_size=61968, file_id='31146c0fcf22afd27c0f6abe91962b08efeefd7e', mimetype='image/webp', ready_state=None), message_id='295a95ae-0118-4cd0-9a34-7e00c0d69495', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-23 23:52:26,048 [INFO] [router:0x73c06af80b50] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-23 23:52:26,049 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:52:27,547 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/31146c0fcf22afd27c0f6abe91962b08efeefd7e "HTTP/1.1 200 OK"
2026-04-23 23:52:27,677 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:54:49,657 [INFO] 🛑 Connect loop cancelled, performing cleanup.
2026-04-23 23:54:49,657 [INFO] 🛑 ChatBot stopped
2026-04-23 23:54:51,948 [INFO] Запуск фото-бота на сервере tcs.sibcem.ru...
2026-04-23 23:54:52,321 [INFO] HTTP Request: POST https://tcs.sibcem.ru/bridge/api/client/v1/oauth/token "HTTP/1.1 201 Created"
2026-04-23 23:54:52,346 [INFO] HTTP Request: GET https://tcs.sibcem.ru/api/v4/server "HTTP/1.1 200 OK"
2026-04-23 23:54:52,347 [INFO] ⏳ Attempting WebSocket connection...
2026-04-23 23:54:52,364 [INFO] ✅ WebSocket connected
2026-04-23 23:54:52,364 [INFO] 🚀 Starting authorization
2026-04-23 23:54:52,364 [INFO] 🛠 Created AuthMethod with id=1
2026-04-23 23:54:52,433 [INFO] 🔐 Authenticated as bot_tcs@tcs.sibcem.ru/60d64d63
2026-04-23 23:55:04,223 [INFO] 📥 Incoming event: Message(timestamp=1776963301650, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=92, position='0'), content=AttachmentContent(file_name='image_2026.04.23_23-55-01_3280.webp', file_size=48884, file_id='ec564bb845d9ead8144a632a008ca361143ef326', mimetype='image/webp', ready_state=None), message_id='27865386-09b3-4d0d-bffa-7a077b831da9', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-23 23:55:04,224 [INFO] [router:0x775ecb984ca0] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-23 23:55:04,224 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:55:05,197 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/ec564bb845d9ead8144a632a008ca361143ef326 "HTTP/1.1 200 OK"
2026-04-23 23:55:05,405 [INFO] ✉️ Sending file to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:55:05,544 [INFO] Успешно обработано фото для ds.krivochenko
2026-04-23 23:56:02,536 [INFO] 📥 Incoming event: Message(timestamp=1776963359671, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=96, position='0'), content=AttachmentContent(file_name='image_2026.04.23_23-55-59_3880.webp', file_size=41150, file_id='3105ea960dbd509a3fd08ef9f09477053b31f6a5', mimetype='image/webp', ready_state=None), message_id='6dcfa1a4-452f-4999-b2e0-3385c04c754c', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-23 23:56:02,536 [INFO] [router:0x775ecb984ca0] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-23 23:56:02,536 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:56:03,985 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/3105ea960dbd509a3fd08ef9f09477053b31f6a5 "HTTP/1.1 200 OK"
2026-04-23 23:56:04,090 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:56:19,904 [INFO] 📥 Incoming event: Message(timestamp=1776963377210, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=99, position='0'), content=AttachmentContent(file_name='image_2026.04.23_23-56-16_9780.webp', file_size=30108, file_id='dbd42aa40a3491e5c496c906722887cccb99b47d', mimetype='image/webp', ready_state=None), message_id='37dd0e1b-e000-4de3-a160-3d4dc3c11743', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-23 23:56:19,904 [INFO] [router:0x775ecb984ca0] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-23 23:56:19,904 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:56:20,959 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/dbd42aa40a3491e5c496c906722887cccb99b47d "HTTP/1.1 200 OK"
2026-04-23 23:56:21,119 [INFO] ✉️ Sending file to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-23 23:56:21,254 [INFO] Успешно обработано фото для ds.krivochenko
2026-04-24 00:02:01,048 [INFO] 🛑 Connect loop cancelled, performing cleanup.
2026-04-24 00:02:01,049 [INFO] 🛑 ChatBot stopped
2026-04-24 00:02:03,574 [INFO] Запуск фото-бота на сервере tcs.sibcem.ru...
2026-04-24 00:02:03,963 [INFO] HTTP Request: POST https://tcs.sibcem.ru/bridge/api/client/v1/oauth/token "HTTP/1.1 201 Created"
2026-04-24 00:02:03,981 [INFO] HTTP Request: GET https://tcs.sibcem.ru/api/v4/server "HTTP/1.1 200 OK"
2026-04-24 00:02:03,982 [INFO] ⏳ Attempting WebSocket connection...
2026-04-24 00:02:03,996 [INFO] ✅ WebSocket connected
2026-04-24 00:02:03,996 [INFO] 🚀 Starting authorization
2026-04-24 00:02:03,996 [INFO] 🛠 Created AuthMethod with id=1
2026-04-24 00:02:04,069 [INFO] 🔐 Authenticated as bot_tcs@tcs.sibcem.ru/3aca404a
2026-04-24 00:02:18,536 [INFO] 📥 Incoming event: Message(timestamp=1776963735846, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=103, position='0'), content=AttachmentContent(file_name='image_2026.04.24_00-02-15_6030.webp', file_size=34002, file_id='75a04b613653999c91814222650aa3afad25acbd', mimetype='image/webp', ready_state=None), message_id='fbc6a5ad-14f0-45e3-974a-2c46d75beb6f', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 00:02:18,536 [INFO] [router:0x7099be182050] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 00:02:18,537 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:02:20,023 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/75a04b613653999c91814222650aa3afad25acbd "HTTP/1.1 200 OK"
2026-04-24 00:02:20,164 [INFO] ✉️ Sending file to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:02:20,293 [INFO] Успешно обработано фото для ds.krivochenko
2026-04-24 00:03:17,433 [INFO] 🛑 Connect loop cancelled, performing cleanup.
2026-04-24 00:03:17,433 [INFO] 🛑 ChatBot stopped
2026-04-24 00:03:19,011 [INFO] Запуск фото-бота на сервере tcs.sibcem.ru...
2026-04-24 00:03:19,279 [INFO] HTTP Request: POST https://tcs.sibcem.ru/bridge/api/client/v1/oauth/token "HTTP/1.1 201 Created"
2026-04-24 00:03:19,302 [INFO] HTTP Request: GET https://tcs.sibcem.ru/api/v4/server "HTTP/1.1 200 OK"
2026-04-24 00:03:19,303 [INFO] ⏳ Attempting WebSocket connection...
2026-04-24 00:03:19,322 [INFO] ✅ WebSocket connected
2026-04-24 00:03:19,322 [INFO] 🚀 Starting authorization
2026-04-24 00:03:19,322 [INFO] 🛠 Created AuthMethod with id=1
2026-04-24 00:03:19,393 [INFO] 🔐 Authenticated as bot_tcs@tcs.sibcem.ru/7686cbd0
2026-04-24 00:03:30,444 [INFO] 📥 Incoming event: Message(timestamp=1776963807702, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=107, position='0'), content=AttachmentContent(file_name='image_2026.04.24_00-03-27_4020.webp', file_size=32534, file_id='46dea905d43af0fd4a0aeb939cb52a0d54a41eb1', mimetype='image/webp', ready_state=None), message_id='a5bab295-8a17-401c-8782-45dd3cfa07e9', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 00:03:30,444 [INFO] [router:0x7f763ab7dea0] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 00:03:30,444 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:03:30,973 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/46dea905d43af0fd4a0aeb939cb52a0d54a41eb1 "HTTP/1.1 200 OK"
2026-04-24 00:03:31,141 [INFO] ✉️ Sending file to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:03:31,290 [INFO] Успешно обработано фото для ds.krivochenko
2026-04-24 00:04:57,657 [INFO] 🛑 Connect loop cancelled, performing cleanup.
2026-04-24 00:04:57,657 [INFO] 🛑 ChatBot stopped
2026-04-24 00:04:59,521 [INFO] Запуск фото-бота на сервере tcs.sibcem.ru...
2026-04-24 00:04:59,897 [INFO] HTTP Request: POST https://tcs.sibcem.ru/bridge/api/client/v1/oauth/token "HTTP/1.1 201 Created"
2026-04-24 00:04:59,920 [INFO] HTTP Request: GET https://tcs.sibcem.ru/api/v4/server "HTTP/1.1 200 OK"
2026-04-24 00:04:59,921 [INFO] ⏳ Attempting WebSocket connection...
2026-04-24 00:04:59,938 [INFO] ✅ WebSocket connected
2026-04-24 00:04:59,938 [INFO] 🚀 Starting authorization
2026-04-24 00:04:59,938 [INFO] 🛠 Created AuthMethod with id=1
2026-04-24 00:05:00,020 [INFO] 🔐 Authenticated as bot_tcs@tcs.sibcem.ru/dc28dd50
2026-04-24 00:05:12,095 [INFO] 📥 Incoming event: Message(timestamp=1776963909484, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=111, position='0'), content=AttachmentContent(file_name='image_2026.04.24_00-05-09_1850.webp', file_size=36734, file_id='137bb1dc861f951934607e84df8d2e3067b0e81a', mimetype='image/webp', ready_state=None), message_id='4fad207a-1a3a-4f5e-8ce6-ada8460e856e', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 00:05:12,096 [INFO] [router:0x7bc5f7589de0] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 00:05:12,096 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:05:13,600 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/137bb1dc861f951934607e84df8d2e3067b0e81a "HTTP/1.1 200 OK"
2026-04-24 00:05:13,758 [ERROR] Ошибка при работе с фото для ds.krivochenko: Message.answer_photo() missing 1 required positional argument: 'preview'
2026-04-24 00:05:13,758 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:06:47,892 [INFO] 🛑 Connect loop cancelled, performing cleanup.
2026-04-24 00:06:47,892 [INFO] 🛑 ChatBot stopped
2026-04-24 00:06:50,231 [INFO] Запуск фото-бота на сервере tcs.sibcem.ru...
2026-04-24 00:06:50,615 [INFO] HTTP Request: POST https://tcs.sibcem.ru/bridge/api/client/v1/oauth/token "HTTP/1.1 201 Created"
2026-04-24 00:06:50,634 [INFO] HTTP Request: GET https://tcs.sibcem.ru/api/v4/server "HTTP/1.1 200 OK"
2026-04-24 00:06:50,635 [INFO] ⏳ Attempting WebSocket connection...
2026-04-24 00:06:50,648 [INFO] ✅ WebSocket connected
2026-04-24 00:06:50,648 [INFO] 🚀 Starting authorization
2026-04-24 00:06:50,649 [INFO] 🛠 Created AuthMethod with id=1
2026-04-24 00:06:50,723 [INFO] 🔐 Authenticated as bot_tcs@tcs.sibcem.ru/89b2d6f9
2026-04-24 00:06:54,616 [INFO] 📥 Incoming event: Message(timestamp=1776964014581, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=114, position='0'), content=AttachmentContent(file_name='image_2026.04.24_00-06-54_0770.webp', file_size=36734, file_id='6b6d137bb96d86f9b064372b1d545ae5ca580e08', mimetype='image/webp', ready_state=None), message_id='45208bf9-4942-49ab-9db2-ac130fd48adf', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 00:06:54,616 [INFO] [router:0x757f5e571e70] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 00:06:54,616 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:06:56,676 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/6b6d137bb96d86f9b064372b1d545ae5ca580e08 "HTTP/1.1 200 OK"
2026-04-24 00:06:56,837 [INFO] ✉️ Sending photo to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:06:56,990 [INFO] Успешно обработано фото для ds.krivochenko
2026-04-24 00:10:28,416 [INFO] 🛑 Connect loop cancelled, performing cleanup.
2026-04-24 00:10:28,416 [INFO] 🛑 ChatBot stopped
2026-04-24 00:21:37,851 [INFO] Запуск фото-бота на сервере tcs.sibcem.ru...
2026-04-24 00:21:38,237 [INFO] HTTP Request: POST https://tcs.sibcem.ru/bridge/api/client/v1/oauth/token "HTTP/1.1 201 Created"
2026-04-24 00:21:38,257 [INFO] HTTP Request: GET https://tcs.sibcem.ru/api/v4/server "HTTP/1.1 200 OK"
2026-04-24 00:21:38,258 [INFO] ⏳ Attempting WebSocket connection...
2026-04-24 00:21:38,269 [INFO] ✅ WebSocket connected
2026-04-24 00:21:38,270 [INFO] 🚀 Starting authorization
2026-04-24 00:21:38,270 [INFO] 🛠 Created AuthMethod with id=1
2026-04-24 00:21:38,348 [INFO] 🔐 Authenticated as bot_tcs@tcs.sibcem.ru/1c46032d
2026-04-24 00:24:04,723 [INFO] 📥 Incoming event: Message(timestamp=1776965041929, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=118, position='0'), content=AttachmentContent(file_name='image_2026.04.24_00-24-01_6060.webp', file_size=28260, file_id='fc945836ef4f03ab001a2b8380ffe6743bfd7d71', mimetype='image/webp', ready_state=None), message_id='47af2156-718c-4b38-8c42-aeb26c002cf6', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 00:24:04,724 [INFO] [router:0x757ad5372650] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 00:24:04,725 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:24:06,125 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/fc945836ef4f03ab001a2b8380ffe6743bfd7d71 "HTTP/1.1 200 OK"
2026-04-24 00:24:06,301 [INFO] ✉️ Sending photo to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:24:06,455 [INFO] Фото подготовлено для ds.krivochenko, ждем подтверждения.
2026-04-24 00:24:32,525 [INFO] 📥 Incoming event: Message(timestamp=1776965072292, type=<MessageType.PLAIN_MESSAGE: 200>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=122, position='0'), content=TextContent(text='Нет', parse_mode='html'), message_id='af22acbc-5b9f-4f03-aaab-8b537733f964', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 00:24:32,525 [INFO] [router:0x757ad5372650] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 00:24:32,525 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:25:14,683 [INFO] 📥 Incoming event: Message(timestamp=1776965111899, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=124, position='0'), content=AttachmentContent(file_name='image_2026.04.24_00-25-11_5690.webp', file_size=25826, file_id='945182624c6424558092caf588aac83a071656b4', mimetype='image/webp', ready_state=None), message_id='40c604e8-d252-4227-92aa-cfe807e3ad10', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 00:25:14,683 [INFO] [router:0x757ad5372650] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 00:25:14,683 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:25:16,148 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/945182624c6424558092caf588aac83a071656b4 "HTTP/1.1 200 OK"
2026-04-24 00:25:16,258 [INFO] ✉️ Sending photo to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:25:16,411 [INFO] Фото подготовлено для ds.krivochenko, ждем подтверждения.
2026-04-24 00:25:30,911 [INFO] 📥 Incoming event: Message(timestamp=1776965130661, type=<MessageType.PLAIN_MESSAGE: 200>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=128, position='0'), content=TextContent(text='Да', parse_mode='html'), message_id='5cc37cc7-74d9-46c2-98f7-712ab19e6fad', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 00:25:30,911 [INFO] [router:0x757ad5372650] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 00:25:30,911 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:25:31,111 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:27:38,891 [INFO] 📥 Incoming event: Message(timestamp=1776965256125, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=131, position='0'), content=AttachmentContent(file_name='image_2026.04.24_00-27-35_8290.webp', file_size=39604, file_id='71c02d7294899f9b801d804dd5d2d8085f4ed300', mimetype='image/webp', ready_state=None), message_id='ebf9fab0-6c23-4231-8383-a628ff22831a', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 00:27:38,891 [INFO] [router:0x757ad5372650] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 00:27:38,891 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:27:40,704 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/71c02d7294899f9b801d804dd5d2d8085f4ed300 "HTTP/1.1 200 OK"
2026-04-24 00:27:40,849 [INFO] ✉️ Sending photo to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:27:41,004 [INFO] Фото подготовлено для ds.krivochenko, ждем подтверждения.
2026-04-24 00:28:35,890 [INFO] 📥 Incoming event: Message(timestamp=1776965313221, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=135, position='0'), content=AttachmentContent(file_name='image_2026.04.24_00-28-32_9170.webp', file_size=30814, file_id='a50aaded753fd1d8a8cd7be18b53d19f8ff81f9a', mimetype='image/webp', ready_state=None), message_id='ac4db733-0418-4f59-8483-03180350d633', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 00:28:35,890 [INFO] [router:0x757ad5372650] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 00:28:35,890 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:28:37,510 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/a50aaded753fd1d8a8cd7be18b53d19f8ff81f9a "HTTP/1.1 200 OK"
2026-04-24 00:28:37,662 [INFO] ✉️ Sending photo to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:28:37,814 [INFO] Фото подготовлено для ds.krivochenko, ждем подтверждения.
2026-04-24 00:29:02,445 [INFO] 📥 Incoming event: Message(timestamp=1776965342360, type=<MessageType.PLAIN_MESSAGE: 200>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=139, position='0'), content=TextContent(text='Да', parse_mode='html'), message_id='0a3128bc-ed28-48ac-acc1-dc8eabadfbf1', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 00:29:02,445 [INFO] [router:0x757ad5372650] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 00:29:02,445 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 00:29:02,672 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 01:08:28,256 [INFO] 📥 Incoming event: Message(timestamp=1776967707857, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=142, position='0'), content=AttachmentContent(file_name='image_2026.04.24_01-08-27_7210.webp', file_size=70874, file_id='3b9c34d0a4d5159302bbd2e664bbebc74bf7b1f8', mimetype='image/webp', ready_state=None), message_id='0b126ae1-9feb-4339-bee3-f9929a76da03', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 01:08:28,281 [INFO] [router:0x757ad5372650] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 01:08:28,300 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 01:08:30,338 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/3b9c34d0a4d5159302bbd2e664bbebc74bf7b1f8 "HTTP/1.1 200 OK"
2026-04-24 01:08:30,613 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 01:08:43,132 [INFO] 📥 Incoming event: Message(timestamp=1776967722748, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=145, position='0'), content=AttachmentContent(file_name='image_2026.04.24_01-08-42_5490.webp', file_size=44960, file_id='192fb72c99e818b5a3cc8e096d057716aa0a8fee', mimetype='image/webp', ready_state=None), message_id='027b3201-9cda-496f-9569-c047ad05dc3d', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 01:08:43,132 [INFO] [router:0x757ad5372650] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 01:08:43,132 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 01:08:44,085 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/192fb72c99e818b5a3cc8e096d057716aa0a8fee "HTTP/1.1 200 OK"
2026-04-24 01:08:44,329 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 01:08:55,062 [INFO] 📥 Incoming event: Message(timestamp=1776967734742, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=148, position='0'), content=AttachmentContent(file_name='image_2026.04.24_01-08-54_6370.webp', file_size=41150, file_id='cd7c52d43bb145cab9db9e5ece908c18a638e885', mimetype='image/webp', ready_state=None), message_id='dbbf3cab-aa5d-445d-ac4f-33e783bc4f20', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 01:08:55,063 [INFO] [router:0x757ad5372650] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 01:08:55,063 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 01:08:56,594 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/cd7c52d43bb145cab9db9e5ece908c18a638e885 "HTTP/1.1 200 OK"
2026-04-24 01:08:56,751 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 01:09:06,471 [INFO] 📥 Incoming event: Message(timestamp=1776967746177, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=151, position='0'), content=AttachmentContent(file_name='image_2026.04.24_01-09-05_9600.webp', file_size=51088, file_id='64c8e4f93958d31c7d968f31187a57242c8c75a1', mimetype='image/webp', ready_state=None), message_id='eec9d2de-01d5-469e-8805-7a4ae22b3c59', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 01:09:06,471 [INFO] [router:0x757ad5372650] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 01:09:06,471 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 01:09:08,453 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/64c8e4f93958d31c7d968f31187a57242c8c75a1 "HTTP/1.1 200 OK"
2026-04-24 01:09:08,592 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 12:08:20,569 [INFO] 📥 Incoming event: Message(timestamp=1777007297696, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=154, position='0'), content=AttachmentContent(file_name='image_2026.04.24_12-08-17_3930.webp', file_size=41550, file_id='ab6dd76dbccf29443043f9ad4a2259cdf9d88139', mimetype='image/webp', ready_state=None), message_id='146d6162-8b7d-4e2b-8d1c-cb79c859ff25', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 12:08:20,598 [INFO] [router:0x757ad5372650] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 12:08:20,617 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 12:08:22,738 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/ab6dd76dbccf29443043f9ad4a2259cdf9d88139 "HTTP/1.1 200 OK"
2026-04-24 12:08:23,151 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 12:08:39,495 [INFO] 📥 Incoming event: Message(timestamp=1777007316582, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=157, position='0'), content=AttachmentContent(file_name='image_2026.04.24_12-08-36_2420.webp', file_size=46970, file_id='6828a553f6cdbc5d0dfa224da4aef9948d3309aa', mimetype='image/webp', ready_state=None), message_id='832d86ea-82ec-4851-9507-818ad67e44d1', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 12:08:39,495 [INFO] [router:0x757ad5372650] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 12:08:39,495 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 12:08:41,467 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/6828a553f6cdbc5d0dfa224da4aef9948d3309aa "HTTP/1.1 200 OK"
2026-04-24 12:08:41,719 [INFO] ✉️ Sending photo to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 12:08:42,077 [INFO] Фото подготовлено для ds.krivochenko, ждем подтверждения.
2026-04-24 12:09:11,132 [INFO] 📥 Incoming event: Message(timestamp=1777007351000, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=161, position='0'), content=AttachmentContent(file_name='image_2026.04.24_12-09-10_5280.webp', file_size=50966, file_id='8b475f2a95701d32f2ca01cdc72a31ba1a775946', mimetype='image/webp', ready_state=None), message_id='f256a6b8-176c-4b5c-a6f0-9e25e856b829', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 12:09:11,132 [INFO] [router:0x757ad5372650] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 12:09:11,132 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 12:09:13,945 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/8b475f2a95701d32f2ca01cdc72a31ba1a775946 "HTTP/1.1 200 OK"
2026-04-24 12:09:14,301 [INFO] ✉️ Sending photo to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 12:09:14,440 [INFO] Фото подготовлено для ds.krivochenko, ждем подтверждения.
2026-04-24 12:09:29,899 [INFO] 📥 Incoming event: Message(timestamp=1777007369786, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=165, position='0'), content=AttachmentContent(file_name='image_2026.04.24_12-09-29_3140.webp', file_size=54302, file_id='9399f7914e37463ff42adc2647b90aaf4644e47d', mimetype='image/webp', ready_state=None), message_id='d650aa68-fd7a-414a-ad23-7d2d58d9ea5b', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 12:09:29,899 [INFO] [router:0x757ad5372650] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 12:09:29,899 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 12:09:31,446 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/9399f7914e37463ff42adc2647b90aaf4644e47d "HTTP/1.1 200 OK"
2026-04-24 12:09:31,543 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 12:09:45,818 [INFO] 📥 Incoming event: Message(timestamp=1777007385689, type=<MessageType.ATTACHMENT: 202>, author=EnvelopeAuthor(id='ds.krivochenko@tcs.sibcem.ru', type=<EnvelopeAuthorType.USER: 1>), box=EnvelopeBox(id=168, position='0'), content=AttachmentContent(file_name='image_2026.04.24_12-09-45_2090.webp', file_size=43322, file_id='225a71a2869ae1ca8f7d5a544f3eaec4b9f50587', mimetype='image/webp', ready_state=None), message_id='717652b9-de3a-456d-ae14-b6bd6f40a450', chat_id='744bad93e58c4c498e15468562c6a2da3b610e9c', is_edited=False, reply_message_id=None)
2026-04-24 12:09:45,818 [INFO] [router:0x757ad5372650] matched handler=async_wrapper filters=[InstanceOfFilter]
2026-04-24 12:09:45,818 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-24 12:09:47,467 [INFO] HTTP Request: GET https://tcs.sibcem.ru/bridge/api/client/v1/files/225a71a2869ae1ca8f7d5a544f3eaec4b9f50587 "HTTP/1.1 200 OK"
2026-04-24 12:09:47,569 [INFO] ✉️ Sending message to 744bad93e58c4c498e15468562c6a2da3b610e9c
2026-04-26 19:36:24,516 [INFO] 🛑 Connect loop cancelled, performing cleanup.
2026-04-26 19:36:24,549 [INFO] 🛑 ChatBot stopped
+127
View File
@@ -0,0 +1,127 @@
import io
import cv2
import os
import logging
import numpy as np
from PIL import Image, ImageFilter, ImageEnhance
logger = logging.getLogger(__name__)
def prepare_ad_photo(input_path: str, output_path: str, target_size: int = 96) -> dict:
try:
# 1. Загружаем изображение для OpenCV
if isinstance(input_path, bytes):
img = cv2.imdecode(np.frombuffer(input_path, np.uint8), cv2.IMREAD_COLOR)
else:
img = cv2.imread(input_path)
if img is None:
return {"success": False, "error": "Не удалось прочитать файл изображения."}
if isinstance(input_path, bytes):
img = cv2.imdecode(np.frombuffer(input_path, np.uint8), cv2.IMREAD_COLOR)
else:
img = cv2.imread(input_path)
if img is None:
return {"success": False, "error": "Не удалось прочитать файл изображения."}
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 2. Загружаем каскад Хаара для поиска лица
cascade_path = cv2.data.haarcascades + 'haarcascade_frontalface_default.xml'
face_cascade = cv2.CascadeClassifier(cascade_path)
# 3. Ищем лица
# Оставляем оптимальное значение minNeighbors=8 для баланса
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=8, minSize=(50, 50))
if len(faces) == 0:
return {"success": False, "error": "Лицо не найдено! Пожалуйста, сделайте фото анфас при хорошем освещении."}
if len(faces) > 1:
faces = sorted(faces, key=lambda f: f[2] * f[3], reverse=True)
x, y, w, h = faces[0]
# =========================================================
# АБСОЛЮТНАЯ ЗАЩИТА ОТ ГРАФИКИ (НОРМАЛИЗОВАННАЯ МАТЕМАТИКА)
# =========================================================
# 1. Вырезаем центральную зону лица
face_roi_original = gray[y + int(h*0.2):y + int(h*0.8), x + int(w*0.2):x + int(w*0.8)]
# 2. Сжимаем до 100x100 пикселей.
# Это уравнивает 4K-фотографии и мелкие картинки, делая метрики стабильными.
face_roi = cv2.resize(face_roi_original, (100, 100))
std_dev = np.std(face_roi)
laplacian_var = cv2.Laplacian(face_roi, cv2.CV_64F).var()
unique_colors = len(np.unique(face_roi))
logger.info(f"Анализ нормализованного лица: std_dev={std_dev:.2f}, laplacian={laplacian_var:.2f}, colors={unique_colors}")
# ПРОВЕРКА 1: Плоские, замыленные картинки
if std_dev < 10.0 or laplacian_var < 30.0:
logger.warning(f"Заблокирован плоский рисунок/замыливание: std={std_dev:.1f}, lap={laplacian_var:.1f}")
return {"success": False, "error": "Изображение слишком размыто или имеет плоскую текстуру. Отправьте реальное фото."}
# ПРОВЕРКА 2: Векторы, комиксы и жесткий 2D-арт (Умный порог резкости + цвета)
# У реального человека на хорошую камеру laplacian может доходить до 500-600,
# но при этом всегда будет богатая палитра цветов (шум матрицы).
# У мультиков высокая резкость всегда сопровождается бедной палитрой.
if laplacian_var > 850.0 or (laplacian_var > 400.0 and unique_colors < 150):
logger.warning(f"Заблокирован резкий 2D-арт: lap={laplacian_var:.1f}, colors={unique_colors}")
return {"success": False, "error": "Изображение похоже на графический арт или сильно отфильтровано. Пожалуйста, загрузите естественное фото."}
# ПРОВЕРКА 3: 3D-рендеры и нейросети (Мало шума)
# На реальной фотографии (даже с хорошим светом) шум матрицы телефона
# даст минимум 110-120 уникальных оттенков на 10000 пикселей.
if unique_colors < 105:
logger.warning(f"Заблокирован 3D-рендер по палитре: unique_colors={unique_colors}")
return {"success": False, "error": "Изображение распознано как 3D-модель или рисунок (неестественная палитра). Ждем реальное фото!"}
# =========================================================
# 4. Кадрируем (делаем квадрат с отступами вокруг лица)
margin = int(w * 0.3)
y1 = max(0, y - int(margin * 1.5))
y2 = min(img.shape[0], y + h + margin)
x1 = max(0, x - margin)
x2 = min(img.shape[1], x + w + margin)
side = min(x2 - x1, y2 - y1)
center_x, center_y = (x1 + x2) // 2, (y1 + y2) // 2
crop_x1 = max(0, center_x - side // 2)
crop_y1 = max(0, center_y - side // 2)
crop_x2 = crop_x1 + side
crop_y2 = crop_y1 + side
# 5. Обработка через Pillow
pil_img = Image.open(io.BytesIO(input_path))
# ВАЖНО: Убираем альфа-канал (прозрачность), иначе BMP выдаст ошибку
if pil_img.mode in ('RGBA', 'P', 'LA'):
background = Image.new('RGB', pil_img.size, (255, 255, 255))
background.paste(pil_img, mask=pil_img.split()[3] if pil_img.mode == 'RGBA' else None)
pil_img = background
elif pil_img.mode != 'RGB':
pil_img = pil_img.convert('RGB')
cropped_img = pil_img.crop((crop_x1, crop_y1, crop_x2, crop_y2))
# Сжимаем до нужного размера (96x96)
final_img = cropped_img.resize((target_size, target_size), Image.Resampling.LANCZOS)
# Добавляем немного резкости, чтобы лицо не мылилось при 96px
final_img = final_img.filter(ImageFilter.UnsharpMask(radius=1.5, percent=100, threshold=3))
# 6. Сохраняем в формате BMP
final_img.save(output_path, format="BMP")
# 7. Проверяем финальный вес
size_kb = os.path.getsize(output_path) / 1024
if size_kb > 99:
return {"success": False, "error": f"Сбой: размер файла ({size_kb:.1f} KB) превысил лимит в 99 KB."}
return {"success": True, "size_kb": round(size_kb, 1)}
except Exception as e:
logger.error(f"Ошибка в photo_processor: {e}")
return {"success": False, "error": str(e)}