Reputation: 587
I am not familiar with Discord bots or much of Python so here's a simple question I can't figure out the answer to.
I have two files; discord_bot.py and test.py How do I forward a message from test.py to send it to a channel in Discord?
test.py
import discord_bot
discord_bot.signal(msg = "Hi")
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)
The Discord bot works fine but calling the signal function from test is not the correct way to do it. Any help here please?
Upvotes: 2
Views: 6264
Reputation: 1829
This is a lot to unpack.
0. Never post your discord token online. Discord may automatically invalidate your token if it's posted online.
1. You are not running your bot at the moment, add bot.run(TOKEN)
at the end
2. How the commands of the discord bot extension work
@bot.command()
is a decorator, if you do not know how they work, read up on it. Overly simplified, they take your function and register in the bot.
The inner workings of the commands
extension are basically:
signal(ctx, *args)
This is why the ctx object can't be positional, because the way the function is called in the inner workings of the bot as a normal argument.
4. Do not try to mess with creating your own context object, unless you know what you're doing. You only need to create context objects if you're overriding the default message parser.
5. Don't use commands for this.
What you want to do, as far as I can tell: Call a command yourself. This is easy enough:
file 1:
@bot.command()
async def signal(ctx, *, msg):
print(msg)
file 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'))
This works easily, it prints your stuff. But you don't want it to be printed, right? You want it to be sent in a channel. This is what you need the context object for, which I said before, to not construct yourself. So how do we actually do this?
The answer is: Don't use commands. They are used for reacting to messages, not to be called by themselves.
6. The solution you (probably) want
So the major changes here are:
signal is now a normal async function with no decorator
We actually specify a channel where we want the stuff to be sent in as an argument of the function
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)
Major changes here are:
file 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))
Upvotes: 5