@aspitsin138

Как отправлять данные пользователю из бота telegram?

Нужно собирать через бот информацию с пользователя и отправлять ее в чат. После нажатия кнопки "Отправить" ничего не происходит, нет ни ошибки ни отправленного сообщения. Разрешения у пользователя на прием сообщений включены. Пробовал на разные ID отправлять, не отправляет. Код:
import re
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import Application, CommandHandler, MessageHandler, filters, CallbackQueryHandler, ContextTypes

# Устанавливаем токены для Telegram бота
telegram_token = ''

# Обработчик команды /start
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    keyboard = [
        [InlineKeyboardButton("Позвать менеджера", callback_data='call_manager')],
        [InlineKeyboardButton("Запрос стоимости", callback_data='request_price')],
        [InlineKeyboardButton("Выкуп", callback_data='purchase')],
        [InlineKeyboardButton("Назад", callback_data='back')]
    ]
    reply_markup = InlineKeyboardMarkup(keyboard)
    await update.message.reply_text("Привет, как дела?", reply_markup=reply_markup)

# Обработчик для кнопок меню
async def button(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    query = update.callback_query
    await query.answer()

    if query.data == 'request_price':
        context.user_data['request_step'] = 1
        await query.message.reply_text("Введите наименование:")
    elif query.data == 'purchase':
        context.user_data['purchase_step'] = 1
        await query.message.reply_text("Введите наименование:")
    elif query.data == 'call_manager':
        await query.message.reply_text("Подключение к менеджеру @")
    elif query.data == 'back':
        await start(update, context)

# Функция проверки, является ли строка числом
def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

# Функция проверки, является ли строка ссылкой
def is_valid_url(url):
    regex = re.compile(
        r'^(?:http|ftp)s?://'  # http:// or https://
        r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|'  # domain...
        r'localhost|'  # localhost...
        r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|'  # ...or ipv4
        r'\[?[A-F0-9]*:[A-F0-9:]+\]?)'  # ...or ipv6
        r'(?::\d+)?'  # optional port
        r'(?:/?|[/?]\S+)$', re.IGNORECASE)
    return re.match(regex, url) is not None

# Обработчик для запроса стоимости
async def handle_request_price(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    step = context.user_data.get('request_step', 0)
    
    if step == 1:
        context.user_data['name'] = update.message.text
        context.user_data['request_step'] = 2
        await update.message.reply_text("Введите вес:")
    elif step == 2:
        if not is_number(update.message.text):
            await update.message.reply_text("Введите корректное число для веса:")
            return
        context.user_data['weight'] = update.message.text
        context.user_data['request_step'] = 3
        await update.message.reply_text("Введите объем:")
    elif step == 3:
        if not is_number(update.message.text):
            await update.message.reply_text("Введите корректное число для объема:")
            return
        context.user_data['volume'] = update.message.text
        context.user_data['request_step'] = 4
        await update.message.reply_text("Загрузите фотографию:")
    elif step == 4:
        if not update.message.photo and not update.message.document:
            await update.message.reply_text("Пожалуйста, загрузите фотографию.")
            return
        if update.message.photo:
            photo_file = await update.message.photo[-1].get_file()
        else:
            photo_file = await update.message.document.get_file()
        photo_path = f'/Users/a1/Documents/для телеграм/{photo_file.file_id}.jpg'
        await photo_file.download_to_drive(photo_path)
        context.user_data['photo'] = photo_path
        context.user_data['request_step'] = 5
        await update.message.reply_text("Нажмите кнопку 'Отправить', чтобы получить данные.")
        await update.message.reply_text("Отправить", reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("Отправить", callback_data='send_request_price')]]))

