Итак, это может показаться немного странным вопросом, но недавно я создал команду для своего бота в разногласиях, которая шаг за шагом проводит пользователя через создание встраивания. Это работает отлично, но я хотел реализовать способ завершения команды даже без заполнения всех полей. Таким образом, если пользователь набирает «завершить» при создании встраивания, он перейдет к той части процесса сборки, которая спрашивает, на какие каналы он хочет отправить встраивание. Вот мой код:
@embed.command()
@commands.has_permissions(manage_permissions = True)
@commands.bot_has_permissions(manage_permissions = True)
async def build(self, ctx):
channel = ctx.channel
content = f''
def check(m):
if m.channel == m.channel and m.content == "CANCEL":
raise ValueError("Cancelled command")
return m.content.lower is not None and m.channel == channel and m.content.lower
# The first round: TITLE
beggining = await ctx.send('Alright! Let\'s get started! What would you like the **title** of your embed to be?')
firstin = await self.bot.wait_for("message", check=check)
await firstin.delete() # Delete the first input
await beggining.delete()
firstembed=discord.Embed(title=f'{firstin.content}')
# The second round: MAIN BODY
theembed = await ctx.send(content=content, embed=firstembed)
asking = await ctx.send('Got it! What would you like the **main body** of your embed to be?')
secondin = await self.bot.wait_for("message", check=check)
await secondin.delete() # Delete the second input
secondembed=discord.Embed(title=firstin.content, description=secondin.content)
await theembed.edit(content=content, embed=secondembed)
await asking.edit(content='Okay. Now, what would you like the **footer** of your embed to be?')
# The third round: FOOTER
thirdin = await self.bot.wait_for("message", check=check)
await thirdin.delete() # Delete the third input
thirdembed=discord.Embed(title=firstin.content, description=secondin.content)
thirdembed.set_footer(text=thirdin.content)
await theembed.edit(content=content, embed=thirdembed)
await asking.edit(content='Sounds good. Now, what would you like the **hex color code** of your embed to be?')
# Fourth round: COLOR
fourthin = await self.bot.wait_for("message", check=check)
await fourthin.delete() # Delete the fourth input
readableHex = int(hex(int(fourthin.content.replace("#", ""), 16)), 0)
fourthembed=discord.Embed(title=firstin.content, description=secondin.content, color=readableHex)
fourthembed.set_footer(text=thirdin.content)
await theembed.edit(content=content, embed=fourthembed)
await asking.edit(content='Cool. What would you like the **image link** of your embed to be?')
# The fifth round: IMAGE
fifthin = await self.bot.wait_for("message", check=check)
await fifthin.delete() # Delete the fifth input
fifthembed=discord.Embed(title=firstin.content, description=secondin.content, color=readableHex)
fifthembed.set_footer(text=thirdin.content)
fifthembed.set_image(url=fifthin.content)
await theembed.edit(content=content, embed=fifthembed)
await asking.edit(content='Now, what would you like the **thumbnail image link** of your embed to be?')
# The sixth round: THUMBNAIL
sixthin = await self.bot.wait_for("message", check=check)
await sixthin.delete() # Delete the sixth input
sixthembed=discord.Embed(title=firstin.content, description=secondin.content, color=readableHex)
sixthembed.set_footer(text=thirdin.content)
sixthembed.set_image(url=fifthin.content)
sixthembed.set_thumbnail(url=sixthin.content)
await theembed.edit(content=content, embed=sixthembed)
await asking.edit(content='Now, what would you like the **author name** of your embed to be?')
# The sevnth round: AUTHOR NAME
seventhin = await self.bot.wait_for("message", check=check)
await seventhin.delete() # Delete the seventh input
seventhembed=discord.Embed(title=firstin.content, description=secondin.content, color=readableHex)
seventhembed.set_footer(text=thirdin.content)
seventhembed.set_image(url=fifthin.content)
seventhembed.set_thumbnail(url=sixthin.content)
seventhembed.set_author(name=seventhin.content)
await theembed.edit(content=content, embed=seventhembed)
await asking.edit(content='Almost done! What would you like the **author icon link** of your embed to be? You can also mention someone or yourself to use their avatar.')
# The eighth round: AUTHOR ICON
eighthin = await self.bot.wait_for("message", check=check)
await eighthin.delete() # Delete the eighth input
if (eighthin.mentions.__len__()>0):
for user in eighthin.mentions:
eighthinavatar = user.avatar_url
else: eighthinavatar = eighthin.content
eighthembed=discord.Embed(title=firstin.content, description=secondin.content, color=readableHex)
eighthembed.set_footer(text=thirdin.content)
eighthembed.set_image(url=fifthin.content)
eighthembed.set_thumbnail(url=sixthin.content)
eighthembed.set_author(name=seventhin.content, icon_url=eighthinavatar)
await theembed.edit(content=content, embed=eighthembed)
await asking.edit(content='Done! Now please mention the channels you would like to send your embed to!')
# The ninth round: CHANNELS
ninthin = await self.bot.wait_for("message", check=check)
if (ninthin.channel_mentions.__len__()>0):
for channel in ninthin.channel_mentions:
await channel.send(content=content, embed=eighthembed)
await ninthin.add_reaction(check_mark)
@build.error
async def build_error(self, ctx, error):
if isinstance(error, commands.errors.CommandInvokeError):
await ctx.send(f'{x_mark} The embed has been terminated, you will have to start over. This was either due to cancellation or an incorrect argument.')
Есть ли способ сделать это? Спасибо.
Вы можете создать пользовательскую ошибку самостоятельно, CommandInvokeError
будет вызываться каждый раз, когда что-то не получается в самой команде, не лучший вариант imo, вот как:
class CancelledCommand(commands.CheckFailure):
pass
# Somewhere (in the check func)
raise CancelledCommand('Command has been cancelled')
# In the error handler
if isinstance(error, CancelledCommand):
...
Кроме того, 4 вещи о функции проверки
str.lower()
это метод, а не атрибут, поэтому вам нужно его вызвать.m.content
никогда не будет None
.m.channel == m.channel
вообще не имеет смысла, я думаю, вы имели в виду m.channel == ctx.channel
m.author == ctx.author
Вот проверка, улучшенная:
def check(m):
if m.channel == ctx.channel and m.author == ctx.author:
if m.content.lower() == 'finish':
raise CancelledCommand('Command has been cancelled')
return True
return False