I'm looking to make my buttons on an information post persistent so that they remain interactable even after my bot is restarted but I'm not entirely sure how it would work and how it would apply to my code. I am currently using cogs for my discord bot. I have researched about persistency and even checked the example but was struggling to implement it into my code
main.py
import discord
from discord.ext import commands
from discord import app_commands
import asyncio
from variables import cogs, success, failed, check_is_it_us, MY_GUILD, TOKEN, status
bot = commands.Bot(command_prefix=">", intents=discord.Intents.all())
@bot.event
async def on_ready():
synced = await bot.tree.sync()
print(f"Logged in as {bot.user} (ID: {bot.user.id})")
print(f"Loaded {success}") if failed == [] else print(f"Loaded {success}\nFailed to load {failed}")
print(f"Synced {len(synced)} commands.")
await bot.change_presence(activity = discord.Game(name=status))
@bot.tree.command(name="sync")
@app_commands.check(check_is_it_us)
async def sync(interaction: discord.Interaction):
bot.tree.copy_global_to(guild=MY_GUILD)
synced = await bot.tree.sync()
print(f"Synced {len(synced)} commands.")
await interaction.response.send_message(f"Synced {len(synced)} commands.", ephemeral=True)
async def loadCogs():
for cog in cogs:
try:
await bot.load_extension(f"Cogs.{cog}")
success.append(cog)
except Exception as e:
print(e)
failed.append(cog)
async def main():
await loadCogs()
asyncio.run(main())
bot.run(TOKEN)
The cog that I would like to have persistent buttons in is called info.py
and the command is called /sendinfo
and basically I just want the bot to send a message where the user can click on the buttons to see an ephemeral message of the rules and be able to get the Member role.
info.py
import discord
from discord.ext import commands
from discord import app_commands
from typing import Literal
import platform
from variables import suggestionChannel, pollChannel, pollRole, timeformat, stats, convertTime, check_is_it_us, rules
import asyncio
import random
from discord.utils import get
class info(commands.Cog):
def __init__(self, bot):
self.bot = bot
createGroup = app_commands.Group(name="create", description="Allows you to create suggestions and polls")
infoGroup = app_commands.Group(name="info", description="Shows you info")
@app_commands.command(name="sendinfo", description="Sends the information message")
@app_commands.check(check_is_it_us)
async def sendinfo(self, interaction:discord.Interaction):
view=discord.ui.View(timeout=None)
async def rulesButtoncallback(interaction:discord.Interaction):
rulesEmbed = discord.Embed(title="Official Rules for DRags Club", description="Please agree to our guidelines.")
for item in rules:
rule = item.split("|")
rulesEmbed.add_field(name=rule[0], value=rule[1], inline=False)
await interaction.response.send_message(embed=rulesEmbed, ephemeral=True)
rulesButton = discord.ui.Button(style = discord.ButtonStyle.blurple, label = "Rules")
rulesButton.callback = rulesButtoncallback
view.add_item(rulesButton)
async def verifyButtoncallback(interaction:discord.Interaction):
role = get(interaction.guild.roles, name = "Member")
await interaction.user.add_roles(role)
await interaction.response.send_message("You have been verified!", ephemeral=True)
verifyButton = discord.ui.Button(style = discord.ButtonStyle.blurple, label = "Verify")
verifyButton.callback = verifyButtoncallback
view.add_item(verifyButton)
embed=discord.Embed(colour= 000, title = "DRags' Club", description = "Welcome to the home of [DRags](https://www.youtube.com/@_DRags). Explore the **2 year old** server and see what we have to offer!")
await interaction.channel.send(embed=embed, view=view)
await interaction.response.send_message(f"The information message has been sent in {interaction.channel}!", ephemeral=True)
async def setup(bot):
await bot.add_cog(info(bot))
Please note that there a more commands in this cog that I removed for simplicity.
The structure of rules
in variables.py
rules = ["rule name|rule description","rule name|rule description"]
So basically I want to find out how I could make the buttons on this command persistent and I have linked the screenshot of the command here too.
Change your view to be class-based, it's gonna be easier to manage.
class MyPersistentView(discord.ui.View):
def __init__(self):
super().__init__(timeout=None)
@discord.ui.button(label="Rules", custom_id="rules-button", style=discord.ButtonStyle.blurple)
async def rules_callback(self, interaction, button):
rulesEmbed = discord.Embed(title="Official Rules for DRags Club", description="Please agree to our guidelines.")
for item in rules:
rule = item.split("|")
rulesEmbed.add_field(name=rule[0], value=rule[1], inline=False)
await interaction.response.send_message(embed=rulesEmbed, ephemeral=True)
@discord.ui.button(label="Verify", custom_id="verify_button", style=discord.ButtonStyle.blurple)
async def verify_callback(self, interaction, button)
role = get(interaction.guild.roles, name = "Member")
await interaction.user.add_roles(role)
await interaction.response.send_message("You have been verified!", ephemeral=True)
class info(commands.Cog):
def __init__(self, bot):
self.bot = bot
createGroup = app_commands.Group(name="create", description="Allows you to create suggestions and polls")
infoGroup = app_commands.Group(name="info", description="Shows you info")
@app_commands.command(name="sendinfo", description="Sends the information message")
@app_commands.check(check_is_it_us)
async def sendinfo(self, interaction:discord.Interaction):
view = MyPersistentView(timeout=None)
await interaction.response.send_message(view=view)
Now to create a persistent view it's really simple. Inside the setup_hook
method call bot.add_view
and pass the MESSAGE_ID
(you can do this by copying the message ID in discord after sending the initial message)
from cogs.info import MyPersistentView # or wherever you defined your view class
bot = commands.Bot(command_prefix=">", intents=discord.Intents.all())
MESSAGE_ID = 0
async def setup_hook():
bot.add_view(MyPersistentView(), message_id=MESSAGE_ID)
bot.setup_hook = setup_hook