@Dezzly

Почему не отправляется рассылка в боте telegram?

В таком состояние все работает, но рассылка отправляется при вводе любого сообщения в чат чего не должно быть.
import asyncio
import logging
import sqlite3

from aiogram import Bot, Dispatcher, types, F
from aiogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery
from aiogram.filters import CommandStart, Command
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup

# *** Настройки ***
TOKEN = '***'
ADMIN_ID = [1966823500]

# *** Инициализация ***
logging.basicConfig(level=logging.INFO)
bot = Bot(token=TOKEN)
dp = Dispatcher()

# *** База данных ***
DB_FILE = 'users.db'

def create_db():
    conn = sqlite3.connect(DB_FILE)
    cursor = conn.cursor()
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS users (
            id INTEGER PRIMARY KEY,
            user_id INTEGER UNIQUE
        )
    ''')
    conn.commit()
    conn.close()

create_db()

def add_user(user_id):
    conn = sqlite3.connect(DB_FILE)
    cursor = conn.cursor()
    try:
        cursor.execute("INSERT INTO users (user_id) VALUES (?)", (user_id,))
        conn.commit()
        logging.info(f"Добавлен пользователь с ID: {user_id}")
    except sqlite3.IntegrityError:
        logging.info(f"Пользователь с ID: {user_id} уже существует")
    finally:
        conn.close()

def get_all_users():
    conn = sqlite3.connect(DB_FILE)
    cursor = conn.cursor()
    cursor.execute("SELECT user_id FROM users")
    users = [row[0] for row in cursor.fetchall()]
    conn.close()
    return users

# *** Состояния FSM ***
class States(StatesGroup):
    waiting_for_text = State()

broadcast_text = ""  

# *** Обработчики ***
@dp.message(CommandStart())
async def cmd_start(message: Message):
    user_id = message.from_user.id
    logging.info(f"Обработчик /start вызван пользователем с ID: {user_id}")
    add_user(user_id)
    await message.answer("Привет! Ты зарегистрирован в боте.")

@dp.message(Command("admin"), lambda msg: msg.from_user.id in ADMIN_ID)
async def cmd_admin(message: Message):
    user_id = message.from_user.id
    logging.info(f"Обработчик /admin вызван пользователем с ID: {user_id}")
    await message.answer("Админ-панель:\n"
                         "Выберите действие:",
                         reply_markup=InlineKeyboardMarkup(inline_keyboard=[
                             [InlineKeyboardButton(text="Начать рассылку", callback_data="start_broadcast")],
                             [InlineKeyboardButton(text="Статистика пользователей", callback_data="user_stats")]
                         ]))

@dp.callback_query(F.data == 'start_broadcast')
async def process_start_broadcast(callback: CallbackQuery):
    logging.info(f"Обработчик 'start_broadcast' вызван пользователем с ID: {callback.from_user.id}")
    global broadcast_text
    await callback.message.answer("Введите текст для рассылки:")

# Ожидаем сообщение с текстом рассылки
@dp.message()
async def get_broadcast_text(message: types.Message):
    global broadcast_text
    logging.info(f"Получен текст рассылки от пользователя с ID: {message.from_user.id}: {message.text}")
    broadcast_text = message.text
    keyboard = InlineKeyboardMarkup(inline_keyboard=[
        [InlineKeyboardButton(text='Да', callback_data='confirm_broadcast'),
         InlineKeyboardButton(text='Нет', callback_data='cancel_broadcast')]
    ])
    await message.answer("Подтвердите рассылку:", reply_markup=keyboard)

@dp.callback_query(F.data == 'confirm_broadcast')
async def confirm_broadcast(callback: CallbackQuery):
    logging.info(f"Обработчик 'confirm_broadcast' вызван пользователем с ID: {callback.from_user.id}")
    global broadcast_text
    if broadcast_text:
        await callback.message.answer("Рассылка началась...")
        await send_broadcast(broadcast_text)
        await callback.message.answer("Рассылка завершена!")
        broadcast_text = ""  # Очищаем текст рассылки после отправки

@dp.callback_query(F.data == 'cancel_broadcast')
async def cancel_broadcast(callback: CallbackQuery):
    logging.info(f"Обработчик 'cancel_broadcast' вызван пользователем с ID: {callback.from_user.id}")
    global broadcast_text
    broadcast_text = ""  # Очищаем текст рассылки
    await callback.message.answer("Рассылка отменена.")

@dp.callback_query(F.data == 'user_stats')
async def process_user_stats(callback: CallbackQuery):
    logging.info(f"Обработчик 'user_stats' вызван пользователем с ID: {callback.from_user.id}")
    total_users = len(get_all_users())
    await callback.message.answer(f"Всего пользователей в боте: {total_users}")

async def send_broadcast(text):
    users = get_all_users()
    for user_id in users:
        try:
            logging.info(f"Отправка сообщения пользователю с ID: {user_id}")
            await bot.send_message(chat_id=user_id, text=text)
            await asyncio.sleep(0.3)
        except Exception as e:
            logging.error(f"Ошибка при отправке сообщения пользователю {user_id}: {e}")

# *** Запуск бота ***
async def main():
    await dp.start_polling(bot)

if __name__ == '__main__':
    asyncio.run(main())


А в таком состояние, когда добавляем F.state == States.waiting_for_text "# Ожидаем сообщение с текстом рассылки" Рассылка не работает, нажимаешь "Начать рассылку" появляется текст "введите текст для рассылки" я ввожу и ничего не происходит.

# Ожидаем сообщение с текстом рассылки
@dp.message(F.state == States.waiting_for_text)
async def get_broadcast_text(message: types.Message):
    global broadcast_text
    logging.info(f"Получен текст рассылки от пользователя с ID: {message.from_user.id}: {message.text}")
    broadcast_text = message.text
    keyboard = InlineKeyboardMarkup(inline_keyboard=[
        [InlineKeyboardButton(text='Да', callback_data='confirm_broadcast'),
         InlineKeyboardButton(text='Нет', callback_data='cancel_broadcast')]
    ])
    await message.answer("Подтвердите рассылку:", reply_markup=keyboard)


Такая же проблема была и при вызове панели /admin, ничего не происходило, заменил на lambda все заработало

Логи при рабочем состояние:

INFO:aiogram.dispatcher:Start polling
INFO:aiogram.dispatcher:Run polling for bot @fwefwegfweg_bot id=7490700236 - 'test'
INFO:root:Обработчик /start вызван пользователем с ID: 1966823500
INFO:root:Пользователь с ID: 1966823500 уже существует
INFO:aiogram.event:Update id=44150201 is handled. Duration 172 ms by bot id=7490700236
INFO:root:Обработчик /admin вызван пользователем с ID: 1966823500
INFO:aiogram.event:Update id=44150202 is handled. Duration 139 ms by bot id=7490700236
INFO:root:Обработчик 'start_broadcast' вызван пользователем с ID: 1966823500
INFO:aiogram.event:Update id=44150203 is handled. Duration 125 ms by bot id=7490700236
INFO:root:Получен текст рассылки от пользователя с ID: 1966823500: 123
INFO:aiogram.event:Update id=44150204 is handled. Duration 63 ms by bot id=7490700236
INFO:root:Обработчик 'confirm_broadcast' вызван пользователем с ID: 1966823500
INFO:root:Отправка сообщения пользователю с ID: 1966823500
INFO:root:Отправка сообщения пользователю с ID: 1887578321
INFO:root:Отправка сообщения пользователю с ID: 6818632433
INFO:root:Отправка сообщения пользователю с ID: 6768633712
INFO:aiogram.event:Update id=44150205 is handled. Duration 2202 ms by bot id=7490700236

И не в рабочем когда добавляем F.state == States.waiting_for_text:

INFO:aiogram.dispatcher:Start polling
INFO:aiogram.dispatcher:Run polling for bot @fwefwegfweg_bot id=7490700236 - 'test'
INFO:root:Обработчик /start вызван пользователем с ID: 1966823500
INFO:root:Пользователь с ID: 1966823500 уже существует
INFO:aiogram.event:Update id=44150207 is handled. Duration 202 ms by bot id=7490700236
INFO:root:Обработчик /admin вызван пользователем с ID: 1966823500
INFO:aiogram.event:Update id=44150208 is handled. Duration 156 ms by bot id=7490700236
INFO:root:Обработчик 'start_broadcast' вызван пользователем с ID: 1966823500
INFO:aiogram.event:Update id=44150209 is handled. Duration 140 ms by bot id=7490700236
INFO:aiogram.event:Update id=44150210 is not handled. Duration 0 ms by bot id=7490700236
  • Вопрос задан
  • 139 просмотров
Пригласить эксперта
Ваш ответ на вопрос

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

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