python-3.x Discord bot离线并停止响应

pgky5nke  于 2023-06-07  发布在  Python
关注(0)|答案(1)|浏览(138)

我正在使用Pycord library来开发我的discord bot。我使用的是asyncpg,所以我不使用常规的bot.run(),因为它控制了一个循环,我不能正确地执行数据库查询,它们都给予任务已经在进行中类的错误。
也许我的机器人启动的实现有问题,但前5-10分钟机器人工作正常,响应命令并执行一切正常。后来,机器人离线,我只得到on_ready()事件每10分钟触发一次,on_connect()没有触发(随附日志截图)
在**机器人准备好之后!**消息机器人在线2-3分钟,然后离线。

下面是整个main.py脚本,只需向下滚动到main()函数。在这里留下了事件齿轮,以防我搞砸了一些事件,问题就在那里。

import asyncio
import os
import sys

import discord
from database import Database
from embeds import DefaultEmbed, LinkEmbed
from environ_loader import load_env
from logger import Log
from owner_commands import OwnerCog
from twitch import TwitchRequests
from ui import LinkView

class EventCog(discord.Cog):
    def __init__(self, bot):
        self.bot: discord.Bot = bot
        self.db: Database = None

    @discord.Cog.listener()
    async def on_ready(self):
        self.db: Database = self.bot.db
        Log.success("Bot is ready!")

    @discord.Cog.listener()
    async def on_connect(self):
        await self.bot.sync_commands()
        Log.info("Connected to the servers")

    @discord.Cog.listener()
    async def on_guild_join(self, guild: discord.Guild):
        channel = guild.system_channel
        if channel:
            channel = channel.id
        await self.db.add_guild(guild.id, channel)

    @discord.Cog.listener()
    async def on_guild_remove(self, guild: discord.Guild):
        print(f"Should delete {guild.id}")
        print(await self.db.remove_guild(guild.id))

    async def setup_hook(self):
        bot.db = await Database.connect()

perms = discord.Permissions()
intents = discord.Intents()
perms.manage_roles = True
intents.guilds = True
bot = discord.Bot(permissions=perms, intents=intents, debug_guilds=[696434683730329713])

@bot.slash_command(description="For sure!")
async def link(
    ctx: discord.ApplicationContext,
    twitch_url: discord.Option(str, "Enter the twitch streamer link")
):
    try:
        data = await TwitchRequests.getChannelInfo(twitch_url)
    except Exception as e:
        Log.failure(str(e))
    else:
        await ctx.respond(embed=LinkEmbed(
            twitch_name=data["login"],
            twitch_description=data["description"],
            twitch_thumbnail=data["profile_image_url"],
            creation_date=data["created_at"],
            is_partner=data["broadcaster_type"] == "partner"
        ), view=LinkView())

async def main():
    events = EventCog(bot)
    ownerCommands = OwnerCog(bot)
    bot.add_cog(events)
    bot.add_cog(ownerCommands)

    await bot.login(os.getenv("BOT_TOKEN"))
    await bot.application_info()
    DefaultEmbed.bot_name = bot.user.name
    DefaultEmbed.bot_thumnail_url = bot.user.avatar.url
    await events.setup_hook()
    await bot.connect()

if __name__ == "__main__":
    load_env()
    TwitchRequests.init()
    if os.name == "nt":
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

    Log.info("Launching discord bot")
    try:
        asyncio.run(main())
        print("COMPLETED")
    finally:
        if sys.exc_info()[0] is None:
            Log.info("Bot offline")

更新

即使我说我不能使用常规的bot.run(),我测试了它,它很好,它没有断开,我想答案在于bot.run()的实现。我在main()协程中做错了一些事情。下一个是找出我到底做错了什么。

knpiaxh1

knpiaxh11#

问题解决!

Bot继承自Client,它在init方法中接受loop。如果没有通过,它将创建一个新的事件循环,这将以某种方式干扰我的代码片段,并创建那些烦人的周期性连接/断开。
因此,解决方案是在bot初始化之前创建一个循环,并在discord.Bot()构造函数中传递当前循环,如下所示:

discord.Bot(permissions=perms, intents=intents, debug_guilds=[...], loop=loop)
附言:

它还解决了斜杠命令中自动完成的问题。之前我什么都做不了,因为它总是说执行命令的bot循环和循环是不同的。现在它工作得非常好,甚至更好!=)

相关问题