Вызов функции из другого файла - бот Discord - PullRequest
1 голос
/ 17 февраля 2020

Я не знаком с ботами Discord и многим из Python, поэтому вот простой вопрос, на который я тоже не могу найти ответ.

У меня есть два файла; discord_bot.py и test.py Как переслать сообщение из test.py для отправки его на канал в Discord

test.py

import discord_bot

discord_bot.signal(msg = "Hi")

discord_bot.py

import discord
from discord.ext import commands

TOKEN = 'Njc3MjA2MTA5MjM2MjMyMjMx.XkQ3sQ.Ew47BnNqRyZpZSHjze8eGTpd2Q'
bot = commands.Bot(command_prefix='!')

@bot.command()
async def signal(ctx, *, msg):
    await ctx.send(msg)

Бот Discord работает нормально, но вызов функции signal из теста не является правильным способом сделать это. Любая помощь здесь, пожалуйста? bot.run (ЗНАК)

1 Ответ

1 голос
/ 17 февраля 2020

Это много для распаковки.

0. Никогда не размещайте свой токен для разногласий в сети. Discord может автоматически сделать недействительным ваш токен, если он будет опубликован в сети.

1. Вы не запускаете своего бота в данный момент, добавьте bot.run(TOKEN) в конце

2. Как работают команды расширения диска Discord

@bot.command() - это декоратор , если вы не знаете, как они работают, ознакомьтесь с ним. Слишком упрощенно, они берут вашу функцию и регистрируют в боте.

Внутренняя работа расширения commands в основном:

  1. Зарегистрируйте все команды с помощью загрузка декораторов
  2. Каждый раз, когда приходит сообщение, проверьте, содержит ли оно префикс, и если да, проверьте, соответствует ли оно команде.
  3. Если обе проверки из 2 пройдены, создайте контекст объект, а затем передать этот объект в функцию. Примерно так:
signal(ctx, *args)

Вот почему объект ctx не может быть позиционным, потому что способ вызова функции во внутренней работе бота как обычный аргумент.

4. Не пытайтесь возиться с созданием своего собственного объекта контекста, если только вы не знаете, что делаете. Вам необходимо создавать объекты контекста, только если вы переопределяете парсер сообщений по умолчанию.

5. Не используйте команды для этого.

Что вы хотите сделать, насколько я могу судить: Вызовите команду самостоятельно. Это достаточно просто:

файл 1:

@bot.command()
async def signal(ctx, *, msg):
    print(msg)

файл 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'))

Это работает легко, печатает ваши материалы. Но вы не хотите, чтобы это было напечатано, верно? Вы хотите, чтобы оно было отправлено в канале . Это то, для чего вам нужен объект контекста, о котором я говорил ранее, чтобы не создавать себя. Так как же мы на самом деле это делаем?

Ответ таков: Не используйте команды . Они используются для реагирования на сообщения, а не для их самостоятельного вызова.

6. Решение, которое вы (вероятно) хотите

Итак, основные изменения здесь таковы:

  1. сигнал теперь является обычной асинхронной c функцией без декоратора

  2. Мы фактически указываем канал, куда мы хотим, чтобы материал отправлялся в качестве аргумента функции

file 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)

Основные изменения:

  1. Мы используем asyncio.run для вызова функции. Функции Asyn c нельзя вызывать с обычным синтаксисом.
  2. Возможно, вам потребуется запустить file2.py, чтобы запустить программу. Запущенный файл1 не загрузит файл2.

файл 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))
...