如何在 discord.py 中使用命令时获取输入
How to take an input while using a command in discord.py
所以我想制作一个程序,允许成员在一段时间内担任角色
这是我当前的代码
请注意,感谢@curlybracesenjoyer,我已经找到了解决方案,如果您正在寻找代码,请向下滚动并查看新代码......TY
**OLD CODE**
**FOR NEW CODE PLEASE SEE THE ANSWERS WHERE I HAVE POSTED THE ANSWER MYSELF**
import discord
import os
import time
from discord.ext import commands
from discord.ext.commands import Bot
from discord.utils import get
x=0.0#want to use it for float input
y=0.0#want to covert x from hours to seconds
bot = commands.Bot(command_prefix=";")
@bot.command('role')
@commands.has_permissions(administrator=True) #permissions
async def role(ctx, user : discord.Member, *, role : discord.Role):
if role.position > ctx.author.top_role.position: #if the role is above users top role it sends error
return await ctx.send('**:x: | That role is above your top role!**')
await ctx.channel.send('Enter time in hours')
#problem
#i want to take in x as float input
#and i want to convert x into seconds and store into y
await user.add_roles(role) #adds role if not already has it
await ctx.send(f"Added {role} to {user.mention}")
time.sleep()#i want to use y here
await user.remove_roles(role) #removes the role if user already has
await ctx.send(f"Removed {role} from {user.mention}")
bot.run(os.getenv('TOKEN'))
在继续回答之前,我想提几点:
- 我们可以使用附加到
bot
(实例)的变量,因此我们不必使用 global
,这被认为是一种不好的做法
- 我们应该使用比
x
和 y
更冗长的变量名
- 仅仅有一个
sleep
是非常糟糕的,因为它阻碍了 bot 的整个功能
在异步编程中,阻塞调用本质上是函数中所有不等待的部分。但是,不要绝望,因为并非所有形式的阻塞都是不好的!使用阻塞调用是不可避免的,但你必须努力确保你不会过度阻塞函数。请记住,如果您阻塞的时间太长,那么您的机器人将冻结,因为此时它还没有停止函数的执行来做其他事情。
阻塞时间过长的一个常见原因是 time.sleep()
。不要那样做。 Use asyncio.sleep()
代替。类似于这个例子:
# bad
time.sleep(10)
# good
await asyncio.sleep(10)
只是等待时间结束也是一个坏主意,因为它的波动性很大,比如说,如果你的机器人离线,那么用户就可以永远保持这个角色。
别太担心,你可以稍后修复其中的一些问题。
答案:
要从调用该命令的同一用户那里获取浮点数,必须这样做:
@bot.command()
async def foo(ctx):
def check(m):
if m.author == ctx.author and m.channel == ctx.channel:
try:
float(m.content)
return True
except ValueError:
return False
return False
await ctx.send("Tell me the hours")
res = await bot.wait_for("message", check=check)
bot.seconds = float(res.content) * 3600
await ctx.send(f"The seconds are {bot.seconds}")
# This bot.seconds can be accessed in everywhere
result
感谢@curlybracketenjoyer 在这方面的帮助
对于那些将来看到这个的人,我解决了我的问题,这是我的代码
import discord
import os
import asyncio
from discord.ext import commands
from discord.ext.commands import Bot
from discord.utils import get
bot = commands.Bot(command_prefix=";")
@bot.command()
async def permit(ctx, user : discord.Member):
def check(m):
if m.author == ctx.author and m.channel == ctx.channel:
try:
float(m.content)
return True
except ValueError:
return False
return False
permitRole=ctx.guild.get_role(941361821816860732)#the id of particular role you want to give
await ctx.send("Tell me the hours")
res = await bot.wait_for("message", check=check)
bot.seconds = float(res.content) * 3600
await user.add_roles(permitRole)#giving the role to mentioned user
await ctx.send(f"Added role to {user.mention}")#tells the user that the role is given
await ctx.send(f"The time is {bot.seconds} seconds")#tells the time period of the role to the user
toime=float(res.content)#gets the message input as float variable
toimefoinal=toime*3600 #converts to seconds
await asyncio.sleep(toimefoinal)#sleeps the command
await ctx.send("TIME UP")#this is after the time period
await user.remove_roles(permitRole)#removes the role
await ctx.send("TY FOR CHOOSING THIS SERVER!")
bot.run(os.getenv('TOKEN'))#bot token
result
注意:无需担心角色会在分配的时间后被收回,这是经过充分测试的
再次感谢@curlybracesenjoyer
所以我想制作一个程序,允许成员在一段时间内担任角色
这是我当前的代码
请注意,感谢@curlybracesenjoyer,我已经找到了解决方案,如果您正在寻找代码,请向下滚动并查看新代码......TY
**OLD CODE**
**FOR NEW CODE PLEASE SEE THE ANSWERS WHERE I HAVE POSTED THE ANSWER MYSELF**
import discord
import os
import time
from discord.ext import commands
from discord.ext.commands import Bot
from discord.utils import get
x=0.0#want to use it for float input
y=0.0#want to covert x from hours to seconds
bot = commands.Bot(command_prefix=";")
@bot.command('role')
@commands.has_permissions(administrator=True) #permissions
async def role(ctx, user : discord.Member, *, role : discord.Role):
if role.position > ctx.author.top_role.position: #if the role is above users top role it sends error
return await ctx.send('**:x: | That role is above your top role!**')
await ctx.channel.send('Enter time in hours')
#problem
#i want to take in x as float input
#and i want to convert x into seconds and store into y
await user.add_roles(role) #adds role if not already has it
await ctx.send(f"Added {role} to {user.mention}")
time.sleep()#i want to use y here
await user.remove_roles(role) #removes the role if user already has
await ctx.send(f"Removed {role} from {user.mention}")
bot.run(os.getenv('TOKEN'))
在继续回答之前,我想提几点:
- 我们可以使用附加到
bot
(实例)的变量,因此我们不必使用global
,这被认为是一种不好的做法 - 我们应该使用比
x
和y
更冗长的变量名
- 仅仅有一个
sleep
是非常糟糕的,因为它阻碍了 bot 的整个功能
在异步编程中,阻塞调用本质上是函数中所有不等待的部分。但是,不要绝望,因为并非所有形式的阻塞都是不好的!使用阻塞调用是不可避免的,但你必须努力确保你不会过度阻塞函数。请记住,如果您阻塞的时间太长,那么您的机器人将冻结,因为此时它还没有停止函数的执行来做其他事情。
阻塞时间过长的一个常见原因是 time.sleep()
。不要那样做。 Use asyncio.sleep()
代替。类似于这个例子:
# bad
time.sleep(10)
# good
await asyncio.sleep(10)
只是等待时间结束也是一个坏主意,因为它的波动性很大,比如说,如果你的机器人离线,那么用户就可以永远保持这个角色。
别太担心,你可以稍后修复其中的一些问题。
答案:
要从调用该命令的同一用户那里获取浮点数,必须这样做:
@bot.command()
async def foo(ctx):
def check(m):
if m.author == ctx.author and m.channel == ctx.channel:
try:
float(m.content)
return True
except ValueError:
return False
return False
await ctx.send("Tell me the hours")
res = await bot.wait_for("message", check=check)
bot.seconds = float(res.content) * 3600
await ctx.send(f"The seconds are {bot.seconds}")
# This bot.seconds can be accessed in everywhere
result
感谢@curlybracketenjoyer 在这方面的帮助
对于那些将来看到这个的人,我解决了我的问题,这是我的代码
import discord
import os
import asyncio
from discord.ext import commands
from discord.ext.commands import Bot
from discord.utils import get
bot = commands.Bot(command_prefix=";")
@bot.command()
async def permit(ctx, user : discord.Member):
def check(m):
if m.author == ctx.author and m.channel == ctx.channel:
try:
float(m.content)
return True
except ValueError:
return False
return False
permitRole=ctx.guild.get_role(941361821816860732)#the id of particular role you want to give
await ctx.send("Tell me the hours")
res = await bot.wait_for("message", check=check)
bot.seconds = float(res.content) * 3600
await user.add_roles(permitRole)#giving the role to mentioned user
await ctx.send(f"Added role to {user.mention}")#tells the user that the role is given
await ctx.send(f"The time is {bot.seconds} seconds")#tells the time period of the role to the user
toime=float(res.content)#gets the message input as float variable
toimefoinal=toime*3600 #converts to seconds
await asyncio.sleep(toimefoinal)#sleeps the command
await ctx.send("TIME UP")#this is after the time period
await user.remove_roles(permitRole)#removes the role
await ctx.send("TY FOR CHOOSING THIS SERVER!")
bot.run(os.getenv('TOKEN'))#bot token
result 注意:无需担心角色会在分配的时间后被收回,这是经过充分测试的 再次感谢@curlybracesenjoyer