class buttonHandler(discord.ui.View): def init(self): super().init(timeout=None)
@discord.ui.button(label="Verify", style=discord.ButtonStyle.primary, custom_id='persistent_view:primary')
async def buttons_verify(self, interaction: discord.Interaction, button: discord.ui.Button):
#interaction.response.send_message("you clicked me")
db = self.client.mongoConnect["zbot"]
collection = db["Verify"]
verify_data = collection.find_one({"_id" : interaction.guild_id})
role = discord.utils.get(interaction.guild.roles, id=verify_data['roles'])
if role not in interaction.user.roles:
await interaction.user.add_roles(role)
await interaction.response.send_message("Welcome to the server", ephemeral=True)
else:
await interaction.response.send_message("Already Verified", ephemeral=True)
class rules(commands.Cog):
def __init__(self, client: commands.Bot):
self.client = client
#test the button function this code is confirmed to work in python 2.0
#@app_commands.commands.command(name="button", description="just a button")
#async def button1(self, interaction: Interaction):
# view = buttonHandler()
# await interaction.response.send_message("test", view=view)
@app_commands.command(name="rules", description="(Admin only)add rules and make a reaction please please add a role named Member for this to work")
async def self_role(self, interaction: discord.Interaction, channel: str, role: str):
##Gets the mongodb database
db = self.client.mongoConnect["zbot"]
collection = db["Verify"]
## turns the channel into a channel id
role_new = re.sub(r'[^0-9]', '', role)
role_id_int = int(role_new)
channel_new = re.sub(r'[^0-9]', '', channel)
channel_id_int = int(channel_new)
channel_int_new = self.client.get_channel(channel_id_int)
##
await interaction.response.send_message("enter your message")
#message = ''
def check(m):
return m.author == interaction.user and m.channel == interaction.channel
view = buttonHandler(role=role_id_int)
msg = await self.client.wait_for('message',timeout=120.0, check=check)
await channel_int_new.send(msg.content, view=view)
if await collection.find_one({"_id" : interaction.guild_id}) == None:
newData = {"_id" : interaction.guild_id, "roles": role_id_int}
await collection.insert_one(newData)
else:
await collection.replace_one({"_id" : interaction.guild_id, "roles": role_id_int})
whenever I reset my bot the button stops working I tried to make it persistent with Rapptz/discord.py persistent.py but its not working
Since views are not automatically reinitialized when the bot restarts, you need to this yourself. This can be accomplished by calling Bot.add_view
in your bot's setup_hook
.
Some important considerations:
In order a view to persist between restarts it needs to meet the following conditions:
- The timeout of the View has to be set to None
- Every item in the View has to have a custom_id set
import discord
from discord.ext import commmands
class PersistentView(discord.ui.View):
def __init__(self):
super().__init__(timeout=None)
@discord.ui.button(label='Green', style=discord.ButtonStyle.green, custom_id='persistent_view:green')
async def green(self, interaction: discord.Interaction, button: discord.ui.Button):
await interaction.response.send_message('This is green.', ephemeral=True)
class PersistentViewBot(commands.Bot):
def __init__(self):
intents = discord.Intents.default()
intents.message_content = True
super().__init__(command_prefix=commands.when_mentioned_or('$'), intents=intents)
async def setup_hook(self) -> None:
# Register the persistent view for listening here.
# Note that this does not send the view to any message.
# In order to do this you need to first send a message with the View, which is shown below.
# If you have the message_id you can also pass it as a keyword argument, but for this example
# we don't have one.
self.add_view(PersistentView())
bot = PersistentViewBot()
bot.run("token")
Code excerpt from discord.py github repo examples