How to restart a loop in discord.py? - python

I am making a discord bot using discord.py. I want to make a command to purge all messages inside a channel every 100 seconds. Here is my code:
autodeletetime = -100
autodeletelasttime = 1
#client.command()
#commands.has_permissions(manage_messages=True)
async def autodelete(ctx):
global autodeleterunning
if autodeleterunning == False:
autodeleterunning = True
asgas = True
while asgas:
message = await ctx.send(f'All messages gonna be deleted in 100 seconds')
await message.pin()
for c in range(autodeletetime,autodeletelasttime):
okfe = abs(c)
await message.edit(content=f"All messages gonna be deleted in {okfe} seconds" )
await asyncio.sleep(1)
if c == 0:
await ctx.channel.purge(limit=9999999999999999999999999999999999999999999999999999999999999999999)
await time.sleep(1)
autodeleterunning = False
else:
await ctx.send(f'The autodelete command is already running in this server')
I want the loop to restart every 100 seconds after the purge is complete.

You should use tasks instead of commands for these kind of commands.
import discord
from discord.ext import commands, tasks
import asyncio
#tasks.loop(seconds=100)
async def autopurge(channel):
message = await channel.send(f'All messages gonna be deleted in 100 seconds')
await message.pin()
try:
await channel.purge(limit=1000)
except:
await channel.send("I could not purge messages!")
#client.group(invoke_without_command=True)
#commands.has_permissions(manage_messages=True)
async def autopurge(ctx):
await ctx.send("Please use `autopurge start` to start the loop.")
# Start the loop
#autopurge.command()
async def start(ctx):
task = autopurge.get_task()
if task and not task.done():
await ctx.send("Already running")
return
autopurge.start(ctx.channel)
# Stop the loop
#autopurge.command()
async def stop(ctx):
task = autopurge.get_task()
if task and not task.done():
autopurge.stop()
return
await ctx.send("Loop was not running")

Related

Python discord bot not respoding to on_message event

I'm trying to make a discord bot but the bot is not responding to any of my commands.
He is writing the command when going online but nothing more.
I have given him every permission and intent but it did not help.
import discord
import time
intents = discord.Intents.default()
intents.members = True
client = discord.Client(intents=intents)
# Dictionary to store the brake times for each user
brb_times = {}
#client.event
async def on_message(message):
# Only process messages from other users, not the bot itself
if message.author == client.user:
return
if message.content.startswith("!brb 5"):
brb_times[message.author.name] = time.time() + 5 * 60
await message.channel.send(f"{message.author.mention} has taken a 5-minute brake.")
elif message.content.startswith("!brb 10"):
brb_times[message.author.name] = time.time() + 10 * 60
await message.channel.send(f"{message.author.mention} has taken a 10-minute brake.")
elif message.content.startswith("!brb 15"):
brb_times[message.author.name] = time.time() + 15 * 60
await message.channel.send(f"{message.author.mention} has taken a 15-minute brake.")
elif message.content.startswith("!back"):
if message.author.name in brb_times:
brake_time = brb_times[message.author.name]
del brb_times[message.author.name]
elapsed_time = time.time() - brake_time
if elapsed_time > 0:
await message.channel.send(f"{message.author.mention} is back, but was late by {int(elapsed_time)} seconds.")
else:
await message.channel.send(f"{message.author.mention} is back.")
else:
await message.channel.send(f"{message.author.mention} was not on a brake.")
#client.event
async def on_ready():
print("Bot is ready!")
await client.get_channel(CENSORED).send("Bot is ready to track breaks!")
client.run("CENSORED")
You need message_content to be True in intents.

Music Discord Bot Looping Music

