Ответы пользователя по тегу discord.py
  • Не отображается слеш команда в списке команд. Сама команда реализована когом. Что нужно изменить в коде?

    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
    Ответ написан
    Комментировать
  • Почему не работает функция?

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

    Однако для метода add_roles помимо HTTP ошибок есть только одно исключение, которое возникает, если у бота нет прав на выдачу роли.
    Убедитесь, что у бота есть нужные права и что роль, которую вы пытаетесь выдать находиться в списке ролей ниже, чем наивысшая из ролей бота.
    Ответ написан
    Комментировать
  • Не отправляет ответ что делать?

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

    Использовать модальные окна как показано в официальный примерах, а не как сказал чат гпт или какой-то ютубер.
    Ответ написан
  • Как создать экономического бота?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    Текущая структура кода не предусматривает адекватного способа решения поставленных вами задач, а правила ресурса в целом не предусматривают решение чужих задач. Так что на вопрос есть три возможных ответа:
    1. Добавить любого существующего, их сотни на любой вкус
    2. Сформировать ТЗ и пойти на фриланс
    3. Выучить язык за пределами if...else..., описать модель предметной области, продумать объекты и их взаимодействие, нарисовать схему, написать тесты, разделить задачи на более мелкие подзадачи и реализовать их.
    Ответ написан
    Комментировать
  • Disnake не находит команду. как решить?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    Потому что нельзя делать префиксом слеш
    Ответ написан
  • Как получить содержание сообщения disnake.interaction?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    original_message это корутина. Соответственно рабочий код будет как вы сами и написали будет
    message = await interaction.original_message()
    При этом в приложенном коде нет await

    При любых подобных проблемах делайте print(type(obj)) и смотрите по документации что вам вернулось.
    Ответ написан
  • Как сделать слэш команду с выбором человека и выбором 1 из 3 пунктов? И желательно чтобы бот это всë выводил в ответ + кто отправил команду. Можно?

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

    Да все это сделать можно, открываете документацию и изучаете.
    Даже 3 строчки что вы приложили дают понять, что вы ее не открывали, поскольку слеш-команды принимают не Контекст, а Взаимодействие. Это разные объекты с разными атрибутами и методами.
    @client.tree.command()
    async def send(interaction: discord.Interaction, text_to_send: str):
        await interaction.response.send_message(text_to_send)

    В частности у него есть атрибут response, который как раз отвечает за ответ, а не самостоятельное сообщение.

    Кто вызвал команду лежит в user.

    Для выбора человека и выбора из пунктов нужно ознакомиться со страницей discord-converters, там даны все типы, которые можно передать в параметры команды. Нужно только проставить типы, все остальное библиотека делает сама.
    Ответ написан
  • Как получить Member, имея id пользователя?

    fenrir1121
    @fenrir1121 Куратор тега discord.py
    Начни с документации
    в дискорде есть кнопка, и у этой кнопки свой тэг ввиде 'y/n user_id role_id'
    Проверяйте, что она имеет именно этот вид. И get_role и get_member возвращают None в случае если не найден искомый ID.
    Почему он не найден вопрос к вам.
    Ответ написан
    Комментировать