如何制作在 Python 中发布消息时调用的循环 Discord Bot 任务
How to Make a Looping Discord Bot Task that is Invoked When a Message is Posted in Python
我正在尝试编写一个发布昨天的 Wordle 解决方案的 discord 机器人,但我似乎无法弄清楚如何让消息调用任务,然后让该任务循环。我尝试使用 while 循环,但该机器人只能在一台服务器上工作。尝试使用循环任务也不起作用。这是代码
import imp
import json
import requests
import discord
import os
import time
from datetime import date, timedelta
from discord.ext import tasks
client = discord.Client()
#channel_id_exists = False
#channel_id = 0
@client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
@client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('!wordle_setup'):
await message.delete()
await message.channel.send("Setting up...")
channel_id = message.channel.id
await wordle_guess(channel_id).start()
@tasks.loop(seconds=10)
async def wordle_guess(channel_id):
message_channel = client.get_channel(channel_id)
yesterday = date.today() - timedelta(days=1)
year = yesterday.year
month = yesterday.month
day = yesterday.day
word_guess = json.loads(requests.get(
"https://najemi.cz/wordle_answers/api/?day={0}&month={1}&year={2}".format(day, month, year)).text)["word"]
await message_channel.send("Word guess for " + yesterday.isoformat() + " : " + word_guess + '\nhttps://www.merriam-webster.com/dictionary/' + word_guess)
client.run("TOKEN")
机器人在设置时卡住,或者任务没有在 10 秒内循环,或者机器人只适用于一台服务器。我使用设置命令来防止需要将频道 ID 硬编码到代码中。
我已通过将代码包装在客户端 class 中并允许存储多个频道 ID 解决了这个问题。新代码显示在这里。
import asyncio
import imp
import json
import requests
import discord
import os
import time
from datetime import date, timedelta
from discord.ext import tasks
import threading
print("test!")
class MyClient(discord.Client):
channel_id = []
channel_id_exists = False
async def on_ready(self):
print('We have logged in as {0.user}'.format(self))
async def on_message(self, message):
if message.author == self.user:
return
if message.content.startswith('!wordle_setup'):
await message.delete()
await message.channel.send("Setting up...")
self.channel_id.append(message.channel.id)
self.channel_id_exists = True
@tasks.loop(seconds=3600*24)
async def wordle_guess(self):
if self.channel_id_exists:
yesterday = date.today() - timedelta(days=1)
year = yesterday.year
month = yesterday.month
day = yesterday.day
for channel_id_iter in self.channel_id:
message_channel = self.get_channel(channel_id_iter)
word_guess = json.loads(requests.get(
"https://najemi.cz/wordle_answers/api/?day={0}&month={1}&year={2}".format(day, month, year)).text)["word"]
await message_channel.send("Wordle guess for " + yesterday.isoformat() + " : " + word_guess + '\nhttps://www.merriam-webster.com/dictionary/' + word_guess)
client = MyClient()
client.wordle_guess.start()
client.run("TOKEN")
我正在尝试编写一个发布昨天的 Wordle 解决方案的 discord 机器人,但我似乎无法弄清楚如何让消息调用任务,然后让该任务循环。我尝试使用 while 循环,但该机器人只能在一台服务器上工作。尝试使用循环任务也不起作用。这是代码
import imp
import json
import requests
import discord
import os
import time
from datetime import date, timedelta
from discord.ext import tasks
client = discord.Client()
#channel_id_exists = False
#channel_id = 0
@client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
@client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('!wordle_setup'):
await message.delete()
await message.channel.send("Setting up...")
channel_id = message.channel.id
await wordle_guess(channel_id).start()
@tasks.loop(seconds=10)
async def wordle_guess(channel_id):
message_channel = client.get_channel(channel_id)
yesterday = date.today() - timedelta(days=1)
year = yesterday.year
month = yesterday.month
day = yesterday.day
word_guess = json.loads(requests.get(
"https://najemi.cz/wordle_answers/api/?day={0}&month={1}&year={2}".format(day, month, year)).text)["word"]
await message_channel.send("Word guess for " + yesterday.isoformat() + " : " + word_guess + '\nhttps://www.merriam-webster.com/dictionary/' + word_guess)
client.run("TOKEN")
机器人在设置时卡住,或者任务没有在 10 秒内循环,或者机器人只适用于一台服务器。我使用设置命令来防止需要将频道 ID 硬编码到代码中。
我已通过将代码包装在客户端 class 中并允许存储多个频道 ID 解决了这个问题。新代码显示在这里。
import asyncio
import imp
import json
import requests
import discord
import os
import time
from datetime import date, timedelta
from discord.ext import tasks
import threading
print("test!")
class MyClient(discord.Client):
channel_id = []
channel_id_exists = False
async def on_ready(self):
print('We have logged in as {0.user}'.format(self))
async def on_message(self, message):
if message.author == self.user:
return
if message.content.startswith('!wordle_setup'):
await message.delete()
await message.channel.send("Setting up...")
self.channel_id.append(message.channel.id)
self.channel_id_exists = True
@tasks.loop(seconds=3600*24)
async def wordle_guess(self):
if self.channel_id_exists:
yesterday = date.today() - timedelta(days=1)
year = yesterday.year
month = yesterday.month
day = yesterday.day
for channel_id_iter in self.channel_id:
message_channel = self.get_channel(channel_id_iter)
word_guess = json.loads(requests.get(
"https://najemi.cz/wordle_answers/api/?day={0}&month={1}&year={2}".format(day, month, year)).text)["word"]
await message_channel.send("Wordle guess for " + yesterday.isoformat() + " : " + word_guess + '\nhttps://www.merriam-webster.com/dictionary/' + word_guess)
client = MyClient()
client.wordle_guess.start()
client.run("TOKEN")