discord.ext.commands.errors.ExtensionFailed: NameError - discord.py

I was using cogs on discord.py to detach the file, but there was a bug that caused NameError and was not running. How can I solve this?
Error
discord.ext.commands.errors.ExtensionFailed: Extension 'cogs.news' raised an error: NameError: name 'news' is not defined.
app.py
...
# Cogs Part
extension = ["cogs.commands","cogs.news", "cogs.manage"]
for filename in os.listdir('./cogs'):
if filename.endswith('.py'):
client.load_extension(f'cogs.{filename[:-3]}')
...
cogs/news.py
...
class news(news.Cog):
def __init__(self, bot):
self.bot = bot
#commands.command(name='news')
async def news(self, ctx):
# ^^^ NameError : name 'news' is not defined
...

If you need any more help after reading this, you can join this small discord server.
I don't know if you left it out intentionally, but you need to add the following code at the end of the cogs/news.py file.
def setup(bot):
bot.add_cog(news(bot))
Also, you shouldn't need to load the extensions like you did, try doing this instead by removing the:
extension = ["cogs.commands","cogs.news", "cogs.manage"]
Like so:
for file in os.listdir("./cogs"):
if file.endswith(".py"):
name = file[:-3]
client.load_extension(f"cogs.{name}")
If none of this works consider replacing the
class news(news.Cog):
With:
class news(commands.Cog):
EXTRAS:
You can also add a command on the app.py file that allows you to reload any command in the cogs without restarting the bot:
#client.command()
#commands.is_owner()
async def reload(ctx, *, name: str):
try:
client.reload_extension(f"cogs.{name}")
except Exception as e:
return await ctx.send(e)
await ctx.send(f'"**{name}**" Cog reloaded')
And an option that alows you to disable or enable a command:
#client.command()
#commands.is_owner()
async def load(ctx, *, name: str):
try:
client.load_extension(f"cogs.{name}")
except Exception as e:
return await ctx.send(e)
await ctx.send(f'"**{name}**" Cog loaded')
And
#client.command()
#commands.is_owner()
async def unload(ctx, *, name: str):
try:
client.unload_extension(f"cogs.{name}")
except Exception as e:
return await ctx.send(e)
await ctx.send(f'"**{name}**" Cog unloaded')
If this help in any way, an upvote and a mark as answer would be appreciated :)

Related

How to have cog listener called before cog command

