I've had this problem for a while, trying to use both commands and events in one file.
I know that there's a function called process_commands(), but the bot doesn't seem to have this function. Is there anything I need to import though? (else than discord.ext and commands)
picture of code: https://i.stack.imgur.com/Gdvj8.png
you should add await client.process_commands(message) on top of the on_message event
#client.event
async def on_message(message):
await client.process_commands(message)
# do other stuff
also message.send('...') in your command doesnt work, it must be awaited since its a coroutine. (Docs)
#client.command()
async def test(ctx): # ctx instead of message
await ctx.send("test")
Related
How can I create a function (without async) that sends a message to a specific channel every time it (the function) gets executed somewhere in the code?
def sendMsg():
channel = client.getChannel(Channel id)
message.channel.send("example message")
#excecuting the function
sendMsg()
Doesn't do anything
async def on_message():
await message.channel.send("example message")
Only this one works
So my question is if I can modify the code on the top make it work?
If you need to send the message outside of an async context, you need to add the task into the event loop. Note that when you "call" a coroutine, you get the actual coroutine object. "Calling" it doesn't actually run the coroutine, you need to put it in the event loop for it to run.
asyncio.get_event_loop().create_task(<coro>)
# use it like this
asyncio.get_event_loop().create_task(ctx.send('test'))
asyncio.get_event_loop().create_task(message.channel.send("example message"))
Eric's answer is correct. Moreover, in order to get the loop event from discord.py, you can use client.loop to get discord.py's asyncio eventloop
that said, use asyncio.run_coroutine_threadsafe(def,loop) to safely submit task to event_loop
client = discord.Client()
async def send_message_to_specific_channel(message='abc',id=123):
channel = client.get_channel(id)
await channel.send(message)
asyncio.run_coroutine_threadsafe(send_message_to_specific_channel('abc',123),client.loop)
Async is really needed for synchronize the message
If your wanna make it as selfbot response message, do
# Import's here
from discord.ext import commands
bot = commands.Bot(command_prefix='!', help_command=None, self_bot=True)
#bot.event
async def on_message(message):
if message.content.startswith("Hello"):
await message.channel.send(f"Hi #{message.author}")
bot.run('token ofc', bot=False)
Anyways this for selfbot if you wanna do it with bots, delete self_bot=True and bot=False
This is a pretty basic question but here is the issue. I am trying to make a discord bot that takes a message and delays it by a set amount of time. However, it only can handle one message at a time and will not delay any others until that one has gone through. Is there a way to make it so the bot can handle all the messages at once?
here is the code for the function
#client.event
async def on_message(message):
if not message.author.bot:
await message.delete()
time.sleep(100)
await message.channel.send('{} : {}'.format(message.author.name,
message.content))
await client.process_commands(message)
This is because time.sleep() blocks code and pretty much stops everything from working until the time set expires. What you want to use is asyncio.sleep()
import asyncio
#client.event
async def on_message(message):
if not message.author.bot:
await message.delete()
await asyncio.sleep(100)
await message.channel.send('{} : {}'.format(message.author.name,
message.content))
await client.process_commands(message)
asyncio.sleep() will still allow you to do what you intended to do but also allow the bot to continue working and accept more requests/tasks.
Basically, everything appears to work fine and start up, but for some reason I can't call any of the commands. I've been looking around for easily an hour now and looking at examples/watching videos and I can't for the life of me figure out what is wrong. Code below:
import discord
import asyncio
from discord.ext import commands
bot = commands.Bot(command_prefix = '-')
#bot.event
async def on_ready():
print('Logged in as')
print(bot.user.name)
print(bot.user.id)
print('------')
#bot.event
async def on_message(message):
if message.content.startswith('-debug'):
await message.channel.send('d')
#bot.command(pass_context=True)
async def ping(ctx):
await ctx.channel.send('Pong!')
#bot.command(pass_context=True)
async def add(ctx, *, arg):
await ctx.send(arg)
The debug output I have in on_message actually does work and responds, and the whole bot runs wihout any exceptions, but it just won't call the commands.
From the documentation:
Overriding the default provided on_message forbids any extra commands from running. To fix this, add a bot.process_commands(message) line at the end of your on_message. For example:
#bot.event
async def on_message(message):
# do some extra stuff here
await bot.process_commands(message)
The default on_message contains a call to this coroutine, but when you override it with your own on_message, you need to call it yourself.
Ascertained that the problem stems from your definition of on_message, you could actually just implement debug as a command, since it appears to have the same prefix as your bot:
#bot.command()
async def debug(ctx):
await ctx.send("d")
Basically, everything appears to work fine and start up, but for some reason I can't call any of the commands. I've been looking around for easily an hour now and looking at examples/watching videos and I can't for the life of me figure out what is wrong. Code below:
import discord
import asyncio
from discord.ext import commands
bot = commands.Bot(command_prefix = '-')
#bot.event
async def on_ready():
print('Logged in as')
print(bot.user.name)
print(bot.user.id)
print('------')
#bot.event
async def on_message(message):
if message.content.startswith('-debug'):
await message.channel.send('d')
#bot.command(pass_context=True)
async def ping(ctx):
await ctx.channel.send('Pong!')
#bot.command(pass_context=True)
async def add(ctx, *, arg):
await ctx.send(arg)
The debug output I have in on_message actually does work and responds, and the whole bot runs wihout any exceptions, but it just won't call the commands.
From the documentation:
Overriding the default provided on_message forbids any extra commands from running. To fix this, add a bot.process_commands(message) line at the end of your on_message. For example:
#bot.event
async def on_message(message):
# do some extra stuff here
await bot.process_commands(message)
The default on_message contains a call to this coroutine, but when you override it with your own on_message, you need to call it yourself.
Ascertained that the problem stems from your definition of on_message, you could actually just implement debug as a command, since it appears to have the same prefix as your bot:
#bot.command()
async def debug(ctx):
await ctx.send("d")
Basically, everything appears to work fine and start up, but for some reason I can't call any of the commands. I've been looking around for easily an hour now and looking at examples/watching videos and I can't for the life of me figure out what is wrong. Code below:
import discord
import asyncio
from discord.ext import commands
bot = commands.Bot(command_prefix = '-')
#bot.event
async def on_ready():
print('Logged in as')
print(bot.user.name)
print(bot.user.id)
print('------')
#bot.event
async def on_message(message):
if message.content.startswith('-debug'):
await message.channel.send('d')
#bot.command(pass_context=True)
async def ping(ctx):
await ctx.channel.send('Pong!')
#bot.command(pass_context=True)
async def add(ctx, *, arg):
await ctx.send(arg)
The debug output I have in on_message actually does work and responds, and the whole bot runs wihout any exceptions, but it just won't call the commands.
From the documentation:
Overriding the default provided on_message forbids any extra commands from running. To fix this, add a bot.process_commands(message) line at the end of your on_message. For example:
#bot.event
async def on_message(message):
# do some extra stuff here
await bot.process_commands(message)
The default on_message contains a call to this coroutine, but when you override it with your own on_message, you need to call it yourself.
Ascertained that the problem stems from your definition of on_message, you could actually just implement debug as a command, since it appears to have the same prefix as your bot:
#bot.command()
async def debug(ctx):
await ctx.send("d")