message.author.bot
: https://discordpy.readthedocs.io/en/stable/api.htm... As bots grow and are added to an increasing number of guilds, some developers may find it necessary to break or split portions of their bots operations into separate logical processes. As such, Discord gateways implement a method of user-controlled guild sharding which allows for splitting events across a number of gateway connections. Guild sharding is entirely user controlled, and requires no state-sharing between separate connections to operate
В то время как боты растут, и растёт количество серверов, некоторые разработчики могут посчитать нужным разбавлять или разделять операции ботов на несколько логических процессов. Поэтому, Discord gateway (то, к чему бот подключается через websockets для прослушивания событий, и контроля статуса) представляют метод разделения серверов пользователем, который допускает разделение событий на несколько подключений к gateway. Разделение серверов полностью контроллируется пользователем, и не требует общего доступа меж разных подключений для управления.
random_strings = ["abc", "bcd", "etc"] # список строк, из файла/откуда угодно. Для чтения больших файлов может пригодиться https://github.com/Tinche/aiofiles
@tasks.loop(seconds=1)
async def update_text():
text_variable = random.choice(random_strings) # если список большой, возможно может понадобиться run_in_executor, но я в этом не уверен
async def give_me_not_in_roles(members, roles): # members: List[discord.Member], roles: List[discord.Role]
member = random.choice(members)
if any(role in member.roles for role in roles):
return await give_me_not_in_roles(members, roles)
return member
@client.command(name="random")
@commands.has_permissions(administrator = True)
async def rnd(ctx, members: commands.Greedy[discord.Member], *roles: discord.Role): # https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.Greedy
m = await give_me_not_in_roles(members, roles)
await ctx.send(f"{m.mention} won a whole nothing!")
@client.command(name="random")
@commands.has_permissions(administrator = True)
async def rnd(ctx, members: commands.Greedy[discord.Member], *roles: discord.Role): # https://discordpy.readthedocs.io/en/stable/ext/commands/api.html#discord.ext.commands.Greedy
filtered = [m for m in members if not any(m in r.members for r in roles)]
m = random.choice(filtered)
await ctx.send(f"{m.mention} won a whole nothing!")
# В команде:
@commands.command()
async def add_role(ctx, role: discord.Role, member: discord.Member):
# >add_role @rolename @user#0000
# >add_role 525662304373175852 705409329145227030
# >add_role 525662304373175852 @user#0000
# etc...
...
# Вне команды/внутри команды/функции
rolemsg = bot.wait_for("message", ...)
role = await commands.RoleConverter().convert(ctx, rolemsg.content)
members_list = []
строится каждый раз при выполнении функции в вашем случае.members_list
объявить вне функции, но в данном контексте намного проще будет просто тянуть участников голосового канала из самого канала:members = ", ".join(m.name for m in after.channel.members)
after.channel
становится None когда Вы выходите из канала.if voice_channel is not None and channel_category is not None:
if after.channel.id == voice_channel:
if voice_channel and channel_category and after.channel.id == voice_channel:
else:
pass
Python 3.8.1 (tags/v3.8.1:1b293b6, Dec 18 2019, 22:39:24) [MSC v.1916 32 bit (Intel)]
Type 'copyright', 'credits' or 'license' for more information
IPython 7.17.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: def test():
...: for i in range(0, 100):
...: if i%2:
...: 2+2
...: else:
...: pass
...:
In [2]: %timeit test()
14.4 µs ± 559 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [3]: def test():
...: for i in range(0, 100):
...: if i%2:
...: 2+2
...:
In [4]: %timeit test()
13.6 µs ± 435 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
voice_channel_update
в discord.py по умолчанию не существует, и если Вы не вызываете это событие сами, то Вы будете ждать его бесконечно class MyBot(commands.Bot):
async def on_command_error(self, ctx, e):
if isinstance(e, commands.MissingRequiredArgument):
await ctx.send(f"Недостаточно аргументов: {e.param} отсутствует")
else:
super().on_command_error(ctx, e) # вызвываем оригинальный обработчик ошибок команд
headlinesize = headline.getsize(ctx.author.name)
idraw.text((115 + namesize[0] + 2, 64), f'#{tag}', font=sundertext, fill=(63, 68, 71))
intents
в конструктор объекта бота, например:intents = discord.Intents()
intents.members = True
bot = commands.Bot(..., intents=intents)
724322899921600513
существует, например добавив print(role)
guild.get_role(ID)
вместо discord.utils.get
, оно лучше читается Client.wait_for(event, *, check, timeout)
: https://discordpy.readthedocs.io/en/stable/api.htm...def check(message):
return message.author.id == ctx.author.id
try:
m = await bot.wait_for("message", check=check, timeout = 30)
except asyncio.TimeoutError:
pass
async for ... in history(...)
: https://discordpy.readthedocs.io/en/stable/api.htm...counter = 0
async for message in channel.history(limit=200):
if message.author == client.user:
counter += 1
messages = await channel.history(limit=123).flatten()
# messages is now a list of Message...
from datetime import datetime, timedelta
# ...
async for message in channel.history(
limit=None, # If None, retrieves every message in the channel. Note, however, that this would make it a slow operation.
after=datetime.utcnow()-timedelta(hours=2) # If a date is provided it must be a timezone-naive datetime representing UTC time. (https://docs.python.org/3/library/datetime.html#datetime.datetime.utcnow)
):
command_prefix
можно использовать функцию:The command prefix is what the message content must contain initially to have a command invoked. This prefix could either be a string to indicate what the prefix should be, or a callable that takes in the bot as its first parameter and discord.Message as its second parameter and returns the prefix. This is to facilitate “dynamic” command prefixes. This callable can be either a regular function or a coroutine.
SPECIAL_PREFIX = "."
def context_prefix(bot, message):
special_command = bot.get_command("choose")
if any(
message.content.startswith(f"{SPECIAL_PREFIX}{command_string}")
for command_string in [special_command.name, *special_command.aliases]
):
return SPECIAL_PREFIX
return "&"
bot = commands.Bot(command_prefix=context_prefix)
choose
будет вызываться с префиксом .
, в то время как остальные с префиксом &
: client.event
не должен вызываться: https://discordpy.readthedocs.io/en/v1.4.1/api.htm...@client.event # вызов функции-декоратора (скобки) отсуствует
async def on_ready():
print('Ready!')
on_group_*
на клиенте-боте абсолютно бесполезны, так как дискорд не предоставляет возможности добавления ботов в "группы"on_guild_*