#client.command not running, discord.py [duplicate] - discord

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

Related

SyntaxError: 'await' outside async function discord.py

import discord.ext
import discord
from discord.ext import commands
from discord.ext import tasks
from keep_alive import keep_alive
import os
import schedule
client = discord.Client()
client = commands.Bot(command_prefix="")
channel_id = 927272717227528262
channel = client.get_channel(channel_id)
#tasks.loop(seconds=1.0)
#client.event
async def on_message(message):
if message.author == client.user:
return
def job2():
await message.channel.send("message")
schedule.every(10).seconds.do(job2)
while True:
schedule.run_pending()
time.sleep(0)
keep_alive()
client.run(os.getenv('TOKEN'))
Every time I run it I get :
SyntaxError: 'await' outside async function
I am also having the issue where message is undefined the definition of job2 even though it was just defined in the line above.
You should probably be using discord.ext.tasks. Async functions aren't really supported by schedule.
In fact, your bot can never run because your schedule.run_pending() in the infinite loop will never end.
In order to keep your message there you'll need to put it in a global of some type.
the_message = None
#tasks.loop(seconds=1.0)
#client.event
async def on_message(message):
global the_message
if message.author == client.user:
return
the_message = message
async def job2():
if the_message is None:
return
await the_message.channel.send("message")
#tasks.loop(seconds=10.0) # you can do other things like `minutes=5` or `hours=1.75`
async def my_task():
await client.wait_until_ready()
await job2()
my_task.start()
# then the bot runs fine after
keep_alive()
client.run(os.getenv('TOKEN'))
Be careful that this might run before your client is not ready and initializing. You may also want to check wait_until_ready if you're going to do anything with the API, like in your case. You can also find other examples here.
await is used in asynchronous functions to wait for the function to do its thing. However, you have used it in a synchronous function (def job2)
message is not a variable. message is the parameter of the on_message function. A parameter can only be used in the function it is provided to.
Hope this answered your question.

Making my discord bot listen for specific messages and answer back when it identifies one

