Как сохранить функциональность кнопок после перезагрузки бота?

Как сделать кнопки активными после перезапуска бота с помощью функционала сохранения представлений в discord.py?
  • 4 мая 2024 г. 16:00
Ответы на вопрос 3
Для сохранения функциональности кнопок после перезапуска бота в discord.py, вы можете использовать сохранение данных в файле или базе данных. 

Вам нужно сохранить состояние кнопок (их идентификаторы, названия и прочую информацию), которые вы хотите сохранить после перезапуска бота. После перезапуска бота, вам нужно будет загрузить эти данные и пересоздать кнопки с помощью сохраненной информации.

Примерно так это может выглядеть в вашем коде:

```python
from discord.ext import commands
import json

# Функция для сохранения данных в файл
def save_buttons_data(data):
    with open('buttons_data.json', 'w') as file:
        json.dump(data, file)

# Загрузка данных из файла
def load_buttons_data():
    with open('buttons_data.json', 'r') as file:
        data = json.load(file)
    return data

# Создание бота
bot = commands.Bot(command_prefix='$')

@bot.event
async def on_ready():
    # Загрузка данных о кнопках
    buttons_data = load_buttons_data()
    for button_info in buttons_data:
        # Создание кнопки с помощью сохраненной информации
        # Тут должна быть ваша логика создания кнопки на сервере Discord

# Сохранение данных о кнопках при выключении бота
@bot.event
async def on_disconnect():
    buttons_data = []
    # Сюда добавьте логику для сохранения данных о кнопках
    save_buttons_data(buttons_data)

# Запуск бота
bot.run('YOUR_BOT_TOKEN')
```

Это лишь пример, который демонстрирует общую идею сохранения и загрузки данных кнопок для их последующей пересоздания после перезапуска бота. Вам нужно будет адаптировать этот код под свои нужды и работу с кнопками в discord.py.
prostovladikxd ознакомьтесь с правилами ресурса. Поправьте код в вопросе, чтобы он стал читаемым для этого используйте кнопку </> в панели. В будущем старайтесь внимательней подходить к формулировкам и подкрепляйте их кодом: что еще за кнопки перед модальным окном, где этот код? Куда нужно передать параметр self.author? Почему у вас в вечной вьюхе нужен автор? Почему вы в момент создания не знаете данных? 

Отвечая на непосредственный вопрос: инструкция как сделать вечные кнопки есть в репозитории диснейка. По съеховшему коду не могу точно сказать, но вроде бы все корректно.

Я бы рекомендовал вообще не иметь параметров. Вечная вьюха на то и вечная, что не должна пересоздаваться чтобы что-то в ней поменять. Или если в ней не нужно ничего менять зачем тогда параметры? Данные стоит хранить независимо в базе данных, а из вьюхи их читать. Да и имена полей намекают что эти данные стоило бы хранить в базе. В общем ощущение, что проблема у вас не с кнопками, но чтобы на это ответить нужно понимать что вы хотите.
class moderamViewBot(commands.Bot):
    def __init__(self):
        super().__init__(command_prefix=commands.when_mentioned)
        self.persistent_views_added = False

    async def on_ready(self):
        print ('bot started')
        if not self.persistent_views_added:
            self.add_view(moderamView())
            self.persistent_views_added = True

bot = moderamViewBot()


conn = sqlite3.connect("users.db")
cursor = conn.cursor()

cursor.execute(
    """
    CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY,
        balance INTEGER
    )
    """
)
conn.commit()


@bot.slash_command(name="givebalance", description="Выдать баланс")
async def givebalance(interaction: disnake.ApplicationCommandInteraction, member: disnake.Member, balanc: int):
    user_id = member.id
    cursor.execute("SELECT * FROM users WHERE id=?", (user_id,))
    cursor.execute(f"UPDATE users SET balance=balance+{balanc} WHERE id=?", (user_id,))
    cursor.execute("SELECT * FROM users WHERE id=?", (user_id,))
    conn.commit()
    embed=disnake.Embed(title=f"Пользователю {member} было выдано {balanc} руб", description="", color=0x00BFFF)
    await interaction.response.send_message(embed=embed, ephemeral=True)
    embed=disnake.Embed(title=f"Вам было выдано {balanc}руб на баланс", description="", color=0x00BFFF)
    await member.send(embed=embed)