I'm working on an discord music bot with python, I already have a function that plays the songs that are in a queue but I would like to add a command that plays the queue in an infinite loop. How can I do this?
Those are the commands that set the loop value to True or False
#client.command(name='loop', help='Enable loop')
async def loop_on(ctx):
global loop
loop = True
await ctx.send('Looping')
#client.command(name='dunloop', help='Disable loop')
async def loop_off(ctx):
global loop
loop = False
await ctx.send('Loop disabled')
And here the code that plays the music
#client.command(name='play', help='Plays Music')
async def play(ctx):
global queue
if not ctx.message.author.voice:
await ctx.send("You are not connected to a voice channel")
return
else:
channel = ctx.message.author.voice.channel
try: await channel.connect()
except: pass
server = ctx.message.guild
voice_channel = server.voice_client
try:
async with ctx.typing():
player = await YTDLSource.from_url(queue[0], loop=client.loop)
voice_channel.play(player, after=lambda e: print('Player error: %s' % e) if e else None)
if loop:
queue.append(queue[0])
del(queue[0])
await ctx.send('**Playing :** {}'.format(player.title))
except:
await ctx.send('The queue is empty .Use ?queue to add a song !')
And now I would like to add a command that plays the queue without stopping while the loop value is set to True.

How can I send a message without a command?

