关闭 Discord 机器人连接而不终止命令行 (discord.py)

Posted

技术标签:

【中文标题】关闭 Discord 机器人连接而不终止命令行 (discord.py)【英文标题】:Closing Discord bot connection without terminating command line (discord.py) 【发布时间】:2021-03-27 19:52:28 【问题描述】:

目的: 在不中断其他命令的情况下添加更多命令

我一直在寻找一种在不中断我的机器人流程的情况下推出更新的方法,因为它有一些 asyncio 函数会在函数被调用后执行一段时间

我尝试过: 等待客户端.logout()

上面会注销机器人,但也会关闭命令行。我在 discord.py 文档中找到了这个。

我运行的是 Windows 10,Python 版本为 3.9

任何帮助将不胜感激。提前致谢。

【问题讨论】:

1.这之后你想做什么?因为实际上不可能关闭连接然后让窗口打开 2. 你能给我们你想要的那部分代码吗? 你为什么想要那个?这样做的目的是什么? 如果您感到困惑,我正在尝试为机器人发出重新启动命令。 如果您想在不中断机器人流程的情况下推出更新,请考虑研究 cogs 和动态代码加载。您可以将函数分组到一个类(cog)中,并使用像 !reload COGNAME 这样的命令来使用更新的代码重新加载该 cog。您甚至不需要触摸命令或中断连接。 【参考方案1】:

例如,在同一目录中创建一个名为 startup.py 的新 python 文件。在此文件中执行以下操作:

import os
import time

time.sleep(5)
os.system('python YOUR_BOTS_FILE_NAME.py')

然后在您的机器人代码所在的文件中添加一个新命令,我们将调用该命令重新启动,例如:

import discord
from discord.ext import commands
import os

@client.command()
@commands.is_owner()
async def restart(ctx):
    os.system('python startup.py')
    exit()

在 startup.py 文件中,os 等待 5 秒让您的机器人文件关闭,然后再将其打开。机器人文件中的重启命令会启动启动文件,然后自行关闭。

@commands.is_owner()

确保消息的作者是您,这样人们就不会重新启动您的机器人。

【讨论】:

【参考方案2】:

我自己正在开发一个机器人,并且我自己做了一个shutdown 命令,它在不使用终端的情况下关闭了机器人。

我会先添加代码,然后再解释一下。

代码:

myid = <my discord account ID>

@MyBot.command()
async def shutdown(ctx):
    if ctx.author.id == myid:
        shutdown_embed = discord.Embed(title='Bot Update', description='I am now shutting down. See you later. BYE! :slight_smile:', color=0x8ee6dd)
        await ctx.channel.send(embed=shutdown_embed)
        await MyBot.logout()
    if ctx.author.id != myid:
        errorperm_embed = discord.Embed(title='Access Denied!', description='This command is `OWNER` only. You are not allowed to use this. Try not to execute it another time.', color=0xFF0000)
        errorperm_embed.set_footer(text=ctx.author)
        await ctx.channel.send(embed=errorperm_embed, delete_after=10.0)

我没有添加任何has_permissions,因为当我使用我的不和谐 ID 来限制其使用时,我不需要它。

解释:

我定义了一个变量,myid,它等于我的 discord 帐户 ID。 在此处查看如何获取用户 ID:

https://support.discord.com/hc/en-us/articles/206346498-Where-can-I-find-my-User-Server-Message-ID-

我添加了一个条件,如果使用此命令的用户的 ID 等于myid,或者不是。如果它等于我的帐户 ID,那么它将关闭机器人,否则它将向用户显示错误。

我只是使用了await MyBot.logout(),它将您注销并断开连接。

【讨论】:

【参考方案3】:

您可以将代码放在while True 循环中。

while True:
    client = commands.Bot(command_prefix='!')

    async def restart(ctx):
        await client.logout()

    client.run('token')

【讨论】:

【参考方案4】:

您可以用相同的进程替换当前进程,重新开始。您必须事先刷新缓冲区并关闭文件指针,但这很容易做到:

import os
import sys
from typing import List

def restart(filepointers: List):
    # this cleanup part is optional, don't need it if your bot is ephemeral

    # flush output buffers
    sys.stdout.flush()
    sys.stderr.flush()

    # flush and close filepointers
    for fp in filepointers:
         os.fsync(fp)
         fp.close()

    # replace current process
    os.execl(*sys.argv)

然后像你一样(从同一个文件)用你的机器人调用这个函数。

【讨论】:

【参考方案5】:

如果你想更新你的代码,你必须重新启动程序。

import os
path = "your .py file path"

@client.command(name="restart")
async def restart_command(ctx):
    await client.close()
    os.system("python " + path)

【讨论】:

【参考方案6】:

如果您不想终止当前进程而只想热重载不同的功能,您可能需要查看discord.py's extensions feature。使用扩展和 cog 将允许您在不停止机器人的情况下启用/禁用/重新加载某些功能(这应该保持任务运行)。这也是热加载的内置方法。

Extensions 和cogs 通常一起使用(尽管它们并非必须如此)。您可以为要一起重新加载的每组类似命令创建文件。

以下代码示例应集成到您的设置中。您可能还想添加错误处理和输入检查,但它应该让您了解正在发生的事情。有关详细说明或方法选项,请查看docs。

# info.py

# ...
# this is just an example
class Info(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.command()
    async def about(self, ctx):
        await ctx.send("something here")

    # ...

# extensions need a setup function
def setup(bot):
    bot.add_cog(Info(bot))
# main.py

# ...

bot = commands.Bot(
    # ...
)
bot.load_extension("info")

bot.run(token)
# reload command
@bot.command()
async def reload(ctx, extension):
    # probably want to add a check to make sure
    # only you can reload things.
    # also handle the input
    bot.reload_extension(extension)
to use, you might do something like `prefix!reload info`

【讨论】:

是类似于cog_name或类名的reload扩展参数 另外我在一个文件中有 4 个 cog,我如何一次重新加载其中一个 @Joel 重新加载功能在扩展中,因此您需要将您的 cog 拆分为不同的文件。扩展名和python的导入名一样,所以一般是文件名,如果有目录的话用点分隔。 see d.py's docs

以上是关于关闭 Discord 机器人连接而不终止命令行 (discord.py)的主要内容,如果未能解决你的问题,请参考以下文章

如何从另一个命令终止 discord.py 中的异步函数

如何在 discord.py 中设置禁止命令而不禁止管理员?

Discord Slash 命令机器人 - Python 结构 [关闭]

discord.py前缀命令[关闭]

在 discord.js 中创建一个用于从数组中查找和终止角色的 for 循环

我将如何创建一个踢服务器中每个人的机器人命令(discord.js-commando)[关闭]