@bot.slash_command(name="start", description="Личный Кабинет", dm_permission=True)
async def start(interaction: disnake.ApplicationCommandInteraction):
    user_id = interaction.user.id
    cursor.execute("SELECT * FROM users WHERE id=?", (user_id,))
    user = cursor.fetchone()

    if user is None:
        cursor.execute("INSERT INTO users VALUES (?, 0)", (user_id,))
        conn.commit()

    embed=disnake.Embed(title=f"Ваш ID: {user[0]}\nБаланс: {user[1]}", description="", color=0x00BFFF)
    embed.add_field(name="Полезная Информация", value=" - подать объявление\n - Пополнить баланс\n - Вывод баланса\n - Тех.поддержка", inline=False)
    await interaction.response.send_message(embed=embed, ephemeral=True, view=profileView())



class profileView(disnake.ui.View):
    def __init__(self):
        super().__init__(timeout=None)

    @disnake.ui.button(style=disnake.ButtonStyle.primary, emoji='', custom_id="but:1")
    async def b1_button_callback(self, button, interaction):
        embed=disnake.Embed(title=f"Выберите тип товара", description="", color=0x00BFFF)
        embed.add_field(name="Подсказка:", value="1️⃣ - аккаунты\n2️⃣ - вирты\n3️⃣ - Прочие услуги", inline=False)
        await interaction.response.send_message(embed=embed, ephemeral=True, view=opredView())

    @disnake.ui.button(style=disnake.ButtonStyle.green, emoji="", custom_id="but:2")
    async def b2_button_callback(self, button, interaction):
        await interaction.response.send_message("Кнопка нажата", ephemeral=True)

    @disnake.ui.button(style=disnake.ButtonStyle.secondary, emoji="", custom_id="but:3")
    async def b3_button_callback(self, button, interaction):
        await interaction.response.send_message("Кнопка нажата", ephemeral=True)

class opredView(disnake.ui.View):
    def __init__(self):
        super().__init__(timeout=None)

    @disnake.ui.button(style=disnake.ButtonStyle.primary, emoji='1️⃣', custom_id="but:4")
    async def b4_button_callback(self, button, interaction):
        await interaction.response.send_modal(modal=akkModal())
    @disnake.ui.button(style=disnake.ButtonStyle.primary, emoji='2️⃣', custom_id="but:5")
    async def b5_button_callback(self, button, interaction):
        await interaction.response.send_modal(modal=virtModal())
    @disnake.ui.button(style=disnake.ButtonStyle.primary, emoji='3️⃣', custom_id="but:6")
    async def b6_button_callback(self, button, interaction):
        await interaction.response.send_modal(modal=allModal())



class akkModal(disnake.ui.Modal):
    def __init__(self):
        components = [
            disnake.ui.TextInput(
                label="ИГРА | ПРИЛОЖЕНИЕ | ПРОЕКТ",
                placeholder="Пример: GTA 5 RP Сервер: Milton",
                custom_id="1",
                style=TextInputStyle.short,
            ),
            disnake.ui.TextInput(
                label="ОПИСАНИЕ",
                placeholder="Укажите описание аккаунта",
                custom_id="2",
                style=TextInputStyle.short,
            ),
            disnake.ui.TextInput(
                label="ЦЕНА",
                placeholder="Пример: 1500р",
                custom_id="3",
                style=TextInputStyle.short,
            ),
            disnake.ui.TextInput(
                label="ДАННЫЕ",
                placeholder="Логин: ... | Пароль: ... | Прочие данные: ...",
                custom_id="4",
                style=TextInputStyle.short,
            ),
        ]
        super().__init__(
            title=" | ЗАПОЛНИТЕ ДАННЫЕ",
            custom_id="create_tag",
            components=components,
        )

    async def callback(self, interaction: disnake.ModalInteraction):
        author = interaction.user
        objects = interaction.text_values["1"]
        opisanye = interaction.text_values["2"]
        cena_input = interaction.text_values["3"]
        login = interaction.text_values["4"]
        cena_input = ''.join(filter(str.isdigit, cena_input))
        cena = int(cena_input)
        await interaction.response.send_message("Объявление успешно отправлено!", ephemeral=True)
        embed=disnake.Embed(title=f"АККАУНТЫ", description=f"Продавец {author.mention}", color=0x00BFFF)
        embed.add_field(name=f"Игра | Приложение | Проект: {objects}", value="", inline=False)
        embed.add_field(name=f"Описание Аккаунта: {opisanye}", value="", inline=False)
        embed.add_field(name=f"Цена: {cena}", value="", inline=False)
        channel = bot.get_channel(1230041959305838663) #id канала куда будут приходить объявления на проверку модераторам
        await channel.send(embed=embed, view=moderamView(author, objects, opisanye, cena, login))


