@bot.group()
async def clear(ctx):
"""Строка помощи к [p]clear"""
...
@clear.command(name="all")
async def _all(ctx):
"""Строка помощи для [p]clear all"""
...
arg
у вас не имеет стандартного значения. Аргументы без стандартного значения считаются обязательными аргументами.@bot.command() # pass_context НЕ существует в текущей версии discord.py: https://discordpy.readthedocs.io/en/v1.4.1/migrating.html#context-changes
async def help(ctx, arg = None):
emb = discord.Embed(title = 'Помощь', colour = 0x2e2d2d)
if arg == 'poll':
emb.add_field(name = f"{ctx.prefix}poll", value = f"Использовать:\nder poll (название голосования), (первый параметр), (второй параметр), (и так до 9 раз)\nПример создания голосования:\npoll test, 1, 2")
await ctx.send(embed = emb)
else:
emb.add_field(name = f"{ctx.prefix}poll", value = f"Создание голосовния.")
await ctx.send(embed = emb)
from typing import Optional
@commands.command()
async def cmd(ctx, arg: Optional[str]): ...
guild
не определена. В данном случае Вы, скорее всего, хотите получить её из контекста - ctx.guildGuild.voice_channels
и Guild.text_channels
- "списки" (list) с каналами соответствующего типа. Списки не имеют атрибута set_permissions
. Данный атрибут есть у каналов в списке. Для установки прав для каждого канала нужно данный список итерировать. @client.command()
async def set_permissions(сtx, role: discord.Role):
for textchannel in ctx.guild.text_channels:
await alltext.set_permissions(
role,
read_messages=True,
send_messages=True,
manage_channels=True,
manage_roles=True,
)
for voicechannel in ctx.guild.voice_channels:
await allvoice.set_permissions(
role, connect=True, manage_channels=True, manage_roles=True
)
await ctx.send(
f"{ctx.author.mention}, вы успешно установили {role.mention} права доступа во всех текстовых/голосовых каналах"
)
if message.guild.id != 282480459897027773:
return
Message.reactions
. discord.Reaction
- тип возвращаемых объектов в reactions.@bot.command()
async def start(ctx):
mess = await channel.send('Набор в игру')
await asyncio.sleep(10)
mess = await ctx.channel.fetch_message(mess.id)
if yes_react := discord.utils.get(mess.reactions, emoji=ctx.guild.get_emoji(471483388532742130)):
async for user in yes_react.users:
print(str(user)) # выведет всех пользователей поставивших реакцию в консоль
bot.event
используется только для событий.@bot.command()
или @commands.command()
в модулях.from datetime import date
import discord
from datetime import date
@bot.command()
async def bdays4(ctx):
cur_year = date.today().year
bdays = {
"Kenshi": date(day=12, month=8, year=1997),
"Broody": date(day=11, month=11, year=1009),
"Melanie": date(day=22, month=1, year=1941),
"Blueface Baby": date(day=18, month=8, year=2020),
}
for bday_name, date in bdays.items():
bday = date.update(year=cur_year)
if bday == date.today():
await ctx.send(
embed=discord.Embed(
description=f"Happy birthday {bday_name}",
colour=discord.Color.green(),
)
)
on_error_command(context, error)
: https://discordpy.readthedocs.io/en/v1.4.1/ext/com...from discord.ext import commands
from contextlib import suppress
class MyBot(commands.Bot):
async def on_command_error(self, ctx, error):
if isinstance(error, commands.BadArgument):
await ctx.send(f"Неверный аргумент: {error.message}")
else:
await super().on_command_error(ctx, error) # вызывает изначальное поведение on_error_message
bot = MyBot(command_prefix="!")
from discord.ext import commands
from contextlib import suppress
bot = commands.Bot(command_prefix="!")
@bot.event
async def on_command_error(ctx, error):
if isinstance(error, commands.BadArgument):
await ctx.send(f"Неверный аргумент: {error.message}")
.post
, рискну предположить что Disc
- экземпляр объекта типа aiohttp.ClientSession
. Он не знает что такое дискорд.import discord
import aiohttp
session = aiohttp.ClientSession()
# Discord поддерживает только markdown для форматирования. html-теги (<i> и прочие) будут отображаться напрямую
embed_obj = discord.Embed(
title="*Заголовок*", colour=0x21D3CD, url="https://example.com"
) # Цвет в HEX более читаемый
embed_obj.set_image(url="https://via.placeholder.com/140x100")
embed_obj.set_thumbnail(url="https://via.placeholder.com/140x100")
embed_obj.set_footer(text="*Текст*", icon_url="https://via.placeholder.com/140x100")
embed_obj.set_author(
name="*Текст*",
url="https://example.com",
icon_url="https://via.placeholder.com/140x100",
)
embed_obj.add_field(
name="*Текст*", value="\N{Zero Width Space}"
) # Значение поля не может быть пустым, такой embed дискорд отклонит. Используем визуально пустой символ для этого.
await session.post(
"https://discord.com/api/webhooks/%WEBHOOK_ID%/%WEBHOOK_TOKEN",
json={"embeds": [embed_obj.to_dict()]},
)
import aiohttp
import discord
session = aiohttp.ClientSession()
webhook = discord.Webhook.from_url(
"https://discord.com/api/webhooks/%WEBHOOK_ID%/%WEBHOOK_TOKEN",
adapter=discord.AsyncWebhookAdapter(session),
)
embed_obj = ...
await webhook.send(embed=embed_obj)
on_guild_join
передаётся аргумент guild
, который и является сервером, к которому присоединился бот.import logging
@listener # client.event / commands.Cog.listener / etc...
async def on_guild_join(guild):
logging.info(f"Joined guild {guild.name} ({guild.id})"
def func(a, b: int = 0, c)
- не работает, так как a
, b
и c
являются порядковым аргументом.def func(a, b: int = 0, c = 0)
- работаетfrom typing import Optional
...
@commands.command()
async def cmd(ctx, member: Optional[discord.Member], count: int): ...
delete_after
функции send
.@client.command(aliases = ['очистить', 'клеар', 'clr' ,'клр'])
@commands.has_permissions(administrator = True)
async def clear( ctx, amount : int):
await ctx.message.delete()
await ctx.channel.purge(limit = amount)
await ctx.send(embed = discord.Embed(description = f':white_check_mark: удалено {amount} сообщений(я)'), delete_after=5)
discord.utils.get
вы получаете канал того сервера, в котором было написано сообщение.GLOBAL_CHAT = 'глобальный-чат' # PEP8: Названия констант пишутся капсом
@client.event
async def on_message(message):
channel = discord.utils.get(message.guild.text_channels, name=GLOBAL_CHAT)
if message.author.id == client.user.id:
return # return предотвратит выполнение следующего кода
if message.channel.id != channel.id:
return
await message.delete() # удаляем сообщение один раз
for guild in client.guilds:
if channel := discord.utils.get(guild.text_channels, name=GLOBAL_CHAT):
# py3.8: walrus operator ("моржовый" оператор)
# равносильно следующему:
# channel = discord.utils.get(guild.text_channels, name=GLOBAL_CHAT)
# if channel: ...
try:
await channel.send('**{0.author}:** {0.content}'.format(message))
except discord.Forbidden:
print(f"Невозможно отправить сообщение на сервер {guild.name}: Недостаточно прав")
except discord.HTTPException as e:
print(f"Невозможно отправить сообщение на сервер {guild.name}: {e}")
bot.remove_command("help")
@bot.group(invoke_without_command=True)
async def help(ctx, ...):
... # вручную построенная/собирающая команда help.
@help.command()
async def islam(ctx, ...):
... # подкоманда help
@bot.command()
async def islam(ctx):
"""Описание команды"""
...
@bot.command(
help="Данный текст будет использоваться в полноразмерной помощи (help islam)",
brief="Данный текст будет отображаться в help рядом с командой",
usage="Данный текст будет отображаться вместо автоматического построенного текста для аргументов (таких как <arg> [arg] и т.д.)"
)
async def islam(ctx):
...
@bot.command()
async def report(ctx, user: discord.Membmer, *, reason: str): # первый kwarg используется как "собирающий" аргумент
# https://discordpy.readthedocs.io/en/v1.3.4/ext/commands/commands.html#keyword-only-arguments
...
[p]report User#0000 Нарушение правила 42
from asyncio import TimeoutError as AsyncTimeoutError
@bot.command()
async def report(ctx):
...
try:
member = await bot.wait_for("message", check=lambda m: m.author == ctx.author, timeout = 60) # Базовая проверка - будет ловить сообщения от пользователя запустившего команду везде.
except AsyncTimeoutError:
await ctx.send("Вы уснули, я ушёл")
return
# На данный момент переменная "member" является лишь строкой, и не факт что это реальный пользователь
# Используем конвертер для перевода из строки в пользователя
# https://discordpy.readthedocs.io/en/v1.3.4/ext/commands/api.html#discord.ext.commands.MemberConverter
try:
member = commands.MemberConverter().convert(ctx, member)
except commands.BadArgument:
await ctx.send("Это не пользователь, кого вы пытаетесь ~~на...~~ обмануть")
return
# и тоже самое для причины