I want to send a message without command if a condition is true. I wrote this code but it doesn't send any message.
from discord import channel
from discord.ext import commands
from time import sleep
bot = commands.Bot(command_prefix='.')
token = '***'
condition = True
#bot.event
async def on_ready():
print('crypto-bot รจ pronto')
#bot.event
async def on_message(message):
if message.author == bot.user:
return
if message.content == '.ciao':
await message.channel.send('ciao')
async def my_background_task():
if condition == True:
channel = bot.get_channel(926067178539712512)
await channel.send('true')
bot.run(token)
async def my_background_task():
if condition == True:
channel = bot.get_channel(926067178539712512)
await channel.send('true')
await my_background_task()
I know for sure it wasnt working because you didnt trigger the function..but I dont know if this will work or not if this doesnt work trigger the function in the on_message function like this
async def on_message(message):
if message.author == bot.user:
return
if message.content == '.ciao':
await message.channel.send('ciao')
await my_background_task()
You can use tasks.loop for this. It will run every "x" seconds (in my example it's 5 seconds, but you can change it to minutes or hours).
from discord.ext import tasks # add this import
condition = True
#tasks.loop(seconds=5) # choose how often you want to run this function (e.g every 5 seconds)
async def my_background_task():
if condition == True:
channel = await bot.fetch_channel(926067178539712512)
await channel.send('true')
my_background_task.start() # put this before `bot.run(token)`
Like #l---Wernia---l noticed it will continue sending the message until the condition changes. If you want to send only one message then you have to change the condition to False.
#tasks.loop(seconds=5)
async def my_background_task():
global condition # if you want to change global variable inside the function you have to add this line
if condition == True:
channel = await bot.fetch_channel(926067178539712512)
await channel.send('true')
condition = False # changing condition at the end

Discord Python Bot Breaking My Commands When Using Background Task

I am working on a discord bot in python that send a scheduled message in a server at very specific times every day as well as other functionalities. After implementing the scheduled message, the bot commands no longer work - so the users can't use any of the commands but the scheduled message works.
I have the bot set up so it sends a message at 12:00,19:00,21:00,22:00,23:00 UTC. The only problem is now the commands such as ";help" do not work.
import discord
import datetime
import asyncio
from discord.ext import commands
from discord.utils import get
client = commands.Bot(command_prefix = ';',help_command=None) #prefix
race_times_utc = [12,19,21,22,23]
time = datetime.datetime.now
async def timer():
await client.wait_until_ready()
msg_sent = False
while not client.is_closed():
if any(time().hour == race for race in race_times_utc) and time().minute == 0:
if not msg_sent:
channel = client.get_channel(838626115326636022)
racer_role = get(channel.guild.roles, name = 'Racers')
embed = discord.Embed(
title = 'Race Time',
description = 'Scheduled reminder for everyone that race starts soon.',
colour = discord.Colour.blue()
)
await channel.send(f'{racer_role.mention}',embed=embed)
msg_sent = True
else:
msg_sent = False
await asyncio.sleep(1)
#client.event
async def on_ready():
await client.change_presence(activity=discord.Activity(type=discord.ActivityType.watching, name=' ;help'))
client.loop.create_task(timer())
print('Bot is alive')
#Functions such as this no longer working
#client.command()
async def help(ctx):
...
You should use discord.ext.tasks as it seems part of your code is blocking.
import discord
import datetime
import asyncio
from discord.ext import tasks, commands
from discord.utils import get
client = commands.Bot(command_prefix = ';',help_command=None) #prefix
race_times_utc = [12,19,21,22,23]
time = datetime.datetime.now
#tasks.loop(seconds=1.0) # replaces the sleep
async def timer():
msg_sent = False
if any(time().hour == race for race in race_times_utc) and time().minute == 0:
if not msg_sent:
channel = client.get_channel(838626115326636022)
racer_role = get(channel.guild.roles, name = 'Racers')
embed = discord.Embed(
title = 'Race Time',
description = 'Scheduled reminder for everyone that race starts soon.',
colour = discord.Colour.blue()
)
await channel.send(f'{racer_role.mention}',embed=embed)
msg_sent = True
else:
msg_sent = False
#client.event
async def on_ready():
await client.change_presence(activity=discord.Activity(type=discord.ActivityType.watching, name=' ;help'))
print('Bot is alive')
timer.start()

Trying to get my discord bot in python to say the same message every 5 seconds

I am making sort of a "hack" for dank memer. I have made my own bot. My goal with the bot was to get it to keep saying "pls search" about every 5 seconds. Eventually, I would make a command that says "pls give 100" to get the coins. Instead of showing up in discord, it showed up in my app.
#client.command()
async def go(ctx):
def printit():
threading.Timer(5.0, printit).start()
await ctx.send("pls search")
printit()
This will continuously send messages, but you will get rate-limited. This works by scheduling a task in the event loop that sends messages, then canceling it.
import asyncio
#bot.command()
async def comm(ctx):
async def f():
while True:
# await asyncio.sleep(.5) # Control message speed
await ctx.send('Test')
await ctx.send("Start")
task = asyncio.create_task(f())
await asyncio.sleep(5)
await ctx.send("End")
task.cancel()
You can do this:
import time
#bot.command()
async def start(ctx, number_of_times=5):
for i in range(number_of_times):
await ctx.send('pls search')
time.sleep(5)
# type in the user
await ctx.send('pls give <user> 100')
import discord, os, asyncio
from discord.ext import commands
from colorama import Fore, Style
token = "Token Here"
#Bot prefix, like ?help
prefix = ["|", "!", "/"]
def endSong(guild, path):
os.remove(path)
#Clear Command
def Clear():
os.system('clear')
#Colors
def RandomColor():
randcolor = discord.Color(random.randint(0x000000, 0xFFFFFF))
return randcolor
def RandString():
return "".join(
random.choice(string.ascii_letters + string.digits)
for i in range(random.randint(14, 32)))
#Prefix
client = discord.Client()
client = commands.Bot(command_prefix=prefix, self_bot=True)
#Dep
#client.command(name='dankmemer', aliases=['dank', 'dmc'])
async def dankmemer(ctx):
await ctx.message.delete()
count = 0
while True:
try:
count += 1
await ctx.send('pls beg')
print(
f'{Fore.BLUE}[AUTO-MEME] {Fore.GREEN}Meme number: {count} sent'
+ Fore.RESET)
await asyncio.sleep(26)
except Exception as e:
print(f"{Fore.RED}[ERROR]: {Fore.YELLOW}{e}" + Fore.RESET)
#Farm
#client.command(name='dank-farm', aliases=['dankfarm', "dm"])
async def _fish_dank(ctx): # b'\xfc'
await ctx.message.delete()
count = 0
while True:
try:
count += 1
await ctx.send('pls fish')
await ctx.send('pls hunt')
await ctx.send('pls dig')
print(
f'{Fore.BLUE}[AUTO-FARM] {Fore.GREEN}Farm number: {count} sent'
+ Fore.RESET)
await asyncio.sleep(26)
except Exception as e:
print(f"{Fore.RED}[ERROR]: {Fore.YELLOW}{e}" + Fore.RESET)
#onReady
#client.event
async def on_ready():
print(f"You are Online :)")
client.run(token, bot=False)

Categories

Resources