discord.py button stops after reset

Question:

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

Asked By: Zeph108

||

Answers:

Explanation

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:

  1. The timeout of the View has to be set to None
  2. Every item in the View has to have a custom_id set

Code

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")

Reference

discord.Client.add_view

Code excerpt from discord.py github repo examples

Answered By: TheFungusAmongUs
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.