@client.event # https://discordpy.readthedocs.io/en/stable/api.html#discord.Client.event
async def on_voice_state_update(member, before, after): # https://discordpy.readthedocs.io/en/stable/api.html#discord.on_voice_state_update
if not before.channel and after.channel: # https://discordpy.readthedocs.io/en/stable/api.html#discord.VoiceState
await member.add_roles(member.guild.get_role(748879395706999708), reason="Voice role")
# https://discordpy.readthedocs.io/en/stable/api.html#discord.Member.add_roles
# https://discordpy.readthedocs.io/en/stable/api.html#discord.Guild.get_role
Counter
из стандартной библиотеки collections
: https://docs.python.org/3/library/collections.html...from collections import Counter
...
msg_count = Counter()
@client.event
async def on_message(msg):
if msg.author == client.user:
return
global msg_count
msg_count[msg.author.id] += 1
print(f"Message by {msg.author}: {msg.content}")
...
self
у событий есть только в модулях (cogs). И представляет собой сам модуль if Y > N: ...
выполняется только один раз - при запуске файла. Необходимо сделать чтобы оно либо менялось при обновлении (получении/удалении реакции), либо непосредственно перед выводом результата pass_context
не существует в текущей версии discord.py. Контекст передаётся в функцию команды первым аргументом всегда (за исключением момента с нахождением команды в вышеупомянутом "модуле") voting_message = None
@Bot.command()
@commands.has_permissions(administrator=True)
async def startvote(ctx):
embed = discord.Embed(...) # embed goes here
voting_message = await ctx.send(embed=embed)
@Bot.command()
@commands.has_permissions(administrator=True)
async def endvote(ctx):
msg = await bot.get_channel(voting_message.channel.id).fetch_message(voting_message.id)
y = discord.utils.get(msg.reactions, emoji="\N{WHITE HEAVY CHECK MARK}").count
n = discord.utils.get(msg.reactions, emoji="\N{CROSS MARK}").count
if y>n:
result = "Принято"
elif y==n:
result = "Отказано (да = нет)"
else:
result = "Отказано"
emb = discord.Embed(title=f'Окончено голосование.', description = 'Результат: ' + result, colour=discord.Color.purple())
return await ctx.send(embed=emb) # **Возвращаем** сообщение после отправки.
y, n = 0, 0
@commands.command()
async def role(ctx):
role = ctx.bot.get_role(719997201283022879) # Получаем объект роли по ID
if role in ctx.author.roles:
await ctx.send("\N{WHITE HEAVY CHECK MARK}"} # ✅
else:
await ctx.send("\N{CROSS MARK}") # ❌
[p]
- префикс указанный для вашего бота[p]вип
- вернет ошибку[p]вип DiscordTag#0000
- не вернет, в случае если пользователь с тегом DiscordTag#0000 существует на сервереpass_context=True
- устаревший кусок кода, на текущей версии Discord.py такого аргумента у конструктора команд нет, Context передаётся в команду всегдаawait ctx.channel.purge(limit = 1)
- я так предполагаю, этот участок кода вами используется для удаления сообщения с командой. Если это так, рекомендую заменить его на await ctx.message.delete()
во избежание (возможного) "racing condition"bool(var)
).WHITELIST = [990298932007060792]
@bot.check_once()
def whitelist(ctx):
print(f"Check is triggered: {ctx.author} executed {ctx.command}")
return ctx.author.id in WHITELIST # Если ID пользователя в указанном выше списке - вернет True
# В противном случае, результат будет оцениваться как False (функция без указания return возвращает None, а bool(None) == False
@commands.has_permissions(administrator = True)
@client.command()
async def unban(ctx, *):
await ctx.message.delete() # Для удаления сообщения с командой, если в оригинале подразумевалось это
banned_users = await ctx.guild.bans()
for ban_entry in banned_users:
user = ban_entry.user
await ctx.guild.unban(user)
await ctx.send(f"Добро пожаловать. Снова. {user.mention}")
await user.send("Божество услышало твой зов, теперь снова можешь вернуться :3")
@commands.command()
async def clear(ctx, user: discord.Member):
await ctx.channel.purge(limit=None, check=lambda m: m.author==user)
import youtube_dl
ydl_opts = {}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download(['https://vk.com/video-30316056_456326877'])
# [vk] -30316056_456326877: Downloading JSON metadata
# [vk] -30316056_456326877: Downloading m3u8 information
# [hlsnative] Downloading m3u8 manifest
# [hlsnative] Total fragments: 2
# [download] Destination: webm--30316056_456326877.mp4
# [download] 100% of 7.31MiB in 00:01
# [ffmpeg] Fixing malformed AAC bitstream in "webm--30316056_456326877.mp4"
# 0
discord.ext.commands
первым аргументом в команду всегда передает commands.Context.users
глобальной.os.chdir(r'D:\Sublime Text 3\testbot-master')
:users = {}
@bot.command()
async def Rank(ctx, user: discord.Member):
experience = users[str(user.id)]['experience']
lvl_start = users[str(user.id)]['level']
lvl_end = int(experience ** (1/50))
await ctx.send(':thumbsup: {}, Ваш уровень: {} :thumbsup:'.format(user.mention, lvl_end))
users[str(user.id)]['level'] = lvl_end
!Rank
вызовет в данном случае ошибку!Rank @DiscordTag#0000
- нет@bot.command()
async def Rank(ctx, user: discord.Member = None):
if not user:
user = ctx.author
...
pass_context
у команд нет, аргумент контекста передается первым автоматически всегдаfrom discord.ext.commands import Bot
- неиспользуемый импорт в этом коде KeyError
означает что указанного ключа в указанном словаре не существует.Что делать?
async def add_coins(users, user, coin):
if str(user.id) not in users:
users[str(user.id)]['coins'] = 0
users[str(user.id)]['coins'] += coin
.addField("Field name", "<@&ROLEID>"
).<@80351110224678912>
если пользователь не имеет установленного "серверного" никнейма, или <@!80351110224678912>
, если никнейм установлен (по сути, не имеет никакой разницы на практике)embed_obj = discord.Embed(description = "текст")
# или
embed_obj = discord.Embed()
embed_obj.description = "текст"