来自命令的 Discord Bot 循环任务
Discord Bot Looping Task from Command
大家下午好,
我应该在 post 开头声明我是 Python 的新手并且知道足以让自己陷入麻烦,但还不足以总能摆脱麻烦......这就是其中一个例子我出不去了。
我正在尝试使用 discord.py 创建一个 Discord Bot,其最终目标是从 Discord 中的命令启动,开始计算启动命令发出后的天数,并向 Discord 发送消息每天早上和伯爵在一起。我还会有一个命令来重置计数,另一个命令来取消计数器。
出于测试目的,我创建了代码来计算分钟数而不是天数,并创建了一个仅 10 秒而不是一整天的任务循环。
我的问题是我试图在循环中使用 discord.ext 任务,但我显然不知道如何正确使用它,我的在线研究也没有更清楚地说明我。我希望这里的一些人可以引导我朝着正确的方向前进。我在下面提供了我的代码。
当我执行我的代码时我期望发生什么:
- 我发出 $start arg 命令,bot 发送消息“已经 X 分钟”
- 机器人每 10 秒发送一次相同的消息,直到 1 分钟过去,然后消息显示为“已经 X+1 分钟”
- 继续循环直到取消
实际发生了什么:
- 我发出 $start arg 命令,bot 发送消息“已经 X 分钟”
- 没有别的。 Discord 中没有其他消息或任何事情发生,控制台中没有显示任何错误。
代码目前托管在 replit.com 上,因此 keep_alive 函数使用 UpTimeRobot 来保持机器人的活动。
需要注意的是,我最初使用 asyncio.sleep() 只是等待发送新消息。这在较短的时间内(比如几分钟到几小时)效果很好,但即使有 UpTimeRobot 做它的事情,我也无法获得机器人 100% 的正常运行时间,我认为每当机器人离线几分钟,它就会停止我的柜台循环就是这样。这就是促使我研究任务的原因,正如我所读,如果机器人离线一段时间,它们可用于在重新连接时继续循环。
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
经过快速检查,您正在循环方法 min_counter()
,但每次调用它时,您都会将 now
和 today
的值更改为 datetime.today()
。
所以当你去比较这里的值时:
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
这将始终评估为 False。
轻松修复
虽然我不太喜欢使用全局变量,但我们可以通过以下方法解决此问题,同时保持您现在的风格。
启动计数器并在全局范围内初始化一个名为 start_time
的变量:
@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, start_time
start_time = datetime.today()
await ctx.send('It Has Been ' + str(init_count) + ' Minutes.') # Send message of minutes count
min_counter.start()
然后在循环中检查start_time
是否等于now
:
@tasks.loop(seconds=10, count=None, reconnect=True)
async def min_counter():
global count, start_time, init_count
now = datetime.today()
channel = bot.get_channel(channel_id)
if start_time != now:
# increment count by 1
count = count + 1
print('Count: ' + str(count))
await channel.send('It Has Been ' + str(count) + ' Minutes.') # Send message of minutes count
如果一切都适合您,请告诉我,如果需要,我很乐意提供进一步帮助。
大家下午好, 我应该在 post 开头声明我是 Python 的新手并且知道足以让自己陷入麻烦,但还不足以总能摆脱麻烦......这就是其中一个例子我出不去了。
我正在尝试使用 discord.py 创建一个 Discord Bot,其最终目标是从 Discord 中的命令启动,开始计算启动命令发出后的天数,并向 Discord 发送消息每天早上和伯爵在一起。我还会有一个命令来重置计数,另一个命令来取消计数器。 出于测试目的,我创建了代码来计算分钟数而不是天数,并创建了一个仅 10 秒而不是一整天的任务循环。
我的问题是我试图在循环中使用 discord.ext 任务,但我显然不知道如何正确使用它,我的在线研究也没有更清楚地说明我。我希望这里的一些人可以引导我朝着正确的方向前进。我在下面提供了我的代码。
当我执行我的代码时我期望发生什么:
- 我发出 $start arg 命令,bot 发送消息“已经 X 分钟”
- 机器人每 10 秒发送一次相同的消息,直到 1 分钟过去,然后消息显示为“已经 X+1 分钟”
- 继续循环直到取消
实际发生了什么:
- 我发出 $start arg 命令,bot 发送消息“已经 X 分钟”
- 没有别的。 Discord 中没有其他消息或任何事情发生,控制台中没有显示任何错误。
代码目前托管在 replit.com 上,因此 keep_alive 函数使用 UpTimeRobot 来保持机器人的活动。 需要注意的是,我最初使用 asyncio.sleep() 只是等待发送新消息。这在较短的时间内(比如几分钟到几小时)效果很好,但即使有 UpTimeRobot 做它的事情,我也无法获得机器人 100% 的正常运行时间,我认为每当机器人离线几分钟,它就会停止我的柜台循环就是这样。这就是促使我研究任务的原因,正如我所读,如果机器人离线一段时间,它们可用于在重新连接时继续循环。
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
经过快速检查,您正在循环方法 min_counter()
,但每次调用它时,您都会将 now
和 today
的值更改为 datetime.today()
。
所以当你去比较这里的值时:
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
这将始终评估为 False。
轻松修复
虽然我不太喜欢使用全局变量,但我们可以通过以下方法解决此问题,同时保持您现在的风格。
启动计数器并在全局范围内初始化一个名为 start_time
的变量:
@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, start_time
start_time = datetime.today()
await ctx.send('It Has Been ' + str(init_count) + ' Minutes.') # Send message of minutes count
min_counter.start()
然后在循环中检查start_time
是否等于now
:
@tasks.loop(seconds=10, count=None, reconnect=True)
async def min_counter():
global count, start_time, init_count
now = datetime.today()
channel = bot.get_channel(channel_id)
if start_time != now:
# increment count by 1
count = count + 1
print('Count: ' + str(count))
await channel.send('It Has Been ' + str(count) + ' Minutes.') # Send message of minutes count
如果一切都适合您,请告诉我,如果需要,我很乐意提供进一步帮助。