Final release: Multi-session comment bot with filtering
Features: - Multi-account support (session files) - AI comments via Ollama - Telegram bot moderation - Filter by sessions and groups - Docker support - Auto-join groups - Log notifications - DB migration script Bug fixes: - Fixed comment_to for proper post targeting - Fixed entity lookup with multiple ID formats - Fixed callback handlers for filtering - Added auto-join before entity lookup
This commit is contained in:
@@ -12,7 +12,8 @@ from bot.db import (
|
||||
increment_regeneration, get_all_sessions, get_active_sessions,
|
||||
toggle_session, delete_session, get_summary_stats, get_stats,
|
||||
update_stats, add_target_group, get_target_groups, get_all_target_groups,
|
||||
remove_target_group, toggle_target_group, is_target_group
|
||||
remove_target_group, toggle_target_group, is_target_group,
|
||||
get_pending_comments_by_session, get_pending_comments_by_group
|
||||
)
|
||||
from bot.ollama import generate_comment
|
||||
from bot.keyboard import (
|
||||
@@ -381,15 +382,27 @@ class CommentBot:
|
||||
if data == "stats":
|
||||
await self._callback_stats(callback)
|
||||
elif data == "sessions":
|
||||
await self._callback_sessions(callback)
|
||||
await self._callback_sessions_list(callback)
|
||||
elif data.startswith("session_select:"):
|
||||
session_file = data.split(":")[1]
|
||||
await self._callback_session_pending(callback, session_file)
|
||||
elif data == "pending":
|
||||
await self._callback_pending(callback)
|
||||
await self._callback_pending_groups(callback)
|
||||
elif data.startswith("group_pending:"):
|
||||
group_id = data.split(":")[1]
|
||||
await self._callback_group_pending(callback, group_id)
|
||||
elif data == "groups":
|
||||
await self._callback_groups(callback)
|
||||
elif data == "group_add":
|
||||
await self._callback_group_add(callback)
|
||||
elif data.startswith("group_"):
|
||||
await self._callback_group_action(callback)
|
||||
elif data.startswith("group_info:"):
|
||||
await self._callback_group_info(callback, data)
|
||||
elif data.startswith("group_pause:"):
|
||||
await self._callback_group_action(callback, "pause", data)
|
||||
elif data.startswith("group_resume:"):
|
||||
await self._callback_group_action(callback, "resume", data)
|
||||
elif data.startswith("group_delete:"):
|
||||
await self._callback_group_action(callback, "delete", data)
|
||||
elif data.startswith("approve:"):
|
||||
await self._callback_approve(callback)
|
||||
elif data.startswith("reject:"):
|
||||
@@ -400,8 +413,16 @@ class CommentBot:
|
||||
await self._callback_edit(callback)
|
||||
elif data.startswith("edit_cancel:"):
|
||||
await self._callback_edit_cancel(callback)
|
||||
elif data.startswith("session_"):
|
||||
await self._callback_session_action(callback)
|
||||
elif data.startswith("session_status:"):
|
||||
await self._callback_session_action(callback, "status", data)
|
||||
elif data.startswith("session_pause:"):
|
||||
await self._callback_session_action(callback, "pause", data)
|
||||
elif data.startswith("session_resume:"):
|
||||
await self._callback_session_action(callback, "resume", data)
|
||||
elif data.startswith("session_delete:"):
|
||||
await self._callback_session_action(callback, "delete", data)
|
||||
elif data == "main_menu":
|
||||
await self._callback_main_menu(callback)
|
||||
else:
|
||||
await callback.answer("Неизвестная команда")
|
||||
|
||||
@@ -462,6 +483,99 @@ class CommentBot:
|
||||
|
||||
await callback.answer()
|
||||
|
||||
|
||||
async def _callback_sessions_list(self, callback: CallbackQuery):
|
||||
"""Callback для списка сессий"""
|
||||
sessions = get_all_sessions()
|
||||
|
||||
if not sessions:
|
||||
text = "❌ Нет сессий\n\nДобавьте файлы сессий в `sessions/`"
|
||||
await callback.message.edit_text(text, reply_markup=create_back_keyboard())
|
||||
else:
|
||||
text = "👥 **Сессии**\n\nВыберите сессию для просмотра комментариев:\n\n"
|
||||
for session in sessions:
|
||||
status = "🟢" if session['is_active'] else "🔴"
|
||||
username = f"@{session['username']}" if session.get('username') else ""
|
||||
text += f"{status} `{session['session_file']}` {username}\n"
|
||||
|
||||
await callback.message.edit_text(
|
||||
text,
|
||||
parse_mode="Markdown",
|
||||
reply_markup=create_sessions_list_keyboard(sessions)
|
||||
)
|
||||
|
||||
await callback.answer()
|
||||
|
||||
async def _callback_session_pending(self, callback: CallbackQuery, session_file: str):
|
||||
"""Callback для просмотра pending комментариев сессии"""
|
||||
pending = get_pending_comments_by_session(session_file)
|
||||
|
||||
if not pending:
|
||||
await callback.message.edit_text(
|
||||
f"✅ Нет ожидающих комментариев для `{session_file}`",
|
||||
reply_markup=create_back_keyboard()
|
||||
)
|
||||
else:
|
||||
await callback.message.edit_text(
|
||||
f"📝 Ожидают модерации ({len(pending)}):\n\nСессия: `{session_file}`",
|
||||
reply_markup=create_back_keyboard()
|
||||
)
|
||||
for comment in pending[:10]:
|
||||
await self._send_moderation_message(
|
||||
chat_id=callback.message.chat.id,
|
||||
comment=comment
|
||||
)
|
||||
|
||||
await callback.answer()
|
||||
|
||||
async def _callback_pending_groups(self, callback: CallbackQuery):
|
||||
"""Callback для выбора группы из pending"""
|
||||
groups = get_all_target_groups()
|
||||
|
||||
if not groups:
|
||||
text = "📋 **Нет групп**\n\nДобавьте группу через /add_group"
|
||||
await callback.message.edit_text(text, parse_mode="Markdown", reply_markup=create_back_keyboard())
|
||||
else:
|
||||
text = "📋 **Группы**\n\nВыберите группу для просмотра комментариев:\n\n"
|
||||
for group in groups:
|
||||
name = group['group_name'] or f"Группа {group['group_id']}"
|
||||
text += f"📢 `{name}`\n"
|
||||
|
||||
await callback.message.edit_text(
|
||||
text,
|
||||
parse_mode="Markdown",
|
||||
reply_markup=create_groups_list_for_pending_keyboard(groups)
|
||||
)
|
||||
|
||||
await callback.answer()
|
||||
|
||||
async def _callback_group_pending(self, callback: CallbackQuery, group_id: str):
|
||||
"""Callback для просмотра pending комментариев группы"""
|
||||
pending = get_pending_comments_by_group(group_id)
|
||||
|
||||
if not pending:
|
||||
await callback.message.edit_text(
|
||||
f"✅ Нет ожидающих комментариев для этой группы",
|
||||
reply_markup=create_back_keyboard()
|
||||
)
|
||||
else:
|
||||
await callback.message.edit_text(
|
||||
f"📝 Ожидают модерации ({len(pending)}):\n\nГруппа: `{group_id}`",
|
||||
reply_markup=create_back_keyboard()
|
||||
)
|
||||
for comment in pending[:10]:
|
||||
await self._send_moderation_message(
|
||||
chat_id=callback.message.chat.id,
|
||||
comment=comment
|
||||
)
|
||||
|
||||
await callback.answer()
|
||||
|
||||
async def _callback_main_menu(self, callback: CallbackQuery):
|
||||
"""Callback для возврата в главное меню"""
|
||||
await self.cmd_start(callback.message)
|
||||
await callback.answer()
|
||||
|
||||
async def _callback_settings(self, callback: CallbackQuery):
|
||||
"""Callback для настроек"""
|
||||
text = (
|
||||
@@ -622,16 +736,38 @@ class CommentBot:
|
||||
channel_id = comment.get('channel_id') or comment['chat_id']
|
||||
post_url = f"https://t.me/c/{channel_id}/{comment['message_id']}"
|
||||
|
||||
# Получаем название группы/канала из БД
|
||||
# Ищем по chat_id (группа комментариев) или по channel_id (канал)
|
||||
groups = get_all_target_groups()
|
||||
group = None
|
||||
|
||||
# Сначала ищем по chat_id (группа комментариев)
|
||||
for g in groups:
|
||||
if str(g['group_id']) == str(comment['chat_id']):
|
||||
group = g
|
||||
break
|
||||
# Или по channel_id (канал)
|
||||
if str(g.get('group_id')) == str(channel_id):
|
||||
group = g
|
||||
break
|
||||
# Или по comments_group_id
|
||||
if str(g.get('comments_group_id')) == str(comment['chat_id']):
|
||||
group = g
|
||||
break
|
||||
|
||||
group_name = group['group_name'] if group and group.get('group_name') else f"Канал {channel_id}"
|
||||
|
||||
session_info = ""
|
||||
if comment.get('session_file'):
|
||||
session_info = f"👤 Сессия: `{comment['session_file']}`\n\n"
|
||||
|
||||
|
||||
post_text = comment.get('post_text', 'Текст поста не сохранён')
|
||||
if len(post_text) > 300:
|
||||
post_text = post_text[:300] + "..."
|
||||
|
||||
|
||||
text = (
|
||||
f"📝 **Новый комментарий**\n\n"
|
||||
f"📝 Новый комментарий\n\n"
|
||||
f"📢 Канал: **{group_name}**\n"
|
||||
f"🔗 Пост: {post_url}\n"
|
||||
f"{session_info}"
|
||||
f"📄 Текст поста:\n"
|
||||
@@ -640,13 +776,13 @@ class CommentBot:
|
||||
f"_{comment['comment_text'][:500]}_{'...' if len(comment['comment_text']) > 500 else ''}\n\n"
|
||||
f"🔄 Регенераций: {comment.get('regenerations', 0)}"
|
||||
)
|
||||
|
||||
|
||||
keyboard = create_moderation_keyboard(
|
||||
comment['id'],
|
||||
comment['message_id'],
|
||||
comment['chat_id']
|
||||
)
|
||||
|
||||
|
||||
await self.bot.send_message(
|
||||
chat_id=chat_id,
|
||||
text=text,
|
||||
|
||||
Reference in New Issue
Block a user