Ответы пользователя по тегу discord.py
  • Как локализовать label в декораторе button ui?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    Localized работает только для команд и их параметров.

    Для всего остального используйте другое решение и библиотеки, например i18n
    Ответ написан
    Комментировать
  • Не выдаёт роль что делать?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    Перевести ошибку. Ни к питону, ни к библиотеке она отношения не имеет.
    Либо у вас не выданы необходимые полномочия боту, либо его роль находится в списке ролей ниже чем роль, которую он должен выдать.

    Чтобы определить какой из двух вариантов случился в вашем случае нужно перестать обрабатывать ошибки принтами и читать Traceback, там все будет написано.
    Ответ написан
    1 комментарий
  • Pycord, как передать сообщение отправленное боту по команде в отдельный канал?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    Достаете канал по id через get_channel, отправляете через сhannel.send

    channel_id = ... # достаете из БД или оттуда где у вас хранится id нужного канала
    channel = bot.get_channel(channel_id)
    channel.send(feedback_message.content)
    Ответ написан
    Комментировать
  • Как взять данные с базы данных, в app_commands.Choice?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    Для этого используется декоратор autocomplete
    async def fruit_autocomplete(
        interaction: discord.Interaction,
        current: str,
    ) -> List[app_commands.Choice[str]]:
        fruits = ...  # Список данных полученный из БД
        ... # Фильтрация списка 
        return [
            app_commands.Choice(name=fruit, value=fruit)
            for fruit in fruits if current.lower() in fruit.lower()
        ]
    
    @app_commands.command()
    @app_commands.autocomplete(fruit=fruit_autocomplete)
    async def fruits(interaction: discord.Interaction, fruit: str):
        await interaction.response.send_message(f'Your favourite fruit seems to be {fruit}')


    В данном примере функция fruit_autocomplete будет вызываться при наборе каждой буквы. Делаете вместо статичного списка чтение из БД (только убедитесь, что делаете один раз, а не при наборе каждой буквы!) и фильтруете результат на основе текущего ввода, который лежит в current.

    В простейшем виде сравниваете начальные буквы, но можно делать и более интересные вещи, вроде нечеткого поиска, например через расстояние Дамерау-Левенштейна.
    Ответ написан
    Комментировать
  • Timeout работает не так как надо, disnake py, что я делаю не так?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    Таймаут под капотом максимально простая функция, работать не так он не может:
    if not (duration is MISSING) ^ (until is MISSING):
        raise ValueError("Exactly one of `duration` and `until` must be provided")
    
    payload: Dict[str, Any] = {}
    
    if duration is not MISSING:
        if duration is None:
            until = None
        elif isinstance(duration, datetime.timedelta):
            until = utils.utcnow() + duration
        else:
            until = utils.utcnow() + datetime.timedelta(seconds=duration)
    
    # at this point `until` cannot be `MISSING`
    payload["communication_disabled_until"] = utils.isoformat_utc(until)
    
    data = await self._state.http.edit_member(self.id, user.id, reason=reason, **payload)
    return Member(data=data, guild=self, state=self._state)


    Поскольку ни в ней, ни в вашем коде нет упоминаний 4 часов, следовательно у вас вызывается какой-то другой код. Добавляйте принты и/или логирование и смотрите ваши данные.

    P.S. Отформатируйте код вопроса через соответствующий тег.
    Ответ написан
    Комментировать
  • Как сделать, чтобы действия были при определённой роли?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    Вообще зашивать роли в бота это плохая идея, поэтому следующий код прикладываю в дидактических целях и призываю его не использовать.

    Для проверки ролей в checks есть два декоратора checks.has_role и checks.has_any_role

    Применяются следующим образом
    @client.command()
    @app_commands.checks.has_any_role('Library Devs', 'Moderators', 492212595072434186)
    async def cool(interaction: discord.Interaction):
        await interaction.response.send_message('Сообщение увидит только человек с соответствующей ролью')

    Не забудьте обработать ошибки MissingRole и MissingAnyRole чтобы выдавать корректные сообщения об отсутствии прав.

    Почему я считаю что это решение плохое: роли склонны меняться.
    Если это крупный мультисерверный бот, с какими-то кастомными настройками ролей, обычно настройки дополнительно хранятся в БД и роли проверяются по ней в самой команде.

    В общем же виде лучше отталкиваться не от ролей, а от прав, проверка делается через checks.has_permissions, а для более тонкой настройки на сервере зайди в настройки - интеграция и там можно поправить права под каждую команду. В отличии от варианта с ролями это не требует обновлений бота.
    Ответ написан
    Комментировать
  • Как отключить кнопки после нажатия?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    Обычно применяют два подхода. Либо удаляют кнопки, либо делают их не активными.
    for child in view.children:
        if isinstance(child, disnake.ui.Button):
            child.disabled = True
    await message.edit(view=view)
    Ответ написан
  • Не отображается слеш команда в списке команд. Сама команда реализована когом. Что нужно изменить в коде?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    Не надо так делать
    660e372e0c002537203138.jpeg

    Давайте распутывать этот узел:

    Все классы расположенные в disnake.ui предназначены для упрощения создания компонентов. Не надо их с чем-то мешать, кроме миксинов, которые тоже предназначены для создания компонентов, например пагинации.

    Ваше создание команды мало того, что почему-то лежит в колбеке, так еще в декораторе идет запрос объекта bot, а у вас во-первых внутри класса он лежит в self.bot, во-вторых регистрация команд в когах осуществляется через commands.slash_command.

    Вся эта каша запускается только потому, что кусок кода с "командой" в рантайме никогда не вызывается. Ну и разумеется по этой же причине команда не видна.

    Все ссылки выше ведут на официальную документацию, которая содержить понятные примеры использования. Перепишите все как два отдельных класса: первый содержит команды, второй отвечает за создание и взаимодействие с модальным окном.
    Ответ написан
    Комментировать
  • Бот дискорда падает в Rate limited, что делать?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    Давайте по порядку. В документации дискорда очень четко прописаны лимиты для вебсокета и чуть менее четко для HTTP. Цитировать оттуда не буду, думаю там все понятно.

    В общем виде ошибка 429 говорит, что в один из двух лимитов вы не укладываетесь. Чтобы не происходила ошибка можно перед выполнением действий проверять блокировку через AutoShardedClient.is_ws_ratelimited, но это не лечение проблемы, а только обработка.
    Для лечения нужно перехватывать ошибку в глобальном обработчике и по стеку вызовов смотреть на каком действии она происходит. Если приложите стектрейс к запросу, можно будет по нему сказать конкретнее. Только убедитесь чтобы логи не обрезались как у вас выше. Может быть и так было бы понятно, но эндпоинт https://discord.com/api/v10/channels/1215300998588... весь не видно. Учитывайте что она может и в разных когах происходить об этом ниже.

    В целом дискорд не любит, когда боты делают что-либо без явных действий пользователя. Причем чем больше бот, тем строже, поскольку для них это больше нагрузки. К примеру в коде, который вы приложили есть обновление статуса каждые 10 секунд. Будем объективны, пользователям плевать что у бота в статусе, но эти запросы так же идут в общий рейт лимит. Я бы советовал поставить или большое значение (5-10 минут) или вообще избавиться от этой карусели.
    Аналогично пройдите по остальному коду, который не приложен и посмотрите есть ли периодические запросы без явных команд: например обновления каких-нибудь сообщений по таймерам. Если есть увеличивайте таймеры в 2 раза (повторять до исправления) или подумайте как предоставлять функционал без этого.
    Ответ написан
    2 комментария
  • Как исправить ошибку "is not a valid parameter annotation" слэш-команды в когах?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    В слеш командах типы не просто показывают что за объект, но и выполняют конвертацию.
    Документацией в слеш командах разрешены следующие типы
    str
    int
    float
    bool
    disnake.abc.GuildChannel*
    disnake.User or disnake.Member**
    disnake.Role**
    disnake.Attachment
    disnake.abc.Snowflake***

    Судя по тому, что вы пытаетесь принимать commands.Context, которого в слеш командах нет, вы с предыдущих вопросов так и не ознакомились с различиями между обычными командами и слешами.

    Как исправить ошибку
    Либо переписать функцию, потому что во взаимодействии нет методов и атрибутов, которые вы пытаетесь использовать, либо оставить команду обычной.
    Ответ написан
    Комментировать
  • Как вытащить значение их класса, и чтоб давался ответ?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    Вы делаете цикл по текстовым полям и добавляете их как отдельные поля ответа
    for key, value in inter.text_values.items():
                embed.add_field(
                    name=key.capitalize(),
                    value=value[:1024],
                    inline=False,
                )


    Чтобы они были в одну строчку, нужно добавить их в одно поле.
    embed.add_field(
            name='Заголовок',
            value=f'{inter.text_values.get("date",  "")}{inter.text_values.get("time",  "")',
            inline=False,
    )
    Ответ написан
    1 комментарий
  • Dropdown error disnake в чём проблема?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    В чём проблема?
    В том что класс staffapp наследуется от commands.Cog, а не ui.Modal. Эффекта от того что вы сделаете в произвольном классе функцию callback не будет.
    На русском есть очень подробная документация.
    Ответ написан
  • Как получить id (набор цифр) из embed сообщения, используя discord.py?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    Текст эмбедов лежит в embed.description или embed.fields. Чтобы извлекать текст пишите регулярку или ищите заданную подстроку в строке, если формат строго определен.
    Ответ написан
    2 комментария
  • Как записать в переменную упоминание пользователя(в Python)?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    Упоминание пользователя это обычная строка вида <@user_id>. Любая работа с ней аналогична работе со строками.
    В документации описаны все форматы подробных строк.
    Ответ написан
    Комментировать
  • Disnake как сделать страницы в команде help?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    Разделения контента на страницы зовется пагинацией.
    Встроенной в диснейк пагинации нет.
    Писать ее на реакциях это очень плохое решение, пишите на кнопках, для них функционал значительно шире.

    Код как это можно сделать
    class Simple(disnake.ui.View):
        """
        Embed Paginator.
    
        Parameters:
        ----------
        timeout: int
            How long the Paginator should timeout in, after the last interaction. (In seconds) (Overrides default of 60)
        PreviousButton: disnake.ui.Button
            Overrides default previous button.
        NextButton: disnake.ui.Button
            Overrides default next button.
        PageCounterStyle: disnake.ButtonStyle
            Overrides default page counter style.
        InitialPage: int
            Page to start the pagination on.
        """
    
        def __init__(self, *,
                     timeout: int = 60,
                     PreviousButton: disnake.ui.Button = disnake.ui.Button(emoji=disnake.PartialEmoji(name="\U000025c0")),
                     NextButton: disnake.ui.Button = disnake.ui.Button(emoji=disnake.PartialEmoji(name="\U000025b6")),
                     PageCounterStyle: disnake.ButtonStyle = disnake.ButtonStyle.grey,
                     InitialPage: int = 0) -> None:
            self.PreviousButton = PreviousButton
            self.NextButton = NextButton
            self.PageCounterStyle = PageCounterStyle
            self.InitialPage = InitialPage
    
            self.pages = None
            self.ctx = None
            self.message = None
            self.current_page = None
            self.page_counter = None
            self.total_page_count = None
    
            super().__init__(timeout=timeout)
    
        async def start(self, ctx: commands.Context, pages: list[disnake.Embed]):
            self.pages = pages
            self.total_page_count = len(pages)
            self.ctx = ctx
            self.current_page = self.InitialPage
    
            self.PreviousButton.callback = self.previous_button_callback
            self.NextButton.callback = self.next_button_callback
    
            self.page_counter = SimplePaginatorPageCounter(style=self.PageCounterStyle,
                                                           TotalPages=self.total_page_count,
                                                           InitialPage=self.InitialPage)
    
            self.add_item(self.PreviousButton)
            self.add_item(self.page_counter)
            self.add_item(self.NextButton)
    
            self.message = await ctx.send(embed=self.pages[self.InitialPage], view=self)
    
        async def previous(self):
            if self.current_page == 0:
                self.current_page = self.total_page_count - 1
            else:
                self.current_page -= 1
    
            self.page_counter.label = f"{self.current_page + 1}/{self.total_page_count}"
            await self.message.edit(embed=self.pages[self.current_page], view=self)
    
        async def next(self):
            if self.current_page == self.total_page_count - 1:
                self.current_page = 0
            else:
                self.current_page += 1
    
            self.page_counter.label = f"{self.current_page + 1}/{self.total_page_count}"
            await self.message.edit(embed=self.pages[self.current_page], view=self)
    
        async def next_button_callback(self, interaction: disnake.Interaction):
            if interaction.user != self.ctx.author:
                embed = disnake.Embed(description="You cannot control this pagination because you did not execute it.",
                                      color=disnake.Colour.red())
                return await interaction.response.send_message(embed=embed, ephemeral=True)
            await interaction.response.defer()
            await self.next()
    
        async def previous_button_callback(self, interaction: disnake.Interaction):
            if interaction.user != self.ctx.author:
                embed = disnake.Embed(description="You cannot control this pagination because you did not execute it.",
                                      color=disnake.Colour.red())
                return await interaction.response.send_message(embed=embed, ephemeral=True)
            await interaction.response.defer()
            await self.previous()
    
    class SimplePaginatorPageCounter(disnake.ui.Button):
        def __init__(self, style: disnake.ButtonStyle, TotalPages, InitialPage):
            super().__init__(label=f"{InitialPage + 1}/{TotalPages}", style=style, disabled=True)
    Код как использовать
    embeds = [disnake.Embed(title="First embed"),
              disnake.Embed(title="Second embed"),
              disnake.Embed(title="Third embed")]
    
    await Simple().start(ctx, pages=embeds)
    Ответ написан
  • Disnake | Python | Реализация "Формы" как это сделать?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    Реализация «Формы» как это сделать?
    Открыть документацию и посмотреть

    Реализация в плане кода. Подойдёт простой пример создания "Формы"
    Ну ладно, откроем её
    вместо тебя
    import asyncio
    import os
    
    import disnake
    from disnake.ext import commands
    
    bot = commands.Bot(command_prefix=commands.when_mentioned)
    
    class MyModal(disnake.ui.Modal):
        def __init__(self) -> None:
            components = [
                disnake.ui.TextInput(
                    label="Name",
                    placeholder="The name of the tag",
                    custom_id="name",
                    style=disnake.TextInputStyle.short,
                    min_length=5,
                    max_length=50,
                ),
                disnake.ui.TextInput(
                    label="Content",
                    placeholder="The content of the tag",
                    custom_id="content",
                    style=disnake.TextInputStyle.paragraph,
                    min_length=5,
                    max_length=1024,
                ),
            ]
            super().__init__(title="Create Tag", custom_id="create_tag", components=components)
    
        async def callback(self, inter: disnake.ModalInteraction) -> None:
            tag_name = inter.text_values["name"]
            tag_content = inter.text_values["content"]
    
            embed = disnake.Embed(title=f"Tag created: `{tag_name}`")
            embed.add_field(name="Content", value=tag_content)
            await inter.response.send_message(embed=embed)
    
        async def on_error(self, error: Exception, inter: disnake.ModalInteraction) -> None:
            await inter.response.send_message("Oops, something went wrong.", ephemeral=True)
    
    @bot.slash_command()
    async def create_tag(inter: disnake.CommandInteraction):
        await inter.response.send_modal(modal=MyModal())
    
    @bot.event
    async def on_ready():
        print(f"Logged in as {bot.user} (ID: {bot.user.id})\n------")
    
    
    if __name__ == "__main__":
        bot.run(os.getenv("BOT_TOKEN"))
    Ответ написан
    1 комментарий
  • Disnake непонятная ошибка. Кто может помочь?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    Как верно сказано в комментариях правильным действием будет удалить этот код и переписать на кнопках.

    Событие on_raw_reaction_add и метод await bot.wait_for() относятся к низкоуровневым компонентам библиотеки и их использование оправдано только если нет других способов решения проблемы.

    Примером проблем, которые вы получаете может служить то, что вы текущим кодом во-первых будете бесконечно накапливать корутины из-за никогда не завершаемых while True, а во вторых все нажатия на реакции начнут приводить к выполнению логики
    Ответ написан
    Комментировать
  • Как отладить ошибки в коде?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    FlegYy, собственный вопрос перечитайте, вы ctrl-v нажали дважды и не затерли токен.
    В официальной документации дана инструкция по созданию токена и выдаче интентов, читать инструкции надо там. Судя по отсутствию реакции у вас не выдан MESSAGE CONTENT INTENT, а вы сделали префиксную команду вместо слеша. Остальные инструкции тоже прочтите, в том числе как логировать.

    Вы правильно описали, что код как бы рабочий. В реальности в нем в половине мест бот сломается при определенных обстоятельствах. Сколько там других людей писали такой же код, не делает его более качественным. Рассмотрите вариант фриланса, маловероятно что можете корректно реализовать задуманное.
    Ответ написан
  • Почему команды бота(disnake) не обновляются?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    Почему команды бота(disnake) не обновляются?
    Потому что в коде есть какая-то ошибка, препятствующая обновлению. Например намудрили с декораторами.

    Команда работает верно, но почему-то в боте( слэш командах ) она не показывается, уже прошел день.
    Слеш-команда не может верно работать, если она не показывается. Вероятно вы сделали префикс "/", что делать нельзя, поскольку с ним слеш-команды работать не будут.

    Почему команды бота(discord.py) не обновляются?
    Во-первых для разработки объявляется тестовый сервер и обновление на нем происходит мгновенно
    bot = commands.Bot("!", test_guilds=[123456789, 987654321])

    Во-вторых есть флаг дебага sync_commands_debug, который выдаст в логи дополнительную информацию
    Ответ написан
    Комментировать
  • Проблемы с кодом disnake?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    TypeError: Client.__init__() got an unexpected keyword argument 'help_commands'

    Жмешь на commands.Bot, проваливаешься в описание и находишь что аргумент должен зваться help_command без s
    Ответ написан
    Комментировать