【发布时间】:2021-02-19 09:36:41
【问题描述】:
我有一个 for 循环,它遍历一个问题列表,为每个问题创建一个嵌入。这意味着然后等待答案,然后问下一个问题。然后我将答案上传到 mongodb 数据库(在运行一些检查以确保它们是有效答案之后。
我遇到的问题是,有时(10 次尝试中的 3 次)它会一个接一个地问两个问题,而没有时间回答第一个问题。我玩过 sleep() 但发现它仍然会发生。
如果您能提供任何帮助,我们将不胜感激!
import re
import datetime
from copy import deepcopy
import emojis
import asyncio
import discord
import math
import random
from discord.ext import commands, tasks
from dateutil.relativedelta import relativedelta
from utils.util import GetMessage
from time import sleep
"""
product = ['Name': 'Example_Name', 'Description': 'Example Description', 'Quantity in stock': 10, 'Price': 400]
Name =product[0]
Description = product[1]
Quantity = product[2]
Price= product[3]
"""
class Shop(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.Cog.listener()
async def on_ready(self):
print(f"{self.__class__.__name__} Cog has been loaded\n-----")
@commands.command(
name='ShopAddProduct',
#aliases=['w'],
description="List all the Shops",
#usage = "[User] <Name>"
)
@commands.has_role("Server Player")
@commands.has_permissions(send_messages=True)
async def ShopAddProduct(self, ctx):
member = ctx.author
channel = await member.create_dm()
await channel.send("Lets add a product. Answer the following questions to add a product to your shop")
questionList = [
["What is your shop called?","Enter the Name of your shop"],
["What is the product called?","Enter what your product is called"],
["Describe your product","Enter a description"],
["How many of them do you have ready to sell?","Enter how many you have in stock"],
["how much are you selling them for?","Enter how many credits you want for this product."]
]
answers = {}
for i, question in enumerate(questionList):
#answer = await GetMessage(self.bot, ctx, question[0], question[1])
embed = discord.Embed(
title=f"{question[0]}",
description =f"{question[1]}",
)
embed.set_thumbnail(url=ctx.guild.icon_url)
sent = await channel.send(embed=embed)
try:
answer = await self.bot.wait_for(
"message",
timeout=60,
check=lambda message: isinstance(message.channel, discord.channel.DMChannel)
)
except asyncio.TimeoutError:
await sent.delete()
await channel.send("Cancelling due to timeout.", delete_after=10)
sleep(2)
answers[i] = answer.content
embed = discord.Embed(name="Add Product")
for key, value in answers.items():
embed.add_field(name=f"Question: `{questionList[key][0]}`", value=f"Answer: `{value}`", inline=False)
m = await channel.send("Are these all valid?", embed=embed)
await m.add_reaction("✅")
await m.add_reaction("????")
try:
reaction, member = await self.bot.wait_for(
"reaction_add",
timeout=60,
check=lambda reaction, user: user == ctx.author
and reaction.message.channel == channel
)
except asyncio.TimeoutError:
await channel.send("Confirmation Failure. Please try again.")
return
if str(reaction.emoji) not in ["✅", "????"] or str(reaction.emoji) == "????":
await channel.send("Cancelling Product Addition!")
#check answers validity
check = await self.bot.shop.find_by_id(answers[0])
if check == None:
await channel.send(f"The shop `{answers[0]}` does not exist! Please try again.")
return
if not answers[3].isdigit():
#not isinstance(answers[3],int):
await channel.send(f"The quantity you submitted (`{answers[3]}`) must be whole number (integer)! Please try again.")
return
if not answers[4].isdigit():
#not isinstance(answers[4],int):
await channel.send(f"The price you submitted (`{answers[4]}`) must be whole number (integer)! Please try again.")
return
shopcheck = await self.bot.shopCatalogue.find_by_id(answers[0])
productlist = shopcheck['Products']
print(productlist)
product = [answers[1], answers[2], int(answers[3]), int(answers[4])]
productlist.append(product)
print(product)
print(productlist)
data = {
'_id': shopcheck['_id'],
'Products': productlist
}
guild=ctx.guild
await self.bot.shopCatalogue.upsert(data)
embed = discord.Embed(
title=f"Product Added to Shop Catalogue!",
#description =,
)
embed.add_field(
name=f"Product:",
value=answers[1],
inline=True
)
embed.add_field(
name=f"Description:",
value=answers[2],
inline=True
)
embed.add_field(
name=f"Quantity:",
value=answers[3],
inline=False
)
embed.add_field(
name=f"Price:",
value=answers[4],
inline=True
)
embed.set_thumbnail(url=ctx.guild.icon_url)
sent = await channel.send(embed=embed)
def setup(bot):
bot.add_cog(Shop(bot))
【问题讨论】:
-
超时是否会继续循环,即使没有回复也会发送下一条消息?
-
我不确定。我发现无论我是否在上一次尝试运行它时超时都会发生这种情况。它只是发生在一次运行完全有效的情况下,接下来的两个同时提出了前三个问题
-
另一种想法 -
wait_for没有指定消息必须来自某个渠道(正如wait_for文档中的示例之一)。如果其他人在不同的 DM 频道中发送消息,那么它将在机器人实际发送到的任何频道中继续循环。 -
啊,我是目前唯一可以访问该机器人的人,因此不会导致此问题,但在将此机器人公开之前,我需要解决这个问题。请问我该如何指定消息必须来自哪个频道?你能指出你提到的例子的方向吗?
-
这在
wait_for文档here 中。他们有几个例子,但第一个有一个check参数,用于检查接收消息的通道。
标签: python discord.py