使用线程库 python 向 discord bot 添加超时

Adding a timeout to discord bot with threading library python

我一直在研究一个接受投票踢出用户然后重新邀请他们并将他们的角色还给他们的机器人。我做到了 24/7 全天候运行,并意识到我需要暂停,以便如果投票在几分钟后仍未完成,投票将被重置并可以调用新的投票。我尝试使用 Threading 库,但无法使其正常工作。

import threading
import discord
from discord.ext import commands


def reset():
    global vote_started
    global users_voted
    vote_started = False
    users_voted.clear()
    print('[+] Timeout Finished')

@client.command(pass_context=True)
async def votekick(ctx, *, member: discord.Member, Reason=None):
    global vote_started
    global users_needed
    global kicked_user
    global member_to_be_kicked
    global channel
    global role
    t = threading.Timer(120.0, reset) <===== This should call reset function after 120 seconds
    if member == client.user:
        await ctx.send('[-] ok retard')
        return
    else:
        if not vote_started:
            kicked_user = member
            member_to_be_kicked = member
            vote_started = True
            users_voted.append(ctx.author.id)
            await ctx.channel.send(
                f'[+] A votekick has started to kick {member.display_name}. [{len(users_voted)}/{users_needed}]')
            t.start    <======== This should start the reset function if this is the first vote counted
            print('[+] Timeout Started')
        else:
            if ctx.author.id in users_voted:
                await ctx.send('[-] Error: You have already voted.')
            else:
                if member != member_to_be_kicked:
                    await ctx.send(f'[-] A vote to kick {member_to_be_kicked.display_name} has already started. nice '
                                   f'try retard.')
                    return
                users_voted.append(ctx.author.id)
                if len(users_voted) < users_needed:
                    await ctx.channel.send(f'[+] Users voted: [{len(users_voted)}/{users_needed}]')
                else:
                    pass
        if len(users_voted) >= users_needed:
            invite = await ctx.channel.create_invite(reason=None, max_uses=1)
            try:
                dm_channel = await member.create_dm()
                await dm_channel.send(invite)
            except:
                pass
            await ctx.channel.send(
                f"[+] [{len(users_voted)}/{users_needed}] users have voted to kick {member.display_name}.")
            await member.kick(reason=Reason)
            vote_started = False
            users_voted.clear()
            role = member.roles
            channel = ctx.channel

当我 运行 执行此操作时,我认为应该调用重置函数,但在日志中,我看到 [+] Timeout Started 而不是我预期的 [+] Timeout Finished。这意味着永远不会调用重置函数。我需要做什么来解决这个问题。我正在使用 python 3.9.4 和 discord 重写。

计时器永远不会启动,因为您还没有初始化 t.start() 函数

只需在 t.start 中添加括号,计时器就会启动,届时您将再次尝试投票

import threading
import discord
from discord.ext import commands


def reset():
    global vote_started
    global users_voted
    vote_started = False
    users_voted.clear()
    print('[+] Timeout Finished')

@client.command(pass_context=True)
async def votekick(ctx, *, member: discord.Member, Reason=None):
    global vote_started
    global users_needed
    global kicked_user
    global member_to_be_kicked
    global channel
    global role
    t = threading.Timer(120.0, reset)
    if member == client.user:
        await ctx.send('[-] ok retard')
        return
    else:
        if not vote_started:
            kicked_user = member
            member_to_be_kicked = member
            vote_started = True
            users_voted.append(ctx.author.id)
            await ctx.channel.send(
                f'[+] A votekick has started to kick {member.display_name}. [{len(users_voted)}/{users_needed}]')
            t.start() # <========== This line
            print('[+] Timeout Started')
        else:
            if ctx.author.id in users_voted:
                await ctx.send('[-] Error: You have already voted.')
            else:
                if member != member_to_be_kicked:
                    await ctx.send(f'[-] A vote to kick {member_to_be_kicked.display_name} has already started. nice '
                                   f'try retard.')
                    return
                users_voted.append(ctx.author.id)
                if len(users_voted) < users_needed:
                    await ctx.channel.send(f'[+] Users voted: [{len(users_voted)}/{users_needed}]')
                else:
                    pass
        if len(users_voted) >= users_needed:
            invite = await ctx.channel.create_invite(reason=None, max_uses=1)
            try:
                dm_channel = await member.create_dm()
                await dm_channel.send(invite)
            except:
                pass
            await ctx.channel.send(
                f"[+] [{len(users_voted)}/{users_needed}] users have voted to kick {member.display_name}.")
            await member.kick(reason=Reason)
            vote_started = False
            users_voted.clear()
            role = member.roles
            channel = ctx.channel