暂停循环发送消息,等待用户点击InlineKeyboardButton



用户插入一些值。只是为了不给他发很多信息,我想暂停循环发送,等待用户点击内联按钮。那么我如何才能暂停它们并等待用户点击";下一个结果";按钮下面的代码只是简化了,但可以更好地理解场景。

import os
from aiogram.dispatcher import FSMContext
from aiogram import Bot, Dispatcher, executor, types
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.dispatcher.filters.state import StatesGroup, State

bot = Bot(token=os.environ["TOKEN"])
dispatcher = Dispatcher(bot, storage=MemoryStorage())

class Searches(StatesGroup):
by_id = State()

@dispatcher.message_handler(state='*', commands='cancel')
async def cancel_state(message: types.Message, state: FSMContext):
if await state.get_state():
await state.finish()
await message.reply("Search was canceled")

@dispatcher.message_handler(commands="search")
async def answer_search_message(message: types.Message):
find_by_id_button = types.InlineKeyboardButton("по ID", callback_data="by_id")
keyboard = types.InlineKeyboardMarkup().row(find_by_id_button)
await message.answer("Choose search type", parse_mode="HTML", reply_markup=keyboard)

@dispatcher.callback_query_handler(text="by_id")
async def callback_id(callback: types.CallbackQuery):
await callback.message.answer("Insert IDs, split them with ','")
await Searches.by_id.set()

@dispatcher.message_handler(state=Searches.by_id)
async def find_by_id(message: types.Message, state: FSMContext):
ids_from_message = [item for item in range(5)]  # get IDs from user message
for index, item in enumerate(ids_from_message):
photo, caption, url = ("https://www.google.ru/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png", "some text", "https://www.example.org/")  # get some data by id
button_to_site = types.InlineKeyboardButton("More on site", url)
keyboard = types.InlineKeyboardMarkup().row(button_to_site)
if len(ids_from_message) > index + 1:  # if this is not last result - show button "Next result"
keyboard.add(types.InlineKeyboardButton("Next result", callback_data="show_next"))
await message.answer_photo(photo=photo, caption=caption, parse_mode="HTML", reply_markup=keyboard)
# loop should pause here, awaiting for user tap inline button "Next result"
else:
await message.answer_photo(photo=photo, caption=caption, parse_mode="HTML", reply_markup=keyboard)
await state.finish()

executor.start_polling(dispatcher)

好吧,互联网,你总是帮助我,所以这里是我找到的解决这个问题的方法。您只需为用户保存一些数据并将其发送给他,然后它就会触发按钮。下面是完整的代码。

import os
from aiogram.dispatcher import FSMContext
from aiogram import Bot, Dispatcher, executor, types
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.dispatcher.filters.state import StatesGroup, State

def get_record_by_id(doc_id):
# blah-blah some data generating
return "https://www.google.ru/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png", "текст документа", "https://www.example.org/"

bot = Bot(token=os.environ["TOKEN"])
storage = MemoryStorage()
dispatcher = Dispatcher(bot, storage=storage)

class Searches(StatesGroup):
by_id = State()

@dispatcher.message_handler(state='*', commands='cancel')
async def cancel_state(message: types.Message, state: FSMContext):
if await state.get_state():
await state.finish()
await message.reply("Search was canceled")

@dispatcher.message_handler(commands="search")
async def answer_search_message(message: types.Message):
find_by_id_button = types.InlineKeyboardButton("by ID", callback_data="by_id")
keyboard = types.InlineKeyboardMarkup().row(find_by_id_button)
await message.answer("Choose search type", parse_mode="HTML", reply_markup=keyboard)

@dispatcher.callback_query_handler(text="by_id")
async def callback_id(callback: types.CallbackQuery):
await callback.message.answer("Insert IDs, split them with ','")
await Searches.by_id.set()
await callback.answer()

@dispatcher.message_handler(state=Searches.by_id)
async def find_by_id(message: types.Message, state: FSMContext):
user_id = message.from_user.id
ids_from_message = [item for item in range(5)]
photo, caption, url = get_record_by_id(ids_from_message[0])
button_to_site = types.InlineKeyboardButton("More on site", url)
keyboard = types.InlineKeyboardMarkup().row(button_to_site)
if len(ids_from_message) > 1:
del ids_from_message[0]
await storage.set_data(user=user_id, data={"ids_to_send": ids_from_message})
keyboard.add(types.InlineKeyboardButton("Next result", callback_data="show_next"))
await message.answer_photo(photo=photo, caption=caption, parse_mode="HTML", reply_markup=keyboard)
else:
await message.answer_photo(photo=photo, caption=caption, parse_mode="HTML", reply_markup=keyboard)
await state.finish()

@dispatcher.callback_query_handler(state=Searches.by_id, text="show_next")
async def callback_id(callback: types.CallbackQuery, state: FSMContext):
user_id = callback.from_user.id
chat_id = callback.message.chat.id
data = await storage.get_data(user=user_id)
photo, caption, url = get_record_by_id(data["ids_to_send"][0])
button_to_site = types.InlineKeyboardButton("More on site", url)
keyboard = types.InlineKeyboardMarkup().row(button_to_site)
if len(data["ids_to_send"]) > 1:
del data["ids_to_send"][0]
await storage.set_data(user=user_id, data={"ids_to_send": data["ids_to_send"]})
keyboard.add(types.InlineKeyboardButton("Next result", callback_data="show_next"))
await bot.send_photo(chat_id=chat_id, photo=photo, caption=caption, parse_mode="HTML", reply_markup=keyboard)
else:
await bot.send_photo(chat_id=chat_id, photo=photo, caption=caption, parse_mode="HTML", reply_markup=keyboard)
await state.finish()
await callback.answer()

executor.start_polling(dispatcher)

最新更新