Приложение не отвечает discord.py @bot.slash_command
Если использовать команду с несуществующим профилем, бот реагирует правильно, отвечает на команду и никаких проблем нет. Но если ввести команду с настоящим профилем, бот отвечает "Приложение не отвечает", но отправляет нужный embed отдельным сообщением позже. Помогите пожалуйста Вот мой код:
from webserver import keep_alive
from discord.ext import commands
import os
import psutil
import random
import asyncio
import discord
from datetime import datetime
import time
import requests
from bs4 import BeautifulSoup
intents = discord.Intents.all()
bot = commands.Bot(command_prefix='+', intents=intents)
@bot.event
async def on_ready():
print(f'{bot.user} подключен к Discord!')
@bot.slash_command(guild_ids=[432921053493198859, 248124585189310475], description = "отправляет иконку вашего профиля Overwatch 2")
async def icon(ctx, username: str):
username1 = username.replace('#', '-')
url = f"https://overwatch.blizzard.com/ru-ru/career/{username1}"
try:
response = requests.get(url)
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout) as error:
await ctx.send(f"Произошла ошибка подключения: {error}")
return
soup = BeautifulSoup(response.text, 'html.parser')
element = soup.select_one('.Profile-player--portrait')
if element:
link = element['src']
embed = discord.Embed(title=f'Иконка профиля: {username}', color=0x00ff00)
embed.set_image(url=link)
await ctx.send(embed=embed)
else:
await ctx.respond(f"Профиль {username} не найден")
keep_alive()
bot.run(os.getenv("123"))
Ответы (1 шт):
Поскольку дискорд обрабатывает команды интерактивно,

необходимо что-то делать с контекстом выполнения команды.
Например, вы отправляете ответ (await ctx.respond()):
@bot.slash_command(name='test_slash_command', description='Отвечает "Успешный тест!"')
async def __test(ctx):
await ctx.respond('Успешный тест!')
Результат:

Если не сделать что-то с контекстом сразу, то дискорд не дождавшись ответа от бота, выдаст ошибку.
@bot.slash_command(name='test_slash_command', description='Имитирует 5-секундное вычисление и выводит "Команда выполнена!"')
async def __test(ctx):
await asyncio.sleep(5)
await ctx.respond('Команда выполнена!')

Выглядит так, будто при выполнении произошла ошибка, но на деле это просто дискорд не получил ответа от бота в течение первых секунд. Поэтому, если идут какие-то долгие вычисления, дискорд может просто не дождаться ответа и команда не выполнится. В таких случаях контекст стоит либо удалять (await ctx.delete()), либо использовать метод контекста defer().
Из описания следует, что он нужен как раз для таких ситуаций: "Откладывает ответ на взаимодействие. Обычно это используется, когда взаимодействие подтверждено, а дополнительное действие будет выполнено позже."
import asyncio
. . .
@bot.slash_command(name='test_slash_command', description='Имитирует 5-секундное вычисление и выводит "Команда выполнена!"')
async def __test(ctx):
await ctx.defer()
await asyncio.sleep(5)
await ctx.respond('Команда выполнена!')
Результат:

Разумеется, использовать метод await ctx.defer() имеет смысл только если вы собираетесь что-то отвечать на команду. Если же никакого ответа не подразумевается, то лучше просто удалять контекст. Иначе бот просто бесконечно будет "думать" как на скрине выше.