'Discord Bot Looping Task from Command
Good afternoon all, I should preface this post with the statement that I am pretty new to Python and know enough to get myself into trouble, but not enough to always get out of trouble...this is one of those instances I can't get out.
I am attempting to create a Discord Bot using discord.py that has the ultimate goal of being started from a command in Discord, starts counting the days since the start command was issued, and sends a message to Discord every morning with the count. I also would have a command to reset the count and another to cancel the counter. For testing purposes, I have created code to count minutes instead of days and a task loop of only 10 seconds rather than a full day.
My problem is that I am attempting to use a discord.ext task for the loop, but I clearly don't know how to use it properly, and my research online has not made it any more clear to me. I'm hoping some folks here can steer me in the right direction. I have supplied my code below.
What I expect to happen when I execute my code:
- I issue the $start arg command and the bot sends a message of "It has been X minutes"
- Every 10 seconds the bot sends the same message until 1 minute has passed, then message reads "It has been X+1 minutes"
- Continue looping until canceled
What actually happens:
- I issue the $start arg command and the bot sends a message of "It has been X minutes"
- Nothing else. No other messages or anything happens in Discord, no errors shown in the console.
The code is currently being hosted on replit.com, hence the keep_alive function using UpTimeRobot to keep the bot alive. Something to note, I originally used asyncio.sleep() to just wait to send the new message. This worked fine for shorter periods (like a few minutes to hours) but even with UpTimeRobot doing its thing, I can't get 100% uptime of the Bot and I think whenever the bot went offline for a few minutes, it stopped my counter loop and that was that. This is what lead me to look into Tasks, as I read they can be used to continue loops on reconnection if the bot goes offline for a bit.
import discord
import os
import keep_alive
from datetime import date, datetime, time, timedelta
from discord.ext import commands, tasks
bot = commands.Bot(command_prefix="$")
init_count = 0
count = 0
channel_id = My_Channel_ID_Here
@bot.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
@tasks.loop(seconds=10, count=None, reconnect=True)
async def min_counter():
global count
global init_count
count = init_count
today = datetime.today()
now = datetime.today()
channel = bot.get_channel(channel_id)
if today.minute != now.minute:
# increment count by 1
count = count + 1
today = now
print('Count: ' + str(count))
await channel.send('It Has Been ' + str(count) + ' Minutes.') # Send message of minutes count
@bot.command() # Command to start the counter
async def start (ctx, arg: int): # arg is initial number of minutes to start with
global init_count
init_count = arg
await ctx.send('It Has Been ' + str(init_count) + ' Minutes.') # Send message of minutes count
min_counter.start()
@bot.command() # Command to reset counter
async def reset (ctx):
global count
count = 0
await ctx.send('It Has Been 0 Minutes.') # Send message that count is not zero
@bot.command() # Command to stop the counter
async def stop (ctx):
min_counter.cancel()
await ctx.send('Counter Stopped.')
keep_alive.keep_alive() # keep alive function call
bot.run(os.getenv('TOKEN')) # Discord bot private token call
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
