我正在使用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()
协程中做错了一些事情。下一个是找出我到底做错了什么。
1条答案
按热度按时间knpiaxh11#
问题解决!
Bot
继承自Client
,它在init方法中接受loop
。如果没有通过,它将创建一个新的事件循环,这将以某种方式干扰我的代码片段,并创建那些烦人的周期性连接/断开。因此,解决方案是在bot初始化之前创建一个循环,并在
discord.Bot()
构造函数中传递当前循环,如下所示:附言:
它还解决了斜杠命令中自动完成的问题。之前我什么都做不了,因为它总是说执行命令的bot循环和循环是不同的。现在它工作得非常好,甚至更好!=)