从另一个文件调用函数 - Discord bot

Sal*_*zal 2 python api async-await discord discord.py

我不熟悉 Discord 机器人或 Python 的大部分内容,所以这是一个我无法找出答案的简单问题。

我有两个文件;Discord_bot.py 和 test.py 如何转发来自 test.py 的消息以将其发送到 Discord 中的频道?

测试.py

import discord_bot

discord_bot.signal(msg = "Hi")
Run Code Online (Sandbox Code Playgroud)

discord_bot.py

import discord
from discord.ext import commands

TOKEN = '1234567890'
bot = commands.Bot(command_prefix='!')

@bot.command()
async def signal(ctx, *, msg):
    await ctx.send(msg)
Run Code Online (Sandbox Code Playgroud)

Discord 机器人工作正常,但从测试中调用信号函数并不是正确的方法。请问这里有什么帮助吗?

小智 5

有很多东西需要解开。

0. 切勿在网上发布您的不和谐代币。如果您的令牌在线发布,Discord 可能会自动使其失效。

1.您目前没有运行您的机器人,请bot.run(TOKEN)在最后添加

2.discord 机器人扩展的命令如何工作

@bot.command()是一个装饰器,如果你不知道它们是如何工作的,请阅读它。过于简单化,他们接受你的功能并在机器人中注册。

扩展的内部工作原理commands基本上是:

  1. 通过加载装饰器来注册所有命令
  2. 每当消息到达时,检查它是否包含前缀,如果包含,则检查它是否适合命令。
  3. 如果 2 中的两项检查都通过,则构造一个Context对象,然后将该对象传递给该函数。像下面这样:
signal(ctx, *args)
Run Code Online (Sandbox Code Playgroud)

这就是为什么 ctx 对象不能是位置性的,因为该函数在机器人内部工作中作为普通参数调用的方式。

4. 不要试图搞乱创建自己的上下文对象,除非你知道自己在做什么。如果您要覆盖默认消息解析器,则只需创建上下文对象。

5. 不要为此使用命令。

据我所知,你想要做什么:自己调用命令。这很容易:

文件1:

@bot.command()
async def signal(ctx, *, msg):
    print(msg)
Run Code Online (Sandbox Code Playgroud)

文件2:

from file1 import signal
import asyncio # if you don't know asyncio, read up on it

asyncio.run(signal(None, 'This is an argument'))
Run Code Online (Sandbox Code Playgroud)

这很容易工作,它会打印你的东西。但您不希望将其打印出来,对吧?您希望它在通道中发送。这就是你需要上下文对象的原因,我之前说过,不要自己构建。那么我们实际上如何做到这一点呢?

答案是:不要使用命令。它们用于对消息做出反应,而不是由它们自己调用。

6.您(可能)想要的解决方案

所以这里的主要变化是:

  1. 信号现在是一个普通的异步函数,没有装饰器

  2. 我们实际上指定了一个通道,我们希望将内容作为函数的参数发送到该通道

文件1:

import discord
from discord.ext import commands

TOKEN = 'do not share your token online'
bot = commands.Bot(command_prefix='!')

# as the channel_id, pass the channel_id you want the message to be sent in
async def signal(msg, channel_id):
    global bot # getting our bot variable from the global context
    channel = bot.get_channel(channel_id)
    await channel.send(msg)

bot.run(TOKEN)
Run Code Online (Sandbox Code Playgroud)

这里的主要变化是:

  1. 我们使用 asyncio.run 来调用该函数。无法使用常规语法调用异步函数。
  2. 您可能需要运行 file2.py 来启动该程序。运行 file1 将不会加载 file2。

文件2

from file1 import signal
from time import sleep
import asyncio

sleep(5) # We need to give our bot time to log in, or it won't work
asyncio.run(signal('hi!', 123))
Run Code Online (Sandbox Code Playgroud)