# Обработчик для выкупа
async def handle_purchase(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    step = context.user_data.get('purchase_step', 0)
    
    if step == 1:
        context.user_data['name'] = update.message.text
        context.user_data['purchase_step'] = 2
        await update.message.reply_text("Введите ссылку:")
    elif step == 2:
        if not is_valid_url(update.message.text):
            await update.message.reply_text("Введите корректную ссылку:")
            return
        context.user_data['link'] = update.message.text
        context.user_data['purchase_step'] = 3
        await update.message.reply_text("Введите комментарии:")
    elif step == 3:
        context.user_data['comments'] = update.message.text
        context.user_data['purchase_step'] = 4
        await update.message.reply_text("Загрузите фотографию:")
    elif step == 4:
        if not update.message.photo and not update.message.document:
            await update.message.reply_text("Пожалуйста, загрузите фотографию.")
            return
        if update.message.photo:
            photo_file = await update.message.photo[-1].get_file()
        else:
            photo_file = await update.message.document.get_file()
        photo_path = f'photos/{photo_file.file_id}.jpg'
        await photo_file.download_to_drive(photo_path)
        context.user_data['photo'] = photo_path
        context.user_data['purchase_step'] = 5
        await update.message.reply_text("Нажмите кнопку 'Отправить', чтобы получить данные.")
        await update.message.reply_text("Отправить", reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("Отправить", callback_data='send_purchase')]]))

# Обработчик отправки данных пользователю
async def send_to_user(update: Update, context: ContextTypes.DEFAULT_TYPE, type_: str) -> None:
    user_data = context.user_data
    username = update.message.from_user.username  # Получаем имя пользователя

    if type_ == 'request_price':
        data = f"Наименование: {user_data.get('name')}\nВес: {user_data.get('weight')}\nОбъем: {user_data.get('volume')}\nФото: {user_data.get('photo')}\n\nUsername: {username}"
        title = "Запрос на стоимость"
    elif type_ == 'purchase':
        data = f"Наименование: {user_data.get('name')}\nСсылка: {user_data.get('link')}\nКомментарии: {user_data.get('comments')}\nФото: {user_data.get('photo')}\n\nUsername: {username}"
        title = "Запрос на выкуп"

    chat_id = ''  # Обновите настоящим chat ID
    try:
        await context.bot.send_message(chat_id=chat_id, text=f"<b>{title}</b>\n\n{data}", parse_mode='HTML')
        await update.callback_query.message.reply_text("Данные успешно отправлены.")
    except Exception as e:
        print(f"Ошибка при отправке сообщения: {e}")
        await update.callback_query.message.reply_text("Произошла ошибка при отправке данных.")

    print(f"Данные отправлены в {chat_id}:\n{data}")
    
    

    
# Обработчик для кнопок отправки данных
async def callback_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    query = update.callback_query
    await query.answer()

    if query.data == 'send_request_price':
        await send_to_user(update, context, 'request_price')
    elif query.data == 'send_purchase':
        await send_to_user(update, context, 'purchase')
    elif query.data == 'back':
        await start(update, context)

# Создаем и настраиваем приложение бота
application = Application.builder().token(telegram_token).build()

# Добавляем обработчики команд и сообщений
application.add_handler(CommandHandler('start', start))
application.add_handler(CallbackQueryHandler(button))
application.add_handler(CallbackQueryHandler(callback_handler))
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_request_price))
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_purchase))
application.add_handler(MessageHandler(filters.PHOTO, handle_request_price))
application.add_handler(MessageHandler(filters.PHOTO, handle_purchase))
application.add_handler(MessageHandler(filters.Document.ALL, handle_request_price))
application.add_handler(MessageHandler(filters.Document.ALL, handle_purchase))

# Запускаем бота
application.run_polling()
  • Вопрос задан
  • 180 просмотров
Решения вопроса 1
Vindicar
@Vindicar
RTFM!
У тебя, походу, button() прописан как обработчик для всех кнопок. А вот внутри него не прописана ветка для data == 'send_purchase'. На текущем шаге добавь во ВСЕ цепочки if ... elif ... elif ... ветку else, которая выводит отладочное сообщение - тогда хоть будет понятно, какой обработчик вызвался и с каким значением.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы