105 lines
5.4 KiB
Python
105 lines
5.4 KiB
Python
from telegram import Update, InputMediaPhoto, InlineKeyboardMarkup, InlineKeyboardButton
|
|
from telegram.ext import ContextTypes, ConversationHandler, MessageHandler, CommandHandler, filters, CallbackQueryHandler, ContextTypes
|
|
|
|
from db import AsyncSessionLocal
|
|
from models import Channel, Group, Button
|
|
|
|
SELECT_MEDIA, SELECT_TEXT, SELECT_TARGET = range(3)
|
|
|
|
async def new_post_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|
if update.message:
|
|
await update.message.reply_text('Отправьте картинку для поста или /skip:')
|
|
return SELECT_MEDIA
|
|
return ConversationHandler.END
|
|
|
|
async def select_media(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|
if update.message and hasattr(update.message, 'photo') and update.message.photo:
|
|
if context.user_data is None:
|
|
context.user_data = {}
|
|
context.user_data['photo'] = update.message.photo[-1].file_id
|
|
if update.message:
|
|
await update.message.reply_text('Введите текст поста или пересланное сообщение:')
|
|
return SELECT_TEXT
|
|
return ConversationHandler.END
|
|
|
|
async def select_text(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|
if update.message:
|
|
if context.user_data is None:
|
|
context.user_data = {}
|
|
context.user_data['text'] = getattr(update.message, 'text', None) or getattr(update.message, 'caption', None)
|
|
from sqlalchemy import select
|
|
session = AsyncSessionLocal()
|
|
try:
|
|
channels_result = await session.execute(select(Channel))
|
|
channels = channels_result.scalars().all()
|
|
groups_result = await session.execute(select(Group))
|
|
groups = groups_result.scalars().all()
|
|
keyboard = []
|
|
for c in channels:
|
|
keyboard.append([InlineKeyboardButton(f'Канал: {getattr(c, "name", str(c.name))}', callback_data=f'channel_{getattr(c, "id", str(c.id))}')])
|
|
for g in groups:
|
|
keyboard.append([InlineKeyboardButton(f'Группа: {getattr(g, "name", str(g.name))}', callback_data=f'group_{getattr(g, "id", str(g.id))}')])
|
|
reply_markup = InlineKeyboardMarkup(keyboard)
|
|
await update.message.reply_text('Выберите, куда отправить пост:', reply_markup=reply_markup)
|
|
return SELECT_TARGET
|
|
finally:
|
|
await session.close()
|
|
return ConversationHandler.END
|
|
|
|
async def select_target(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|
query = update.callback_query
|
|
if not query:
|
|
return ConversationHandler.END
|
|
await query.answer()
|
|
data = query.data
|
|
session = AsyncSessionLocal()
|
|
try:
|
|
chat_id = None
|
|
markup = None
|
|
if data and data.startswith('channel_'):
|
|
from sqlalchemy import select
|
|
channel_id = int(data.split('_')[1])
|
|
channel_result = await session.execute(select(Channel).where(Channel.id == channel_id))
|
|
channel = channel_result.scalar_one_or_none()
|
|
buttons_result = await session.execute(select(Button).where(Button.channel_id == channel_id))
|
|
buttons = buttons_result.scalars().all()
|
|
markup = InlineKeyboardMarkup([[InlineKeyboardButton(str(b.name), url=str(b.url))] for b in buttons]) if buttons else None
|
|
chat_id = getattr(channel, 'link', None)
|
|
elif data and data.startswith('group_'):
|
|
from sqlalchemy import select
|
|
group_id = int(data.split('_')[1])
|
|
group_result = await session.execute(select(Group).where(Group.id == group_id))
|
|
group = group_result.scalar_one_or_none()
|
|
buttons_result = await session.execute(select(Button).where(Button.group_id == group_id))
|
|
buttons = buttons_result.scalars().all()
|
|
markup = InlineKeyboardMarkup([[InlineKeyboardButton(str(b.name), url=str(b.url))] for b in buttons]) if buttons else None
|
|
chat_id = getattr(group, 'link', None)
|
|
if chat_id:
|
|
chat_id = chat_id.strip()
|
|
if not (chat_id.startswith('@') or chat_id.startswith('-')):
|
|
await query.edit_message_text('Ошибка: ссылка должна быть username (@channel) или числовой ID (-100...)')
|
|
return ConversationHandler.END
|
|
try:
|
|
photo = context.user_data.get('photo') if context.user_data else None
|
|
if photo:
|
|
await context.bot.send_photo(chat_id=chat_id, photo=photo, caption=context.user_data.get('text') if context.user_data else None, reply_markup=markup)
|
|
await query.edit_message_text('Пост отправлен!')
|
|
else:
|
|
await query.edit_message_text('Ошибка: не выбрано фото для поста.')
|
|
except Exception as e:
|
|
await query.edit_message_text(f'Ошибка отправки поста: {e}')
|
|
finally:
|
|
await session.close()
|
|
return ConversationHandler.END
|
|
|
|
new_post_conv = ConversationHandler(
|
|
entry_points=[CommandHandler('new_post', new_post_start)],
|
|
states={
|
|
SELECT_MEDIA: [MessageHandler(filters.PHOTO | filters.Document.IMAGE | filters.COMMAND, select_media)],
|
|
SELECT_TEXT: [MessageHandler(filters.TEXT | filters.FORWARDED, select_text)],
|
|
SELECT_TARGET: [CallbackQueryHandler(select_target)],
|
|
},
|
|
fallbacks=[],
|
|
|
|
)
|