Discord py cogs not loading commands - python

I made a discord bot with a main file and one other file of commands that are loaded with cogs and the problem is that the commands are not loaded.
I simplified the code triny to resolve the error but even this does not work:
bot.py:
import discord
from discord.ext import commands
import config
# declaring intents and launching client
intents = discord.Intents.default()
intents.members = True
intents.presences = True
bot = commands.Bot(command_prefix='.', description="Useful bot", intents=intents)
startup_extensions = ["private_channels"]
# listener
#bot.event
async def on_ready():
print(f'Connected to Discord as {bot.user} !')
#bot.event
async def on_message(message):
if message.author == bot.user:
return
print("message received")
# starting extensions
for extension in startup_extensions:
try:
bot.load_extension(extension)
except Exception as e:
exc = '{}: {}'.format(type(e).__name__, e)
print('Failed to load extension {}\n{}'.format(extension, exc))
# starting bot
bot.run(config.token)
private_channels.py:
from discord.ext import commands
class PrivateChannels(commands.Cog):
def __init__(self, bot):
self.bot = bot
# creates a new private channel
#commands.command(name="test")
async def test(self, ctx):
await ctx.send("test")
def setup(bot):
print("Loading private channels")
bot.add_cog(PrivateChannels(bot))
print("Private channels loaded")

Okay, the main problem that I had is that on_message event overwrites the commands. To correct that, I added await bot.process_commands(message) to on_message to process commands and now it works.

Related

Cogs loads but won't work in discord.py 2.0

I've provided code of two files. bot.py - runs bot, ping.py - cog file.
The problem is that Cog doesn't work, bot doesn't respond to commands, in my ping.py file i have ping command
bot.py
import discord as ds
import asyncio
import os
from dotenv import load_dotenv
from discord.ext import commands
load_dotenv()
intents = ds.Intents.all()
intents.message_content = True
bot = commands.Bot(command_prefix='!', intents=intents)
#bot.event
async def on_message(message):
if message.author == bot.user:
return
username = str(message.author)
user_message = str(message.content)
channel = str(message.channel)
print(f"{username} said: '{user_message}' ({channel})")
async def load_cogs():
for filename in os.listdir('./cogs'):
if filename.endswith('.py'):
await bot.load_extension(f'cogs.{filename[:-3]}')
#bot.event
async def on_ready():
print(f'{bot.user} is now running.')
async def main():
await load_cogs()
async with bot:
TOKEN = os.getenv('TOKEN')
await bot.start(TOKEN)
asyncio.run(main())
ping.py
import discord
from discord.ext import commands
import asyncio
class ping(commands.Cog):
def __init__(self, bot):
self.bot = bot
#commands.command(name="ping", description="Returns Pong!")
async def ping(self, ctx):
await ctx.send("Pong!")
async def setup(bot: commands.Bot):
await bot.add_cog(ping(bot))
After running bot display 0 errors. I tried to changing intents from default() to all() but it didn't help.
You override the on_message event, and you don't have a process_commands in it, so the bot won't be processing any commands.
You can fix this by adding bot.process_commands inside the event.
#bot.event
async def on_message(message):
    ...
    await bot.process_commands(message)
Or register it as a listener so it doesn't override the default event.
#bot.listen()
async def on_message(message):
    ...

Check if user react with an certian emoji with cogs

