@DarkHold
Пытаюсь написать бота для Дискорд серевера

Как подружить команду mute и unmute?

Я пишу многофункционального бот для дискорд серверов но так как владею Python на уровне
О это чё за фигня
Получается много ошибок, и вот над этой я ломаю голову 16 часов без перерыва. В chat GPT пробовал но он выдает гениальные решение которые добавляют мороки. Короче
Я могу выдать Мут но при попытке его снять досрочно командой unmute получается ошибка так как в коде используется чат gpt был добавлен блок который вида изменил ошибку и короче теперь она выглядит так

Вот команда mute

<code>
@bot.command()
@has_allowed_role("mute")
async def mute(ctx, member: discord.Member = None, duration: str = None, *, reason: str = None):
    if member is None:
        embed = discord.Embed(
            title="Ошибка",
            description="Вы не упомянули пользователя, которому нужно выдать наказание.",
            color=discord.Color.red()
        )
        await ctx.send(embed=embed)
        return

    if duration is None:
        embed = discord.Embed(
            title="Ошибка",
            description="Вы не указали длительность мута.",
            color=discord.Color.red()
        )
        await ctx.send(embed=embed)
        return

    try:
        duration = int(duration)
    except ValueError:
        embed = discord.Embed(
            title="Ошибка",
            description="Продолжительность мута должна быть числом.",
            color=discord.Color.red()
        )
        await ctx.send(embed=embed)
        return

    if duration <= 0:
        embed = discord.Embed(
            title="Ошибка",
            description="Продолжительность мута должна быть положительным числом.",
            color=discord.Color.red()
        )
        await ctx.send(embed=embed)
        return

    if reason is None:
        embed = discord.Embed(
            title="Ошибка",
            description="Вы должны указать причину для мута.",
            color=discord.Color.red()
        )
        await ctx.send(embed=embed)
        return

    if member.top_role.position >= ctx.author.top_role.position or member.top_role.position >= ctx.guild.me.top_role.position:
        embed = discord.Embed(
            title="Ошибка",
            description="Вы не можете выдать мут пользователю с ролью, которая находится выше вашей или бота в иерархии.",
            color=discord.Color.red()
        )
        await ctx.send(embed=embed)
        return

    if member.id in temporary_mutes:
        embed = discord.Embed(
            title="Ошибка",
            description="Этот пользователь уже имеет мут.",
            color=discord.Color.red()
        )
        await ctx.send(embed=embed)
        return

    # Проверяем права бота
    if not ctx.guild.me.guild_permissions.manage_roles:
        embed = discord.Embed(
            title="Ошибка",
            description="У бота нет прав для управления ролями.",
            color=discord.Color.red()
        )
        await ctx.send(embed=embed)
        return

    if not ctx.guild.me.guild_permissions.moderate_members:
        embed = discord.Embed(
            title="Ошибка",
            description="У бота нет прав для управления тайм-аутами пользователей.",
            color=discord.Color.red()
        )
        await ctx.send(embed=embed)
        return

    # Выдаем мут пользователю (тайм-аут)
    timeout_duration = timedelta(minutes=duration)
    unmute_time = datetime.utcnow() + timeout_duration

    try:
        await member.edit(timed_out_until=unmute_time, reason=f"{reason} (Модератор: {ctx.author})")
        temporary_mutes[member.id] = (ctx.guild.id, unmute_time)
        embed = discord.Embed(
            title="Успешно",
            description=f'{member.mention} был замучен на {duration} минут по причине: {reason}',
            color=discord.Color.green()
        )
        await ctx.send(embed=embed)
    except discord.Forbidden:
        embed = discord.Embed(
            title="Ошибка",
            description="У меня недостаточно прав для мута этого пользователя.",
            color=discord.Color.red()
        )
        await ctx.send(embed=embed)
    except discord.HTTPException as e:
        embed = discord.Embed(
            title="Ошибка",
            description=f"Произошла ошибка при попытке мута: {e}",
            color=discord.Color.red()
        )
        await ctx.send(embed=embed)

    # Отправляем сообщение в лог-канал
    log_channel = bot.get_channel(config.LOG_CHANNEL_ID)
    if log_channel:
        log_embed = discord.Embed(
            title="Пользователю выдан мут",
            description=f"Пользователю {member.mention} был выдан мут на {duration} минут по причине: {reason}.",
            color=discord.Color.red()
        )
        await log_channel.send(embed=log_embed)

@tasks.loop(minutes=1)
async def check_mutes():
    now = datetime.utcnow()
    to_remove = [user_id for user_id, (guild_id, unmute_time) in temporary_mutes.items() if now >= unmute_time]

    for user_id in to_remove:
        guild = bot.get_guild(temporary_mutes[user_id][0])
        if guild is None:
            continue

        member = guild.get_member(user_id)
        if member is None:
            continue

        try:
            await member.edit(timed_out_until=None, reason="Автоматическое снятие мута")
            del temporary_mutes[user_id]
            print(f"[INFO] Мут снят с пользователя {member}")
        except discord.Forbidden:
            print(f"[ERROR] Недостаточно прав для снятия мута с пользователя {member}")
        except discord.HTTPException as e:
            print(f"[ERROR] Ошибка при попытке снять мут с пользователя {member}: {e}")
</code>

Вот команда unmute 
<code lang="python">
<code>
@bot.command()
@has_allowed_role("unmute")
async def unmute(ctx, member: discord.Member):
    # Проверяем, есть ли временное ограничение у пользователя
    if member.id not in temporary_mutes:
        embed = discord.Embed(
            title="Ошибка",
            description="Пользователь не имеет мута.",
            color=discord.Color.red()
        )
        await ctx.send(embed=embed)
        return

    try:
        # Снимаем временное ограничение
        await member.edit(timed_out_until=None, reason=f"Мут снят модератором {ctx.author}")
        del temporary_mutes[member.id]
        embed = discord.Embed(
            title="Успешно",
            description=f"Мут пользователя {member.mention} успешно снят.",
            color=discord.Color.green()
        )
        await ctx.send(embed=embed)
    except discord.Forbidden:
        embed = discord.Embed(
            title="Ошибка",
            description="У меня недостаточно прав для снятия мута этого пользователя.",
            color=discord.Color.red()
        )
        await ctx.send(embed=embed)
    except discord.HTTPException as e:
        embed = discord.Embed(
            title="Ошибка",
            description=f"Произошла ошибка при попытке снятия мута: {e}",
            color=discord.Color.red()
        )
        await ctx.send(embed=embed)<code 
</code>

P.S словари все есть temp_mutes и intents , библиотеки все установлены
  • Вопрос задан
  • 49 просмотров
Решения вопроса 1
fenrir1121
@fenrir1121 Куратор тега discord.py
Начни с документации
Как подружить команду mute и unmute?
Mute и Unmute дружите. Годится?

Соблюдайте правила русского языка и формулируйте вопрос так, чтобы не нужно было домысливать что имеется ввиду.

Для начала разберемся в терминологии дискорда. То что вы делаете называется таймаутом пользователя, мут в отличии от таймаута автоматически не снимается. В данном случае это важно потому что вероятно вы все 16 часов гуглили не то.
Таймаут не требуется хранить и отслеживать - специально для этого у объекта пользователя есть атрибут Member.timed_out_until, там будет None если таймаута нет или datetime его истечения.

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

И перейдите уже на слеш-команды. 80% кода состоит из валидации полей, вам там ок игнорировать последние 2 года развития библиотек?
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы