Кнопки
Набирать ответы текстом медленно. В discord.py под сообщением можно разместить кнопки — и обрабатывать нажатия прямо в коде.
View и кнопки
class VoteView(discord.ui.View):
def __init__(self):
super().__init__(timeout=180) # через 180 секунд кнопки перестанут работать
self.votes = {}
@discord.ui.button(label="За", style=discord.ButtonStyle.success)
async def yes(self, interaction: discord.Interaction, button: discord.ui.Button):
await interaction.response.send_message("Голос принят", ephemeral=True)
await message.channel.send("Играем ещё раунд?", view=VoteView())
- View — набор элементов под сообщением и их обработчики; у каждого сообщения — свой объект View со своими данными (
self.votes); @discord.ui.button(label=…, style=…)превращает метод в кнопку; стили —primary(синяя),success(зелёная),danger(красная),secondary(серая);- метод получает interaction — нажатие:
interaction.user— кто нажал,interaction.response— как ответить.
Ответ на нажатие
На каждое нажатие нужно ответить ровно один раз:
await interaction.response.send_message("Текст") # новое сообщение
await interaction.response.send_message("Только вам", ephemeral=True) # видит только нажавший
await interaction.response.edit_message(content="Новый текст", view=self) # изменить сообщение с кнопками
Если не ответить за 3 секунды, Discord покажет пользователю «Ошибка взаимодействия».
Менять кнопки
button.label = "Нажато: 5"
button.disabled = True
for item in self.children: # все элементы View
item.disabled = True
await interaction.response.edit_message(view=self)
Изменения появятся у пользователей только после edit_message(view=self). Сначала меняйте кнопки, потом обновляйте сообщение. self.stop() завершает View — больше нажатий он не ждёт.
Кнопки в цикле
Если варианты заранее неизвестны (вопросы викторины), кнопки создают в цикле:
for option in options:
button = discord.ui.Button(label=option)
button.callback = self.make_handler(button)
self.add_item(button)
Функция-фабрика make_handler(button) возвращает обработчик, который «помнит» свою кнопку.
Итог
discord.ui.View,@discord.ui.button(label, style),channel.send(…, view=…);interaction.user,interaction.response.send_message / edit_message,ephemeral=True;button.label,button.disabled,self.children, затемedit_message(view=self);- кнопки в цикле:
discord.ui.Button,callback,add_item.