How to set role by the select discord.py?
Question:
I have this code, and it works:
@bot.command(name="add-role-pick")
async def add_role_pick(ctx: commands.Context, max_value_select: int):
embed_title = 'Тестовый заголовок'
### >>> view
view = discord.ui.View(timeout=None)
add_role_button = discord.ui.Button(label="Добавить роль", style=discord.ButtonStyle.primary)
edit_title_button = discord.ui.Button(label="Изменить название", style=discord.ButtonStyle.secondary)
edit_description_button = discord.ui.Button(label="Изменить описание", style=discord.ButtonStyle.secondary)
send_button = discord.ui.Button(label="Отправить", style=discord.ButtonStyle.green)
edit_image_button = discord.ui.Button(label="Добавить картинку", style=discord.ButtonStyle.secondary)
async def select_callback(interaction: discord.Interaction):
user = interaction.user
print(select.options)
for role_id in select.values:
role = interaction.message.guild.get_role(int(role_id))
await user.add_roles(role)
await interaction.response.send_message("Роли выданы", ephemeral=True)
select = discord.ui.Select(placeholder="Выберите роль", min_values=1, max_values=max_value_select)
select.callback = select_callback
async def add_role_button_callback(interaction):
await interaction.response.send_message("Введите название роли в селекте, затем упомяните роль", ephemeral=True)
role_answer = await bot.wait_for("message", check=check)
role_name = role_answer.content[:len(role_answer.content) - 23]
role_id = role_answer.raw_role_mentions[0]
await role_answer.delete()
view.remove_item(select)
select.add_option(value=role_id, label=role_name)
if len(select.options) >= 2:
view.add_item(select)
await ctx.send('Роль добавлена', ephemeral=True)
await resend_message()
add_role_button.callback = add_role_button_callback
async def send_button_callback(interaction):
result_view = discord.ui.View(timeout=None)
result_view.add_item(select)
await bot.get_channel(981167385140682779).send(embed=result_embed, view=result_view)
await interaction.response.send_message("Сообщение отправлено!", ephemeral=True)
await embed_message.delete()
send_button.callback = send_button_callback
async def edit_title_button_callback(interaction: discord.Interaction):
await interaction.response.send_message("Отправьте название Embed в чат", ephemeral=True)
title_answer = await bot.wait_for("message", check=check)
result_embed.title = title_answer.content
await interaction.message.delete()
await resend_message()
edit_title_button.callback = edit_title_button_callback
async def edit_description_button_callback(interaction: discord.Interaction):
await interaction.response.send_message("Отправьте описание Embed в чат", ephemeral=True)
description_answer = await bot.wait_for("message", check=check)
result_embed.description = description_answer.content
await interaction.message.delete()
await resend_message()
edit_description_button.callback = edit_description_button_callback
async def edit_image_button_callback(interaction: discord.Interaction):
await interaction.response.send_message("Отправьте ссылку на картинку в чат", ephemeral=True)
image_answer = await bot.wait_for("message", check=check)
result_embed.set_image(url=image_answer.content)
await interaction.message.delete()
await resend_message()
edit_image_button.callback = edit_image_button_callback
view.add_item(add_role_button)
view.add_item(edit_title_button)
view.add_item(edit_description_button)
view.add_item(edit_image_button)
view.add_item(send_button)
### <<< view
author_id = ctx.message.author.id
result_embed = discord.Embed(title=embed_title, color=discord.Color.from_rgb(32, 34, 37))
embed_message = await ctx.send(embed=result_embed, view=view, ephemeral=True)
async def resend_message():
await embed_message.edit(embed=result_embed, view=view)
def check(m):
return author_id == m.author.id
The user generates the embed for a channel, and then he could publish this Embed with the View into the channel. A user could select the role, which will be given to him. And it works perfectly. But after redeploying the bot, all my buttons and selects don’t work, and I don’t know why. Tell me please, how can I solve this problem? (With select)
Answers:
Normally, when the bot goes offline, all of its views stop working, even if they don’t have a timeout. You will be able to see the views, but nothing will happen when you try to interact with them. This is a problem if you are trying to create a self-role system, for example. This is where persistent views come in.
Persistent views work forever. When the bot goes offline, the buttons will stop working. However, when the bot comes back online, the buttons will start working again.
In a Persistent View, the timeout must be set to None and all the children in the view much have a custom_id attribute set.
timeout must be set to None and it need a custom_id
@bot.event
async def on_ready():
bot.add_view(MyView()) # Registers a View for persistent listening
I have this code, and it works:
@bot.command(name="add-role-pick")
async def add_role_pick(ctx: commands.Context, max_value_select: int):
embed_title = 'Тестовый заголовок'
### >>> view
view = discord.ui.View(timeout=None)
add_role_button = discord.ui.Button(label="Добавить роль", style=discord.ButtonStyle.primary)
edit_title_button = discord.ui.Button(label="Изменить название", style=discord.ButtonStyle.secondary)
edit_description_button = discord.ui.Button(label="Изменить описание", style=discord.ButtonStyle.secondary)
send_button = discord.ui.Button(label="Отправить", style=discord.ButtonStyle.green)
edit_image_button = discord.ui.Button(label="Добавить картинку", style=discord.ButtonStyle.secondary)
async def select_callback(interaction: discord.Interaction):
user = interaction.user
print(select.options)
for role_id in select.values:
role = interaction.message.guild.get_role(int(role_id))
await user.add_roles(role)
await interaction.response.send_message("Роли выданы", ephemeral=True)
select = discord.ui.Select(placeholder="Выберите роль", min_values=1, max_values=max_value_select)
select.callback = select_callback
async def add_role_button_callback(interaction):
await interaction.response.send_message("Введите название роли в селекте, затем упомяните роль", ephemeral=True)
role_answer = await bot.wait_for("message", check=check)
role_name = role_answer.content[:len(role_answer.content) - 23]
role_id = role_answer.raw_role_mentions[0]
await role_answer.delete()
view.remove_item(select)
select.add_option(value=role_id, label=role_name)
if len(select.options) >= 2:
view.add_item(select)
await ctx.send('Роль добавлена', ephemeral=True)
await resend_message()
add_role_button.callback = add_role_button_callback
async def send_button_callback(interaction):
result_view = discord.ui.View(timeout=None)
result_view.add_item(select)
await bot.get_channel(981167385140682779).send(embed=result_embed, view=result_view)
await interaction.response.send_message("Сообщение отправлено!", ephemeral=True)
await embed_message.delete()
send_button.callback = send_button_callback
async def edit_title_button_callback(interaction: discord.Interaction):
await interaction.response.send_message("Отправьте название Embed в чат", ephemeral=True)
title_answer = await bot.wait_for("message", check=check)
result_embed.title = title_answer.content
await interaction.message.delete()
await resend_message()
edit_title_button.callback = edit_title_button_callback
async def edit_description_button_callback(interaction: discord.Interaction):
await interaction.response.send_message("Отправьте описание Embed в чат", ephemeral=True)
description_answer = await bot.wait_for("message", check=check)
result_embed.description = description_answer.content
await interaction.message.delete()
await resend_message()
edit_description_button.callback = edit_description_button_callback
async def edit_image_button_callback(interaction: discord.Interaction):
await interaction.response.send_message("Отправьте ссылку на картинку в чат", ephemeral=True)
image_answer = await bot.wait_for("message", check=check)
result_embed.set_image(url=image_answer.content)
await interaction.message.delete()
await resend_message()
edit_image_button.callback = edit_image_button_callback
view.add_item(add_role_button)
view.add_item(edit_title_button)
view.add_item(edit_description_button)
view.add_item(edit_image_button)
view.add_item(send_button)
### <<< view
author_id = ctx.message.author.id
result_embed = discord.Embed(title=embed_title, color=discord.Color.from_rgb(32, 34, 37))
embed_message = await ctx.send(embed=result_embed, view=view, ephemeral=True)
async def resend_message():
await embed_message.edit(embed=result_embed, view=view)
def check(m):
return author_id == m.author.id
The user generates the embed for a channel, and then he could publish this Embed with the View into the channel. A user could select the role, which will be given to him. And it works perfectly. But after redeploying the bot, all my buttons and selects don’t work, and I don’t know why. Tell me please, how can I solve this problem? (With select)
Normally, when the bot goes offline, all of its views stop working, even if they don’t have a timeout. You will be able to see the views, but nothing will happen when you try to interact with them. This is a problem if you are trying to create a self-role system, for example. This is where persistent views come in.
Persistent views work forever. When the bot goes offline, the buttons will stop working. However, when the bot comes back online, the buttons will start working again.
In a Persistent View, the timeout must be set to None and all the children in the view much have a custom_id attribute set.
timeout must be set to None and it need a custom_id
@bot.event
async def on_ready():
bot.add_view(MyView()) # Registers a View for persistent listening