class moderamView(disnake.ui.View):
    def __init__(self, author, objects, opisanye, cena, login):
        super().__init__(timeout=None)
        self.author = author
        self.button_pressed = False
        self.objects = objects
        self.opisanye = opisanye
        self.cena = cena
        self.login = login

    @disnake.ui.button(label="Одобрить", style=disnake.ButtonStyle.green, custom_id="but:7")
    async def b7_button_callback(self, button, interaction):
        if self.button_pressed == False:
            await interaction.response.send_message(f'Объявление {self.author.mention} рассмотрено', ephemeral=True)
            embed=disnake.Embed(title="Ваше объявление было успешно рассмотрено! Статус: Одобрено", description="", color=0x00BFFF)
            embed.add_field(name="Информация об объявлении:", value=f"Тип товара: Аккаунты\nИгра | Приложение | Проект: {self.objects}\nОписание аккаунта: {self.opisanye}\nЦена: {self.cena}", inline=False)
            await self.author.send(embed=embed)
            embed=disnake.Embed(title=f"АККАУНТЫ", description=f"", color=0x00BFFF)
            embed.add_field(name=f"Игра | Приложение | Проект: {self.objects}", value="", inline=False)
            embed.add_field(name=f"Описание Аккаунта: {self.opisanye}", value="", inline=False)
            embed.add_field(name=f"Цена: {self.cena}", value="", inline=False)
            login = self.login
            author = self.author
            objects = self.objects
            opisanye = self.opisanye
            cena = self.cena
            channel = bot.get_channel(1230041959305838663)#id канала со всеми одобреными объявлениями
            await channel.send(embed=embed, view=buyView(author, objects, opisanye, cena, login))
            self.button_pressed = True

            self.children[0].label = "❌"
            self.children[0].style = disnake.ButtonStyle.grey
            self.children[1].label = "❌"
            self.children[1].style = disnake.ButtonStyle.grey
            await interaction.message.edit(view=self)

        else:
            return
        
    @disnake.ui.button(label="Отклонить", style=disnake.ButtonStyle.red, custom_id="but:8")
    async def b8_button_callback(self, button, interaction):
        if self.button_pressed == False:
            await interaction.response.send_message(f'Объявление {self.author.mention} рассмотрено', ephemeral=True)
            embed=disnake.Embed(title="Ваше объявление было успешно рассмотрено! Статус: Отклонено", description="", color=0x00BFFF)
            embed.add_field(name="Информация об объявлении:", value=f"Тип товара: Аккаунты\nИгра | Приложение | Проект: {self.objects}\nОписание аккаунта: {self.opisanye}\nЦена: {self.cena}", inline=False)
            await self.author.send(embed=embed)
            self.button_pressed = True

            self.children[0].label = "❌"
            self.children[0].style = disnake.ButtonStyle.grey
            self.children[1].label = "❌"
            self.children[1].style = disnake.ButtonStyle.grey
            await interaction.message.edit(view=self)

        else:
            return

вот исходный код, если посмотреть - то я думаю станет понятно зачем нужны параметры, а передать мне их нужно в 9 строку
self.add_view(moderamView())
Похожие вопросы