I have a problem. How can I check which emoji the user reacted with? That did not work for me How do you check if a specific user reacts to a specific message [discord.py]
I want to check if the reaction is ✅ or ❌
folder structure
├── main.py
├── cogs
│ ├── member.py
The problem is that I don't get an error message. Nothing happens. As soon as I react with an emoji, nothing happens.
member.py
import discord
from discord.ext import commands
from datetime import datetime
class command(commands.Cog):
def __init__(self, bot):
self.bot = bot
#commands.Cog.listener()
async def on_message(self, message):
...
...
for emoji in emojis:
await msg.add_reaction(emoji)
await message.author.send('Send me that ✅ reaction, mate')
def check(reaction, user):
return user == message.author and str(reaction.emoji) == '✅'
res = await self.bot.wait_for(
"reaction_add",
check=check, timeout=None
)
print(res.emoji)
if res.content.lower() == "✅":
await message.author.send("Got it")
else:
await message.author.send("Thanks")
confirmation = await self.bot.wait_for("reaction_add", check=check)
await message.author.send("You responded with {}".format(reaction.emoji))
async def setup(bot):
await bot.add_cog(command(bot))
import asyncio
import os
from dotenv import load_dotenv
import discord
from discord.ext import commands
from discord.ext.commands import has_permissions
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
import discord
from discord.utils import get
class MyBot(commands.Bot):
def __init__(self):
intents = discord.Intents.default()
intents.message_content = True
super().__init__(command_prefix=commands.when_mentioned_or('-'), intents=intents, max_messages=1000)
async def on_ready(self):
print(f'Logged in as {self.user} (ID: {self.user.id})')
async def setup_hook(self):
for file in os.listdir("./cogs"):
if file.endswith(".py"):
extension = file[:-3]
try:
await self.load_extension(f"cogs.{extension}")
print(f"Loaded extension '{extension}'")
except Exception as e:
exception = f"{type(e).__name__}: {e}"
print(f"Failed to load extension {extension}\n{exception}")
bot = MyBot()
bot.run(TOKEN)
You're using a function called check, and it doesn't exist - like your error is telling you. There's one in your class, but that isn't in the same scope so you can't just call it using its name.
To access a method in a class, use self.<name>.
Also, you should only pass the check function, not call it.
(..., check=self.check
EDIT the code in the original question was edited. You're not loading your cogs asynchronously. Extensions & cogs were made async in 2.0. Docs: https://discordpy.readthedocs.io/en/stable/migrating.html#extension-and-cog-loading-unloading-is-now-asynchronous
Put this code in your #commands.Cog.listener() decorator, and the code will work if your cogs loader is working. If you would like me to show you my cogs loader, I can.
accept = '✅'
decline = '🚫'
def check(reaction, user):
return user == author
messsage = await ctx.send("test")
await message.add_reaction(accept)
await message.add_reaction(decline)
reaction = await self.bot.wait_for("reaction_add", check=check)
if str(reaction[0]) == accept:
await ctx.send("Accepted")
elif str(reaction[0]) == decline:
await ctx.send("Denied")

Discord.py - Can't get custom commands to work within inherited class

I'm trying to get custom commands to work in my Discord server. But it doesn't work when I'm not using a decorator, and I do not know how to make it work within a class.
Please help.
(XXX.. just replaces an ID here)
Please have a look at add_my_commands() function. This one should be able to take the prefix and respond with the info. This doesn't work currently.
I have a main.py file which runs separately, as follows:
# Import discord.py
import discord
from discord.ext import commands
# Import Bot Token
from apikeys import *
# Import classes
from steward_bot import MyClient
intents = discord.Intents.default() # or .all() if you ticked all, that is easier
intents.message_content = True
intents.members = True # If you ticked the SERVER MEMBERS INTENT
# Initialize client
bot = MyClient(command_prefix="!", intents=intents)
bot.run(DISCORD_TOKEN)
The MyClient class:
class MyClient(commands.Bot):
def __init__(self, *args, command_prefix, **kwargs):
super().__init__(
*args, command_prefix=command_prefix, case_insensitive=True, **kwargs
)
self.target_message_id = XXXX
self.add_my_commands()
async def on_ready(self):
print("We have logged in as {0.user}".format(self))
print("---------------------------------------------")
async def on_member_remove(self, member):
channel = self.get_channel(XXXX)
await channel.send("Goodbye")
async def on_raw_reaction_add(self, payload):
"""
Give a role based on a reaction emoji
"""
if payload.message_id != self.target_message_id:
return
guild = self.client.get_guild(payload.guild_id)
print(payload.emoji.name)
print("Hello")
# Responding to messages
async def on_message(self, message):
if message.author == self.user:
return
if message.content == "Test":
await message.channel.send("Hey hey chill")
if message.content == "cool":
await message.add_reaction("\U0001F60E")
if message.content == "give me our prefix":
await message.channel.send(str(self.command_prefix))
await self.process_commands(message)
# Throws out reactions to messages
async def on_reaction_add(self, reaction, user):
await reaction.message.channel.send(f"{user} reacted with {reaction.emoji}")
def add_my_commands(self):
#self.command(name="info", pass_context=True)
async def info(ctx):
"""
ctx - context (information about how the command was executed)
info
"""
print(ctx)
await ctx.send("Hello X")
await ctx.send(ctx.guild)
await ctx.send(ctx.author)
await ctx.send(ctx.message.id)
Within the server, I want to run the command "!info" and get the information out. Would appreciate any help!
No need to define your entire bot within a class. Create a main.py file with your bot defined and import cogs from there. I'd also set up my commands through a cog with commands.command().
Example of how I'd go about adding an !info command:
main.py
import discord
from discord.ext import commands
from info import InfoCog
intents = discord.Intents.default()
intents.members = True
intents.guilds = True
intents.messages = True
intents.reactions = True
intents.presences = True
# Initialize client
bot = commands.Bot(command_prefix='!', intents=intents)
bot.add_cog(InfoCog(bot))
#bot.event
async def on_ready(self):
print("We have logged in as {0.user}".format(self))
print("---------------------------------------------")
bot.run(TOKEN)
info.py
import discord
from discord.ext import commands
class InfoCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
#commands.command()
async def info(self, ctx):
await ctx.send('Info')
Or, you could jumble everything into one file. This is how I used to do it with all my commands & events. It was easier to get the hang of at first.
main.py
# Import discord.py
import discord
from discord.ext import commands
intents = discord.Intents.default()
intents.members = True
intents.guilds = True
intents.messages = True
intents.reactions = True
intents.presences = True
bot = commands.Bot(command_prefix='!', intents=intents)
#bot.event
async def on_ready(bot):
print("We have logged in as {0.user}".format(bot))
print("---------------------------------------------")
# [...]
#bot.command()
async def info(ctx):
await ctx.send('info')
# [...]
#bot.event
async def on_message(message):
if message.author == bot.user:
return
if message.content == "give me our prefix":
await message.channel.send(str(bot.command_prefix))
if message.content == "Test":
await message.channel.send("Hey hey chill")
# [...]
#bot.event()
async def on_member_remove(member):
channel = bot.get_channel(CHANNELID)
await channel.send(f"Goodbye, {member}")
# [...]
bot.run(TOKEN)

Discord greetings with cogs ,on_member_join , doen't work

My on_member_join listener doesn't execute properly. The idea is that when a new person enters my discord, my bot greets them with a custom message.
There are no syntax errors and the class loads correctly. The on_ready listener responds correctly with Welcome: ON. If I try to do a debug print it is not executed.
Where am I doing wrong? I don't understand, it seems correct to me.
import discord
from discord.ext import commands
intents = discord.Intents.default()
intents.members = True
client = discord.Client(intents=intents)
class Welcome(commands.Cog):
def __init__(self,client):
self.client=client
#commands.Cog.listener()
async def on_ready(self):
print("Welcome: ON")
#commands.Cog.listener()
async def on_member_join(self, member):
guild= client.get_guild(828676048039706694)
channel=guild.get_channel(828676048039706697)
if channel is not None:
await channel.send(f'Welcome {member.mention}.')
#commands.command()
async def Modulo_benvenuto(self,ctx):
await ctx.send('')
def setup(client):
client.add_cog(Welcome(client))
This is my main file:
import discord
import os
from discord.ext import commands
client = commands.Bot(command_prefix = '.')
#client.command()
async def load(ctx, extension):
client.load_extension(f'cogs.{extension}')
#client.command()
async def unload(ctx, extension):
client.unload_extension(f'cogs.{extension}')
#client.command()
async def reload(ctx, extension):
client.unload_extension(f'cogs.{extension}')
client.load_extension(f'cogs.{extension}')
for filename in os.listdir('./cogs'):
if filename.endswith('.py'):
client.load_extension(f'cogs.{filename[:-3]}')
client.run('TOKEN')
With a new bot it works, this is the code:
import discord
from discord.ext import commands
intents = discord.Intents.default()
intents.members = True
client = discord.Client(intents=intents)
#client.event
async def on_ready():
print("Bot is on")
#client.event
async def on_member_join(member):
print(member)
await member.send("hello")
guild = client.get_guild(831588406089744435)
channel = discord.utils.get(member.guild.channels, id=831588406089744438)
if guild:
print("guild ok")
else:
print("guild not found")
if channel is not None:
await channel.send(f'Welcome to the {guild.name} Discord Server, {member.mention} ! :partying_face:')
else:
print("id channel wrong")
client.run('TOKEN')
For the on_member_join() event reference, you need the Server Members Intent privileged gateway intent to be on. This has to be done both in your bot's page as well as in your script (which you already have done):
Go to the Discord Developer Portal.
Select the application and, under settings, navigate to Bot.
If you scroll down just a bit, you'll reach a section title Privileged Gateway Intents and, under that, SERVER MEMBERS INTENT.
Toggle the SERVERS MEMBERS INTENT to ON.
In the image below, it would be the second of the privileged gateway intents.
The issue with your code is likely because you have a discord.Bot instance defined in both your cog file as well as your main file. Since setup(client) is defined in your cog file and client.load_extension() is called in your main file, you should delete the following lines from your cog file:
cog.py
intents = discord.Intents.default()
intents.members = True
client = discord.Client(intents=intents)
However, to conserve the Intents, you'll want to add the following lines before your discord.Bot() call:
main.py
from discord.ext import commands
intents = discord.Intents.default()
intents.members = True
client = commands.Bot(command_prefix=".", intents=intents)
For your code, I would recommend using the Client.fetch_channel method, since it eliminates the possibility that an incorrect Guild ID results in channel being None.
async def on_member_join(self, member):
channel = await client.fetch_channel(1234567890)
if channel is not None:
await channel.send(f"Welcome {member.mention}.")
Or, you could just use discord.utils.get() and member.guild.channels:
async def on_member_join(self, member):
channel = discord.utils.get(member.guild.channels, id=1234567890)
if channel is not None:
await channel.send(f"Welcome {member.mention}.")
Just a suggestion for reducing potential bugs.
HOW TO FIX :
MAIN FILE
import discord
import os
from discord.ext import commands
intents = discord.Intents.default()
client = commands.Bot(command_prefix = '.', intents=intents)
intents.members = True
#client.command()
async def load(ctx, extension):
client.load_extension(f'cogs.{extension}')
#client.command()
async def unload(ctx, extension):
client.unload_extension(f'cogs.{extension}')
#client.command()
async def reload(ctx, extension):
client.unload_extension(f'cogs.{extension}')
client.load_extension(f'cogs.{extension}')
for filename in os.listdir('./cogs'):
if filename.endswith('.py'):
client.load_extension(f'cogs.{filename[:-3]}')
client.run('TOKEN')
COG FILE
import discord
from discord.ext import commands
class Welcome(commands.Cog):
def __init__(self, client):
self.client=client
#commands.Cog.listener()
async def on_ready(self):
print("Welcome: ON")
#commands.Cog.listener()
async def on_member_join(self, member):
print(member)
await member.send("hello")
guild = self.client.get_guild(831588406089744435)
channel = discord.utils.get(member.guild.channels, id=831588406089744438)
if guild:
print("guild ok")
else:
print("guild not found")
if channel is not None:
await channel.send(f'Welcome to the {guild.name} Discord Server, {member.mention} ! :partying_face:')
else:
print("id channel wrong")
#commands.command()
async def Modulo_benvenuto(self, ctx):
await ctx.send('test')
def setup(client):
client.add_cog(Welcome(client))

Discord.py Priveleged Intents stopping on_message and commands from working

from discord.ext import commands
from discord.ext import tasks
import random
import typing
from discord import Status
from discord import Activity, ActivityType
from discord import Member
from discord.ext.commands import Bot
from asyncio import sleep
intents = discord.Intents()
intents.members = True
intents.presences = True
print(discord.__version__)
bot = commands.Bot(command_prefix='!', intents =intents)
...
...
#bot.event
async def on_ready():
print('hiii, We have logged in as {0.user}'.format(bot))
await bot.change_presence(activity=discord.Game(name="Exploring the archives"))
bot.loop.create_task(status())
#bot.event
async def on_message(message):
if message.author.id == BOT_ID:
return
if message.content.startswith('$hello'):
await message.channel.send('Hello Dad!')
await bot.process_commands(message)
#bot.event
async def on_member_update(before,after):
if before.status != str(after) :
print("{}, #{} has gone {} .".format(after.name,after.id,after.status))
#bot.event
async def on_member_remove(member):
print(f'{member} has left a server.')
#bot.event
async def on_member_join(member):
print(f'{member} has joined a server.')
await member.send('Private message')
#bot.command(pass_context=True)
async def summon(ctx):
await ctx.send ("I have been summoned by the mighty {}, ".format(ctx.message.author.mention) + " bearer of {}. What is your command?".format(ctx.message.author.id))
Hello. I was trying to build a discord Bot and I was mostly successful except from the fact that I couldn't get on_member_join & on_member_update to work (they didn't even seem to register a user entering or leaving the server so I concluded that I lacked some permissions). After a lot of searching I found this in the discord.py documentation and after adding the intents bit at the beggining of my code the on_member_join, on_member_remove & on_member_update worked, but the on_message event and all the commands do not work (i added a print at the beginning of on_message and nothing happened).
After some debugging I found out that the code that stops the commands from responding seems to be ,intents = intents) . However when this is removed, the on_member_join, on_member_remove & on_member_update (understandably) do not trigger.
Any advice?
I'm guessing that using intents = discord.Intents() has all intents set to False.
You can either use intents.messages = True or intents.all().

Categories