Initial commit: Batch Bot - Telegram Comment Bot

0.0.1
Features:
- Multi-account support via session files
- AI comments generation via Ollama (local LLM)
- Telegram bot for moderation (approve/reject/regenerate)
- Docker support (controller + worker)
- Auto-join public groups
- Comment regeneration on group re-add
- Statistics tracking

Tech stack:
- Python 3.11
- Telethon 1.34 (Telegram user client)
- Aiogram 3.4 (Telegram bot framework)
- SQLite (Database)
- Docker & Docker Compose
- Ollama (Local LLM)
This commit is contained in:
2026-02-24 04:40:07 +03:00
commit a18ad30961
20 changed files with 3431 additions and 0 deletions

120
bot/keyboard.py Normal file
View File

@@ -0,0 +1,120 @@
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, ReplyKeyboardMarkup, KeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder, ReplyKeyboardBuilder
def create_moderation_keyboard(comment_id: int, message_id: int, chat_id: int) -> InlineKeyboardMarkup:
"""Создание клавиатуры модерации для комментария"""
# Используем только comment_id для callback data (чтобы не превышать лимит 64 байта)
callback_data = f"{comment_id}"
builder = InlineKeyboardBuilder()
# Кнопки одобрения/отклонения
builder.button(text="✅ Одобрить", callback_data=f"approve:{callback_data}")
builder.button(text="❌ Отклонить", callback_data=f"reject:{callback_data}")
builder.button(text="🔄 Регенерировать", callback_data=f"regenerate:{callback_data}")
builder.button(text="✏️ Редактировать", callback_data=f"edit:{callback_data}")
builder.adjust(2, 2)
return builder.as_markup()
def create_session_keyboard(session_file: str) -> InlineKeyboardMarkup:
"""Клавиатура управления сессией"""
builder = InlineKeyboardBuilder()
builder.button(text="🔘 Статус", callback_data=f"session_status:{session_file}")
builder.button(text="⏸️ Пауза", callback_data=f"session_pause:{session_file}")
builder.button(text="▶️ Активировать", callback_data=f"session_resume:{session_file}")
builder.button(text="🗑️ Удалить", callback_data=f"session_delete:{session_file}")
builder.adjust(2, 2)
return builder.as_markup()
def create_edit_cancel_keyboard(comment_id: int, message_id: int = 0, chat_id: int = 0) -> InlineKeyboardMarkup:
"""Клавиатура для отмены редактирования"""
builder = InlineKeyboardBuilder()
builder.button(text="❌ Отмена", callback_data=f"edit_cancel:{comment_id}")
return builder.as_markup()
def create_main_menu() -> InlineKeyboardMarkup:
"""Главное меню бота (inline)"""
builder = InlineKeyboardBuilder()
builder.button(text="📊 Статистика", callback_data="stats")
builder.button(text="👥 Сессии", callback_data="sessions")
builder.button(text="📝 Ожидающие", callback_data="pending")
builder.button(text="📋 Группы", callback_data="groups")
builder.button(text="⚙️ Настройки", callback_data="settings")
builder.adjust(2, 2, 1)
return builder.as_markup()
def create_main_keyboard() -> ReplyKeyboardMarkup:
"""Главное меню бота (постоянная клавиатура)"""
builder = ReplyKeyboardBuilder()
builder.button(text="📊 Статистика")
builder.button(text="👥 Сессии")
builder.button(text="📝 Ожидающие")
builder.button(text="📋 Группы")
builder.button(text=" Добавить группу")
builder.button(text="❓ Помощь")
builder.adjust(2, 2, 2)
return builder.as_markup(resize_keyboard=True)
def create_groups_list_keyboard(groups: list) -> InlineKeyboardMarkup:
"""Клавиатура со списком групп"""
builder = InlineKeyboardBuilder()
for group in groups:
group_id = group['group_id']
status = "🟢" if group['is_active'] else "🔴"
name = group['group_name'] or f"Группа {group_id}"
builder.button(
text=f"{status} {name}",
callback_data=f"group_info:{group_id}"
)
builder.adjust(1)
# Кнопка добавления новой группы
builder.button(text=" Добавить группу", callback_data="group_add")
return builder.as_markup()
def create_group_action_keyboard(group_id: int) -> InlineKeyboardMarkup:
"""Клавиатура действий с группой"""
builder = InlineKeyboardBuilder()
builder.button(text="⏸️ Пауза", callback_data=f"group_pause:{group_id}")
builder.button(text="▶️ Активировать", callback_data=f"group_resume:{group_id}")
builder.button(text="🗑️ Удалить", callback_data=f"group_delete:{group_id}")
builder.button(text="🔙 Назад", callback_data="groups")
builder.adjust(2, 2)
return builder.as_markup()
def create_sessions_list_keyboard(sessions: list) -> InlineKeyboardMarkup:
"""Клавиатура со списком сессий"""
builder = InlineKeyboardBuilder()
for session in sessions:
session_file = session['session_file']
status = "🟢" if session['is_active'] else "🔴"
builder.button(
text=f"{status} {session_file}",
callback_data=f"session_info:{session_file}"
)
builder.adjust(1)
return builder.as_markup()