I have some code for a cog that looks something like this:
class Example(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.counter = 0
#commands.Cog.listener()
async def on_message(self, message):
print("Listener triggered")
self.counter += 1
#commands.group()
async def first(self, ctx):
if ctx.invoked_subcommand is None:
await ctx.send("Invalid subcommand")
#first.command()
async def second(self, ctx):
print("Command triggered")
await ctx.send(f"Current counter: {self.counter}")
When I run this code and send a message to my bot, second gets called before on_message. I have some code in second that expects on_message to be executed first, but I can't figure out a good way to make this happen. Suggestions?
check wait_for event.
and I think you are trying to make a bot count the number of valid uses of command. To do this, try:
def check(message):
#here put ur condition for message is a valide command
await client.wait_for('message', check=check)

Editing a bot's message just like when you swipe a page, discord.py

I wanted to make a command that edits the bot's old message trought another command, example:
user: !cmds
bot: *commands list*
user: !next
bot: *edits old message into a new one*
I have tried many times to make it myself, but I failed all the times, can anyone help me?
How I tried to make it:
#client.command
async def test():
embed=discord.Embed(title="Page1")
await ctx.send(embed=embed)
#client.event
async def on_command(message):
embed2=discord.Embed(title="Page2")
await client.process_commands(message)
if message.content == '$next':
await message.edit(content=embed2)
The on_command event is called whenever a command is called, you didn't register a next command, that's one, second of all on_command doesn't take message argument, it takes the Context(ctx).
An idea to make what you're asking for is having a cog with an instance variable that references to the previous message, then edit it when the next command is called.
class SomeCog(commands.Cog):
def __init__(self, client):
self.client = client
self._previous_message = None
#commands.command()
async def test(self, ctx):
message = await ctx.send("I'll edit this message when you type `$next`")
self._previous_message = message
#commands.command()
async def next(self, ctx):
if self._previous_message is None: # Exiting if the `test` command wasn't called before, i.e the message is a NoneType
return await ctx.send("You need to invoke first `$test`")
await self._previous_message.edit(content="Edited the message")
client.add_cog(SomeCog(client))
I'm guessing you could do it with global or bot vars but this is the best way to do it, in my opinion.

I am having trouble with this piece of code

I'm making an Administration cog for my discord bot and my code wouldn't identify 'ctx'. PyCharm suggested to replace 'ctx' with 'self' and I have no idea what 'self' does. And from what PyCharm is saying, There are millions of other stuff which I have to write down what it is. PyCharm couldn't identify guild, send, author and channel and it also says that return ctx.author.guild_permissions.manage_messages is an unreachable code. As a note if this seems to be a really stupid question, I am a beginner who started 2 weeks ago.
As for the code:
class Administration(commands.Cog):
def __init__(self, client):
self.client = client
#commands.Cog.listener()
async def on_ready(self):
print("Admin cog ready")
async def cog_check(self, ctx):
admin = get(ctx.guild.roles, name="Admin")
return admin in ctx.author.roles
return ctx.author.guild_permissions.manage_messages
#commands.command(aliases=["purge"])
async def clear(ctx, amount=3):
"""Clears 3 messages"""
await ctx.channel.purge(limit=amount)
#commands.command(pass_context=True)
async def giverole(ctx, user: discord.Member, role: discord.Role):
"""Gives a role to a user"""
await user.add_roles(role)
await ctx.send(f"hey {ctx.author.name}, {user.name} has been giving a role called: {role.name}")
#commands.command(aliases=['make_role'])
#commands.has_permissions(manage_roles=True)
async def create_role(ctx, *, name):
"""Creates a role"""
guild = ctx.guild
await guild.create_role(name=name)
await ctx.send(f'Role `{name}` has been created')
#commands.command(name="slap", aliases=["warn"])
async def slap(ctx, members: commands.Greedy[discord.Member], *, reason='no reason'):
"""Warns someone"""
slapped = ", ".join(x.name for x in members)
await ctx.send('{} just got slapped for {}'.format(slapped, reason))
def setup(client):
client.add_cog(Administration(client))
In classes, (unless it's a staticmethod or classmethod) you always pass self as the first argument.
#commands.command(aliases=["purge"])
async def clear(self, ctx, amount=3): # Note how I put `self` as the first arg, do the same in all commands in the cog
"""Clears 3 messages"""
await ctx.channel.purge(limit=amount)
Also, this will never work
async def cog_check(self, ctx):
admin = get(ctx.guild.roles, name="Admin")
return admin in ctx.author.roles
return ctx.author.guild_permissions.manage_messages
The function will end no matter what when it reaches the first return, you can simply use the AND or OR logical operator if you want to also evaluate the second return statement
async def cog_check(self, ctx):
admin = get(ctx.guild.roles, name="Admin")
return admin in ctx.author.roles and/or ctx.author.guild_permissions.manage_messages

async def on_ready(): SyntaxError: invalid syntax

I was making an discord bot and im new to python and i have looked up but didn't find any answer on how to fix this but i got error from this code
Code:
import discord
from discord.ext import commands
client = command.Bot(command_prefix="<")
#client.event
async def on_ready():
print("Bot is online")
#client.command()
synd def Test(ctx):
await ctx.send("Test successful")
client.run(Token)
line with error:
#client.event
async def on_ready():
print("Bot is online")
Error:
async def on_ready():
^
SyntaxError: invalid syntax
Does anyone know how to fix this? i am using Python version: pip 19.2.3 (python 3.8)
EDITED
The print function needs to be intended another 4 spaces to be like:
async def on_ready():
print("Bot is online")
you can try use command "python3 file_name.py"

on_message stops all of my bot.commands from working

I have a flip command that returns either heads or tails and it was working fine until I added the on_message function. I did some research on SO and read the documentation and here it says to include await bot.process_commands(message) in the on_message function but that did not solve the issue and the flip command still doesn't work. If I remove the on_message function everything works as expected.
bot.py
import discord
from discord.ext import commands
import random
# from app bot user
# click to reveal
TOKEN = 'token_here'
client = commands.Bot(command_prefix = '!')
#client.event
async def on_ready():
print('Bot ready')
#client.command()
async def flip():
flip = random.choice(['heads', 'tails'])
await client.say(flip)
#client.event
async def on_message(message):
if message.content.upper().startswith('N****'):
await client.send_message(message.channel, "Please do not use that word here.")
client.process_commands(message)
#client.event
async def on_member_join(member):
await client.change_presence(game=discord.Game(name='Hi %s' % (member)))
await client.send_message(member, "Hi %s, Welcome to Carson's Discord Server! This server is fairly NSFW at times; you've been warned! Enjoy your stay :)" % (member))
#client.event
async def on_member_remove(member):
await client.change_presence(game=discord.Game(name='Bye %s' % (member)))
client.run(TOKEN)
When I run the script, everything else works normally with no errors. It's just the commands that don't work. Any insight would be greatly appreciated.
You need to await the last line in on_message as process_commands is a coroutine.
await client.process_commands(message)
If you send !flip in discord, you should be able to receive the appropriate response (heads or tails).

Resources