I have been working on a bot that accepts votes to kick a user then re-invites them and gives them their roles back. I made it go 24/7 and realized I need a timeout so that if the vote doesn't complete after a few minutes, the voting will be reset and a new vote can be called. I tried using the Threading library but I cant get it to work properly.
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
When I run this, I thought the reset function should have been called, but in the logs, I see [+] Timeout Started
but not [+] Timeout Finished
like I expected. This means the reset function is never called. What do I need to do to fix this. I am using python 3.9.4 with the discord rewrite.
Timer will never start, because you haven't initialized the t.start()
function
Just add parentheses to t.start
and timer will start, when you'll try to votekick again
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