So, I'm new to python and even more to coding bots on discord. At the moment I'm using discord.py and red-bot (https://docs.discord.red/en/stable/index.html).
At the moment I'm trying to make the bot listen to a new message and print something in response to it, but I just can't figure it out. Since I'm using red-bot I didn't go through the steps of using client = discord.Client() and setting a token on the code itself so using #client.event() doesn't seem to work, nor #bot.event(), and I can't really find any other way to make the bot listen for an on_message() event.
Edit with part of my code:
import discord
from discord.ext import commands
from redbot.core import commands
class MyCog(commands.Cog):
client = discord.Client()
def __init__(self, bot):
self.bot = bot
#bot.event()
async def on_message(self, message):
if 'test' in message.content:
await self.send_message(message.channel, 'it works!')
Console returns that bot in #bot.event() is not defined.
Also a separate initialization file, it's done this way to follow Red's guide of how to make a cog.
from .remind import MyCog
def setup(bot):
bot.add_cog(MyCog(bot))
Here is an example of a cog that replies to a specific word mentioned. It also has a cooldown to prevent the bot spamming which I find absolutely neccesary to include.
from curses.panel import bottom_panel
import discord
from discord.ext import commands
class brilliant(commands.Cog):
def __init__(self, bot):
self.bot = bot
self._cd = commands.CooldownMapping.from_cooldown(1, 60.0, commands.BucketType.member) # Change accordingly
# rate, per, BucketType
def ratelimit_check(self, message):
"""Returns the ratelimit left"""
bucket = self._cd.get_bucket(message)
return bucket.update_rate_limit()
#commands.Cog.listener()
async def on_message(self, message):
if message.author == self.bot.user:
return
msg = message.content.lower()
brilliant = ['brilliant', 'Brilliant', 'brilliant!', 'Brilliant!']
if any(word in msg for word in brilliant):
retry_after = self.ratelimit_check(message)
if retry_after is None:
await message.channel.send("Brilliant!")
await self.bot.process_commands(message)
else:
return
async def setup(bot):
await bot.add_cog(brilliant(bot))
If you want it in the main file, you can put something a lot simpler:
brilliant = ['brilliant', 'Brilliant', 'brilliant!', 'Brilliant!']
#bot.event
async def on_message(message):
if message.author == bot.user:
return
msg = message.content.lower()
if any(word in msg for word in brilliant):
await message.channel.send("Brilliant!")
await bot.process_commands(message)
Hope it helps.

How can I have a trigger without my command prefix, like welcome and not $welcome?

So I wanted to make a feature on my discord bot and I wanted it to respond when users say welcome and say Welcome! back. But every time I try it only responds to $welcome. ($ is my prefix). What should I do?
client = commands.Bot(command_prefix = "$")
#client.command()
async def welcome(ctx, message):
if any(word in message for word in welcome):
await message.channel.send("Welcome!")
#client.event
async def on_message(message):
if "welcome" in message.content:
await message.channel.send('Welcome!')

discord.py Ping Command

I have problem with my discord.py command. I want to make ping command which will respond with my bot's ping. My code is below.
#bot.command()
async def ping(ctx):
await ctx.send(f"Pong :ping_pong:! Bot latency: **{round(bot.latency * 1000)}ms**"
I also tried to write my code like this.
#client.command()
async def ping(ctx):
await ctx.send(f"Pong :ping_pong:! Bot latency: **{round(bot.latency * 1000)}ms**"
None of the above code works.
I have this command and I've tested it to know it works.. you can try it:
#bot.command()
async def ping(ctx):
await ctx.send(f'My ping is** {round(bot.latency*1000)} Ms**')
Btw, if you have defined bot as client, make sure to change bot.latency to client.latency
Did you add a bracket to the end?
#bot.command() # set this to your bots variable
async def ping(ctx):
await ctx.send(f"Ping!\nLatency is **{round(bot.latency * 1000)}ms**!")
embed = discord.Embed(
title="🏓 Pong!",
description=f"The bot latency is {round(self.bot.latency * 1000)}ms.",
color=0x42F56C
)
await ctx.send(embed=embed)
The problem with your code is that you forgot the ) between ms** and ".
#bot.command()
async def ping(ctx):
await ctx.send(f"Pong :ping_pong:! Bot latency: **{round(bot.latency * 1000)}ms**")
This is the code fixed, if you want to use #client, just use this:
#client.command()
async def ping(ctx):
await ctx.send(f"Pong :ping_pong:! Bot latency: **{round(client.latency * 1000)}ms**")

discord.py restart the command

I am making a discord bot and I tried to make a status command that will make my bot's status start changing, so I thought its working pretty well until I realized that I need it to restart and that I have no idea how to do that, so here is my code without the restart part:
#client.command()
async def status(ctx):
await client.change_presence(activity=discord.Streaming(name='firststatus', url='https://www.twitch.tv/my-channel-name'))
await asyncio.sleep(5)
await client.change_presence(activity=discord.Activity(type=discord.ActivityType.watching, name='Secondstatus'))
so I did that but I don't know what to put at the end so it'll restart I guess it will be something like client.command.restart.
You can use a simple while loop or the built-in discord.py extension tasks
from discord.ext import tasks
#tasks.loop(seconds=5)
async def change_status():
await client.change_presence(activity=discord.Streaming(name='firststatus', url='https://www.twitch.tv/my-channel-name'))
await asyncio.sleep(5)
await client.change_presence(activity=discord.Activity(type=discord.ActivityType.watching, name='Secondstatus'))
#client.command()
async def status(ctx):
change_status.start()
The change_status function will loop every 5 seconds and change the presence. You can stop it with change_status.stop()
Reference:
tasks.loop
Loop.start
Loop.stop

Resources