Discord bot命令随机停止与python一起工作?

Posted

技术标签:

【中文标题】Discord bot命令随机停止与python一起工作?【英文标题】:Discord bot commands randomly stop working with python? 【发布时间】:2021-11-14 02:37:37 【问题描述】:

我只是在我的 discord bot 中添加了一些额外的代码来播放 youtube 音乐,但随后我运行该 bot,它正常启动并正常工作,但是当我去测试新命令时,没有任何工作,没有错误或其他任何东西,然后我尝试使用 /hello 之类的基本命令,这些命令以前工作正常,但也没有做任何事情。机器人作为管理角色。 我仔细检查了我没有拼写命令错误,但即使我是 on_command_error 函数也应该调用。我也在 /play 命令的开头做了一个打印调试语句,甚至没有被调用,我还没有改变任何重大的东西。有人有什么想法吗?

from discord.ext import commands
from dotenv import load_dotenv
from lxml import html
import youtube_dl
import requests
import random
import discord
import requests
import shutil,os

# Load .env file
load_dotenv()

PREFIX = "/"
bot = commands.Bot(command_prefix=PREFIX)


# EVENTS #
@bot.event
async def on_ready():
    await bot.get_channel(888736019590053898).send(f"We back online! All thanks to *sploosh* :D")

@bot.event
async def on_command_error(ctx, error):
    if isinstance(error, commands.CommandNotFound):
        replies = ["Err is that even a command?", "Can you type bro?", "Yeah... thats not a command buddy.", "Sorry forgot you can't spell"]
        await ctx.send(random.choice(replies))
        
@bot.event
async def on_message(message):
    if str(message.channel) == "images-videos" and message.content != "":
        await message.channel.purge(limit=1)
    

# COMMANDS #
@bot.command()
async def hello(ctx):
    # Get a random fact
    url = 'http://randomfactgenerator.net/'
    page = requests.get(url)
    tree = html.fromstring(page.content)
    hr = str(tree.xpath('/html/body/div/div[4]/div[2]/text()'))
    
    await ctx.reply("**Hello Bozo!**\n" + "*Random Fact : *" + hr[:-9]+"]")
    
@bot.command()
async def randomNum(ctx, start:int = None, end:int = None):
    if(start == None or end == None):
        await ctx.reply("*Check your arguments!*\n```/randomNum START_NUMBER END_NUMBER```")
    else:
        randNum = random.randint(start, end)
        await ctx.reply(f"*randNum*")

@bot.command()
@commands.is_owner()
async def kick(ctx, member:discord.Member = None, *, reason="You smell bozo."):
    if(member == None):
        await ctx.reply("*Check your arguments!*\n```/kick @MEMBER REASON(optional)```")
    elif ctx.author.id in (member.id, bot.user.id):
        await ctx.reply("*You cant kick yourself/me you silly.*")
    else:
        await member.kick(reason=reason)

@bot.command()
@commands.is_owner()
async def ban(ctx, member:discord.Member = None, *, reason="Bye Bye! :D."):
    if(member == None):
        await ctx.reply("*Check your arguments!*\n```/kick @MEMBER REASON(optional)```")
    elif ctx.author.id in (member.id, bot.user.id):
        await ctx.reply("*You cant ban yourself/me you silly.*")
    else:
        await member.ban(reason=reason)
        
@bot.command()
@commands.is_owner()
async def close_bot(ctx):
    replies = ["Well bye!", "Guess I go now?", "Please let me stay..."]
    await ctx.send(random.choice(replies))
    await bot.close()


# YOUTUBE AUDIO PLAYER
@bot.command()
async def play(ctx, url : str):
    print("WORKING")
    if(url == None):
        await ctx.reply("*Check your arguments!*\n```/play VIDEO_URL```")
    else:
        song = os.path.isfile("songs/song.mp3")
        
        try: # Check if song exists if so remove it
            if(song):
                os.remove("songs/song.mp3")
        except PermissionError:
            await ctx.reply("*Wait for current song to end, or use 'stop' command*")
            return
            
        voiceChannel = discord.utils.get(ctx.guild.voice_channels, name="Lounge")
        await voiceChannel.connect()
        voice = discord.utils.get(bot.voice_clients, guild = ctx.guild)
        
        ytdl_opts =  # Some options you need to pass in
            'format': 'bestaudio/best',
            'postprocessors':[
               'key':'FFmpegExtractAudio',
               'preferredcodec': 'mp3',
               'preferredquality': '192' 
            ],
        
        
        with youtube_dl.YoutubeDL(ytdl_opts) as ydl:
            ydl.download(url) # Download the vid
            
        for file in os.listdir("./"): # Change the name and move to songs folder
            if file.endswith(".mp3"):
                os.rename(file, "song.mp3")
                shutil.move("song.mp3", "songs")
        
        voice.play(discord.FFmpegPCMAudio(source="songs/song.mp3")) # Play the song
        
        
        
@bot.command()
async def leave(ctx):
    voice = discord.utils.get(bot.voice_clients, guild = ctx.guild)
    
    if(voice.is_connected()):
        voice.disconnect()
    else:
        await ctx.reply("*How can I leave a voice channel if I'am not connected?*")

@bot.command()
async def pause(ctx):
    voice = discord.utils.get(bot.voice_clients, guild = ctx.guild)

    if(voice.is_playing()):
        voice.pause()
    else:
        await ctx.reply("*Can't pause buddy, nothings playing...*")

@bot.command()
async def resume(ctx):
    voice = discord.utils.get(bot.voice_clients, guild = ctx.guild)

    if(voice.is_paused()):
       voice.resume()
    else:
        await ctx.reply("*Can't resume buddy, audio is already playing*")
        
@bot.command()
async def stop(ctx):
    voice = discord.utils.get(bot.voice_clients, guild = ctx.guild)
    voice.stop()
        
   
if __name__ == "__main__":
    bot.run(os.getenv("BOT_TOKEN"))

【问题讨论】:

这能回答你的问题吗? Why does on_message stop commands from working? 【参考方案1】:

您需要在自定义 on_message 事件中包含 bot.process_commands(message)

@bot.event
async def on_message(message):
    if str(message.channel) == "images-videos" and message.content != "":
        await message.delete()
    await bot.process_commands(message)

我还将message.channel.purge(limit=1) 更改为message.delete(),因为这是删除消息的正确方法

有关为什么需要这样做的更多信息,请参阅the faq

【讨论】:

使用 cogs 时不需要 await bot.process_commands(message) 行,只是为了完整性。 好吧 OP 没有使用齿轮,但是应该注意

以上是关于Discord bot命令随机停止与python一起工作?的主要内容,如果未能解决你的问题,请参考以下文章

Discord Bot w/ Discord.py 跳线

C# Discord Bot 编码:创建一个发送垃圾邮件的命令,然后用另一个命令停止

Discord Bot 使用 python 向一个命令发送多个响应

代码停止执行 Ban discord bot, python

Discord bot setRole 命令只能随机工作

Python Discord Bot 将消息与列表进行比较