如何在 Discord 机器人项目中运行额外的 Python 代码

Posted

技术标签:

【中文标题】如何在 Discord 机器人项目中运行额外的 Python 代码【英文标题】:How to run extra Python code in a Discord bot project 【发布时间】:2021-01-12 20:02:00 【问题描述】:

我正在尝试运行我的 discord 机器人,从中运行 exit() 或 logout(),运行一些其他 python 代码,然后重新登录。我没有使用异步函数的经验,所以我不知道错误消息是什么意思。

import discord

dToken = "xxxxx"
client = discord.Client()


@client.event
async def on_ready():
    print('Logged in as')
    print(client.user.name)
    print(client.user.id)

    guilds = client.guilds
    for i in range(len(guilds)):

        if str(guilds[i]) == server:
           gld = guilds[i]
           for channel in gld.text_channels:
                if str(channel) == "channelname":
                    print(str(message)+" sent to channel id "+str(channel.id))
                    await client.get_channel(channel.id).send(message)

    await client.logout()

#run bot
client.run(dToken)

#change message and server name depending on extra code I put here
message = "hello!"
server = "servername"

#run bot again with changes
client.run(dToken)

我必须 logout() 因为这是我发现可以使额外代码运行的唯一方法。但是我的代码给出了以下错误:

    Traceback (most recent call last):
  File "C:/Users/mmh/PycharmProjects/pythonProject/test.py", line 21, in <module>
    client.run(dToken)
  File "C:\Users\mmh\PycharmProjects\pythonProject\venv\lib\site-packages\discord\client.py", line 665, in run
    future = asyncio.ensure_future(runner(), loop=loop)
  File "C:\Users\mmh\AppData\Local\Programs\Python\Python37\lib\asyncio\tasks.py", line 608, in ensure_future
    task = loop.create_task(coro_or_future)
  File "C:\Users\mmh\AppData\Local\Programs\Python\Python37\lib\asyncio\base_events.py", line 402, in create_task
    self._check_closed()
  File "C:\Users\mmh\AppData\Local\Programs\Python\Python37\lib\asyncio\base_events.py", line 479, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
sys:1: RuntimeWarning: coroutine 'Client.run.<locals>.runner' was never awaited

Process finished with exit code 1

有人知道我应该做什么吗?

【问题讨论】:

await client.run(dToken) ? @JacobIRR "await" 仅在 def on_ready() 函数内有效 【参考方案1】:

据我所知,你不能连续运行两次client.run(我自己试过,得到了相同的RuntimeError)。但是在这种情况下,您似乎想向两个不同服务器中的两个通道发送消息。如果是这样,您可以简单地在 on_ready 中创建一个函数来向给定通道发送消息,然后您可以调用该函数两次:

@client.event
async def on_ready():
    async def send_message(server_name, channel_name, message):
        # Instead of looping through indices for client.guilds,
        # you should iterate over client.guilds itself
        # (as you did for gld.text_channels)
        for guild in client.guilds:
            if guild.name != server_name:
                continue

            for channel in guild.text_channels:
                if channel.name == channel_name:
                    await channel.send(message)
                    print(message, 'sent to channel id', channel.id)
                    return
            else:
                raise ValueError('could not find channel')

        else:
            raise ValueError('could not find server')

    await send_message('server1', 'textchannel1', 'hello!')
    await send_message('server2', 'textchannel2', 'hello!')

【讨论】:

以上是关于如何在 Discord 机器人项目中运行额外的 Python 代码的主要内容,如果未能解决你的问题,请参考以下文章

如何在旧版本仍在运行时调试 Discord 机器人?

如何在不达到 Discord 的 1,000 个最大连接数的情况下运行从 API 更新的 Discord 机器人?

如何将 discord.js 机器人部署到 Cloud Functions?

如何避免在 Discord 服务器中出现多个机器人实例

如何在运行我的网站的同一台服务器上托管我的 Discord 机器人?

如何修复 Discord.py 不为语音命令运行我的异步功能?