Как в disnake при отправке модального окна определить или передать, какой пользователь его отправил?

Помогите, пожалуйста: я не понимаю, как сделать так, чтобы в сообщении, которое отправляет модал, отображался ник пользователя, отправившего этот модал, и чтобы этому пользователю отправлялось сообщение с пометкой «одобрено» или «отклонено» в зависимости от нажатой кнопки.
  • 31 марта 2026 г. 8:02
Ответы на вопрос 2
Коротко — нужно сохранить пользователя (или его id) в самом модальном окне или во View с кнопками, чтобы потом в callback'ах кнопок к нему обратиться. Ниже — минимальный рабочий пример на disnake, показывающий полный поток:

- пользователь открывает модал;
- в callback модала бот отправляет сообщение для модераторов с кнопками «Одобрить / Отклонить» и в View сохраняет submitter;
- при клике модератора бот отправляет личное сообщение (DM) тому, кто отправил модал.

Пример:

```py
import disnake
from disnake.ext import commands

bot = commands.Bot(command_prefix="!", intents=disnake.Intents.all())

class ApproveRejectView(disnake.ui.View):
    def __init__(self, submitter: disnake.User, *, timeout: float = None):
        super().__init__(timeout=timeout)
        self.submitter = submitter

    @disnake.ui.button(label="Одобрить", style=disnake.ButtonStyle.green)
    async def approve(self, button: disnake.ui.Button, inter: disnake.MessageInteraction):
        # избавляемся от кнопок и редактируем сообщение
        await inter.response.edit_message(content=f"✅ Одобрено модератором {inter.author.display_name}", view=None)
        # отправляем DM submitter'у (ловим исключение, если DM отключены)
        try:
            await self.submitter.send("Ваша заявка одобрена ✅")
        except Exception:
            # по желанию логировать или уведомить модератора, что DM не доставлены
            pass

    @disnake.ui.button(label="Отклонить", style=disnake.ButtonStyle.red)
    async def reject(self, button: disnake.ui.Button, inter: disnake.MessageInteraction):
        await inter.response.edit_message(content=f"❌ Отклонено модератором {inter.author.display_name}", view=None)
        try:
            await self.submitter.send("Ваша заявка отклонена ❌")
        except Exception:
            pass

class MyModal(disnake.ui.Modal):
    def __init__(self, invoker: disnake.User):
        # добавляем поля модала (пример одного текстового поля)
        components = [
            disnake.ui.TextInput(
                label="Описание",
                custom_id="desc",
                style=disnake.TextInputStyle.paragraph,
                required=True,
                max_length=1000
            )
        ]
        super().__init__(title="Заявка", components=components)
        # сохраняем пользователя, который открыл модал
        self.invoker = invoker

    async def callback(self, inter: disnake.ModalInteraction):
        # читаем введённый текст
        desc = inter.text_values.get("desc")  # или inter.text_values["desc"]
        # создаём View с кнопками и передаём туда submitter
        view = ApproveRejectView(self.invoker)
        # отправляем сообщение (например, в тот же канал), указываем ник отправившего
        await inter.response.send_message(
            f"Новая заявка от {self.invoker.display_name}:\n{desc}",
            view=view
        )

# команда/слэш-команда, которая открывает модал
@bot.slash_command(description="Открыть форму")
async def send_form(inter: disnake.ApplicationCommandInteraction):
    # сохраняем пользователя, который открыл модал (inter.author или inter.user)
    invoker = getattr(inter, "author", None) or inter.user
    modal = MyModal(invoker)
    await inter.response.send_modal(modal)

bot.run("TOKEN")
```

Несколько важных замечаний:
- Важно сохранять именно объект пользователя (disnake.User/Member) или его id в modal/view, чтобы в кнопках иметь к кому писать.
- Если вы хотите, чтобы данные кнопок пережили рестарт бота (persistent views), то храните id пользователя в custom_id кнопки (например, "approve:1234567890") и парсите его в обработчике. Persistent views нельзя хранить Python-объекты в памяти между рестартами.
- Пользователь может запретить сообщения в ЛС — отправка DM может вызвать ошибку. Обязательно ловите исключения.
- В callback'ах interaction.author — это тот, кто нажал кнопку (модератор); interaction.user — тоже можно использовать. В модале используйте inter.user/inter.author для определения, кто его отправил (мы сохраняем этот user при создании модала).

Если надо, могу показать вариант с передачей user.id через custom_id кнопки (для persist-views) или адаптировать пример под вашу текущую структуру команд.
<code>member</code> нигде не определён, вот и не работает. Сохрани <code>inter.author.id</code> в модале и передай во View через конструктор, а в кнопке доставай через <code>await inter.client.fetch_user(self.user_id)</code> <br/> <br/> а ещё сигнатуры коллбэков — в disnake это <code>(self, button, inter)</code> , без <code>ctx</code> . и <code>respone</code> → <code>response</code>
Похожие вопросы