I am a new user of discord.py, and i'm facing an issue with a simple code :
from dotenv import load_dotenv
import discord
from discord.ext.commands import Bot
import os
load_dotenv()
class Bothoven:
def __init__(self):
self.version = 0.1
self.client = discord.Client()
self.bot = Bot(command_prefix='$')
#self.bot.event
async def on_ready():
print('We have logged in as {0.user}'.format(self.bot))
#self.bot.command()
async def test(ctx):
print(ctx)
await ctx.send("oui maitre")
self.bot.run(os.getenv("BOT_TOKEN"))
When I run it, everything seems good, the bot prints :
We have logged in as Bothoven#9179
But when I type something in the guild, it rises an exception :
Ignoring exception in on_message
Traceback (most recent call last):
File "D:\PROJETS\Bothoven\venv\lib\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "D:\PROJETS\Bothoven\venv\lib\site-packages\discord\ext\commands\bot.py", line 942, in on_message
await self.process_commands(message)
File "D:\PROJETS\Bothoven\venv\lib\site-packages\discord\ext\commands\bot.py", line 935, in process_commands
if message.author.client:
AttributeError: 'Member' object has no attribute 'client'
I understand the error, and I agree that author has no attribute client, but this statement is in bot.py, a library file.
Have you some idea of how to proceed ?
I'm runing python3.8 and discord.py 1.6
EDIT :
Despite pip was telling me all packages were up to date, deleting my venv and rebuilding it resolved my issue.
There are a few things wrong with your Cog setup:
You have to use commands.Cog.listener() to exploit events
To create commands, use the commands.command() decorator
Your self.bot definition is wrong and you don't need self.client
Here how you would setup your cog correctly:
from os import environ
from discord.ext import commands
bot = commands.Bot(command_prefix='$')
class Bothoven(commands.Cog):
def __init__(self, bot):
self.bot = bot
#commands.Cog.listener()
async def on_ready():
print('Logged in as {0.user}'.format(self.bot))
#commands.command()
async def test(ctx):
print(ctx)
await ctx.send("Oui maƮtre")
bot.add_cog(Bothoven(bot))
bot.run(environ["BOT_TOKEN"])
You can find more about cogs here.
EDIT : Turns out it was a venv issue, re-building it solved the problem.
Related
I've been working on a discord bot for a personal server. I want to use cogs to separate the music player functionality from the main file.
I am raising this error when I load my main.py file:
discord.ext.commands.errors.ExtensionFailed: Extension 'cogs.cog' raised an error: TypeError: object NoneType can't be used in 'await' expression
My main.py file code related to cogs is this:
# Cogs
async def load_extensions():
for filename in os.listdir("./cogs"):
if filename.endswith(".py"):
# cut off the .py from the file name
await bot.load_extension(f"cogs.{filename[:-3]}")
async def main():
async with bot:
await load_extensions()
await bot.start(os.getenv('TOKEN'))
asyncio.run(main())
In my cogs.py file:
import os, discord
from discord.ext import commands
class Test(commands.Cog):
def __init__(self, client):
self.client = client # sets the client variable so we can use it in cogs
self.intents = discord.Intents.default()
self.intents.message_content = True
#commands.command()
async def command(self, ctx):
await ctx.send("Yes?")
def setup(client):
client.add_cog(Test(client, ))
I initially had an error about intents, which was solved by adding self.intents, but I haven't been able to solve this issue. I have utilized StackOverflow, but haven't found anything specific to my issue.
I am trying to make a Discord bot and one of the features is a welcoming from my bot using on_member_join. This is the event:
#bot.event
async def on_member_join(member, self):
embed = discord.Embed(colour=discord.Colour(0x95efcc), description=f"Welcome to Rebellions server! You are the{len(list(member.guild.members))}th member!")
embed.set_thumbnail(url=f"{member.avatar_url}")
embed.set_author(name=f"{member.name}", icon_url=f"{member.avatar_url}")
embed.set_footer(text=f"{member.guild}", icon_url=f"{member.guild.icon_url}")
embed.timestamp = datetime.datetime.utcnow()
await welcome_channel.send(embed=embed)
Although when the bot is working and running and someone joins my server I get this error:
[2022-11-07 19:38:10] [ERROR ] discord.client: Ignoring exception in on_member_join
Traceback (most recent call last):
File "C:\Users\stene\AppData\Local\Programs\Python\Python311\Lib\site-packages\discord\client.py", line 409, in _run_event
await coro(*args, **kwargs)
File "C:\Users\stene\OneDrive\Documents\GitHub\bot\main.py", line 25, in on_member_join
embed.set_thumbnail(url=f"{member.avatar_url}")
^^^^^^^^^^^^^^^^^
AttributeError: 'Member' object has no attribute 'avatar_url'
I am running the latest version of discord.py and python.
Thanks!
welcome cog:
import discord
from discord.ext import commands
import asyncio
import datetime
class WelcomeCog(commands.Cog, name="Welcome"):
def __init__(self, bot):
self.bot = bot
#commands.Cog.listener()
async def on_member_join(self, member):
embed = discord.Embed(colour=discord.Colour(0x95efcc), description=f"Welcome to Rebellions server! You are the{len(list(member.guild.members))}th member!")
embed.set_thumbnail(url=member.avatar.url)
embed.set_author(name=member.name, icon_url=member.avatar.url)
embed.set_footer(text=member.guild)
embed.timestamp = datetime.datetime.utcnow()
channel = self.bot.get_channel(1038893507961692290)
await channel.send(embed=embed)
async def setup(bot):
await bot.add_cog(WelcomeCog(bot))
print("Welcome cog has been loaded successfully!")
In discord.py 2.0 the attribute Member.avatar_url got removed and replaced by Member.avatar. To access the URL, you should use member.avatar.url.
Check out the migration guide for similar instances. Using pip freeze you can check which version of discord.py you have installed, but I assume it's 2.x, and probably you followed a tutorial or copied a code example that used discord.py 1.x.
Following your code you have several errors, which can be corrected in the following code:
First: async def on_member_join(member, self): is an incorrect code.
self always comes before any other argument if this event is in a cog file, but still it isn't a required argument so completely remove it. The correct code for this line is async def on_member_join(member):
Second: Make sure you're using the correct event listener.
#client.event or #bot.event if this is in your Main file, and #commands.Cog.listener() if this is in your cog file.
Third: Please change (member, self): to (member:discord.Member)
Good luck! :D
i splitted some code into another file and i get "'NoneType' object has no attribute 'send'"
as i read , its should be a error like "the channel dont exist" "the bot dont have permission"
but tahts wrong , i can send messages just fine from the main.py in the specific channel just not from the loging.py . here my code .
#bot.py
import discord
import asyncio
from discord.ext import commands
import os
from dotenv import load_dotenv
from datetime import datetime, timedelta, date, time, timezone
import time
import loging
load_dotenv()
TOKEN = os.getenv("DISCORD_TOKEN")
bot = commands.Bot(command_prefix=commands.when_mentioned_or("$"), help_command=None)
#bot.command(name='test', help='this command will test')
async def test(ctx):
await loging.comlog(ctx)
bot.run(TOKEN)
#loging.py
import discord
import asyncio
from discord.ext import commands
import os
from datetime import datetime, timedelta, date, time, timezone
import time
bot = commands.Bot(command_prefix=commands.when_mentioned_or("$"), help_command=None)
timestamp = datetime.now()
timenow = str(timestamp.strftime(r"%x, %X"))
async def comlog(ctx):
channel = ctx.channel
channelid = ctx.channel.id
username = ctx.author
usernameid = ctx.author.id
logingchan = await bot.fetch_channel(983811124929630239)
em = discord.Embed(title=f'${ctx.command}', description=f'{timenow}', color=0x00FF00)
em.set_thumbnail(url=username.avatar_url)
em.add_field(name="Channel:", value=f'{ctx.channel.mention} \n{channelid}', inline=True)
em.add_field(name="User:", value=f'{username}\n{usernameid}', inline=True)
print(f'{timenow}: $help: in "{channel}" by "{username}"')
await logingchan.send(embed=em)
await ctx.message.delete()
for testing i replaced the cahnnel with "ctx" and this works just fine
Ignoring exception in command test:
Traceback (most recent call last):
File "C:\Users\Asuka\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Users\Asuka\Desktop\PROJECT\Discord_Bot\bot.py", line 149, in test
await loging.comlog(ctx)
File "C:\Users\Asuka\Desktop\PROJECT\Discord_Bot\loging.py", line 23, in comlog
await logingchan.send(embed=em)
AttributeError: 'NoneType' object has no attribute 'send'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\Asuka\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\Asuka\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 863, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\Asuka\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 94, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'NoneType' object has no attribute 'send'
yea i know ppl say now , the cahnnel dont exist , the bot dont have premmision . false , why can i send in the exact same channel with my main.py but not with the loging.py . also , if i dont send in a specific channel , and send the embed in channel where the command got used , and i use the channel with the id , my bot can reply in the exact same channel.
You have two separate bots in your two modules.
In the bot.py, you make a bot that you later run with the run method. This bot is fine, and it's connected to discord and can do a bunch of things.
However, you made a second bot in logging.py. This bot isn't actually doing anything and it was never started, so any attempts to get or fetch anything from discord will fail. What you need to do is to give the bot instance to the other module.
You can do this by either putting it into a class, or passing the bot as an argument, which I will show here:
async def comlog(bot, ctx):
channel = ctx.channel
channelid = ctx.channel.id
username = ctx.author
usernameid = ctx.author.id
logingchan = await bot.fetch_channel(983811124929630239)
em = discord.Embed(title=f'${ctx.command}', description=f'{timenow}', color=0x00FF00)
em.set_thumbnail(url=username.avatar_url)
em.add_field(name="Channel:", value=f'{ctx.channel.mention} \n{channelid}', inline=True)
em.add_field(name="User:", value=f'{username}\n{usernameid}', inline=True)
print(f'{timenow}: $help: in "{channel}" by "{username}"')
await logingchan.send(embed=em)
await ctx.message.delete()
# Then pass in the bot when you call the function
#bot.command(name='test', help='this command will test')
async def test(ctx):
await loging.comlog(bot, ctx)
Then you can just delete your second bot definition in logging.py.
If you want permission failure messages you need to use try/except:
try:
await logingchan.send(embed=em)
except discord.errors.Forbidden:
# don't have permissions, do something here
There isn't a bot variable in loging.py
If you want to split bot commands you should make cogs instead
Cogs are like command groups
This is how you do it:
# main.py
from discord.ext import commands
from loging import my_commands_cog
bot = commands.Bot(command_prefix = "idk!")
bot.add_cog(my_commands_cog)
# loging.py
from discord.ext import commands
class my_commands_cog(commands.Cog)
#commands.command(name = "idk")
async def idk(ctx, * , arg):
# stuff
print("idk")
Check it out here: Cogs
I am trying to make a "!invite" command to generate an invite link to the server and send it to the user's DM.
The command works, but I am getting the following error on console:
Ignoring exception in on_message
Traceback (most recent call last):
File "C:\Users\001\Envs\Pix\lib\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "C:\Users\001\PycharmProjects\Testing bot\cogs\invite.py", line 27, in on_message
if ctx.author.guild_permissions.administrator:
AttributeError: 'ClientUser' object has no attribute 'guild_permissions'
Nevertheless, I get the link: My DM screenshot.
How can I fix this error?
Code:
from discord.ext import commands
from var.canais import inviteChannel
class Invite(commands.Cog):
def __init__(self, client):
self.client = client
#commands.command(
name='invite',
pass_context=True
)
async def invite(self, ctx):
invitelink = await ctx.channel.create_invite(
max_uses=1,
unique=True
)
if inviteChannel:
await ctx.message.delete()
await ctx.author.send(f'Invite link: {invitelink}')
#commands.Cog.listener()
async def on_message(self, ctx):
if inviteChannel:
if ctx.author.guild_permissions.administrator:
return
else:
if not ctx.content.startswith('!invite'):
await ctx.delete()
def setup(client):
client.add_cog(Invite(client))
This error is occurring because the on_message event is also called when the bot sends a message, and in your case the bot is sending the message in a dm, therefore it should be a User object (Member objects are guild only), and user objects don't have permissions since they are not inside a server. It's a ClientUser object instead of User which is a special class like User that is unique to the bot. this is a separate class compared to User because this has some special methods that only the bot can use like one for editing the bot's name and more
to fix this just ignore if the message is sent from a bot so the code would be
#commands.Cog.listener()
async def on_message(self, ctx):
if message.author.bot:
return
if inviteChannel:
if ctx.author.guild_permissions.administrator:
return
if not ctx.content.startswith('!invite'):
await ctx.delete()
Here I added if message.author.bot: return so that it stops the function execution if the author is a bot. and I also removed the unnecessary else statement
As the error says:
The line
if ctx.author.guild_permissions.administrator:
throw an AttributeError error because 'ctx.author' (of type ClientUser) does not have guild_permissions attribute.
The error massage also entail that the error was ignored, and so the code proceed without stoping.
I found this
answer that might help you overcome this issue
good luck!
Today I wanted to try to create a discord bot with python. The problem i have is, that there is always an error message when I start the program:
Traceback (most recent call last):
File "D:\...\Discord Bot\PythonGPU_Bot\bot.py", line 1, in <module>
import discord
File "C:\Users\...\Python\Python39\lib\discord\__init__.py", line 4, in <module>
client = discord.Client()
AttributeError: partially initialized module 'discord' has no attribute 'Client' (most likely due to a circular import)
Thats the Error message I always get.
This is my script:
import discord
import asyncio
client = discord.Client()
#client.event
async def on_ready():
print('Logged in as {}'.format(client.user.name))
client.loop.create_task(status_task())
async def status_task():
while True:
await client.change_presence(activity=discord.Game('Hello <:'))
await asyncio.sleep(1)
await client.change_presence(activity=discord.Game('Hello c:'))
await asyncio.sleep(1)
#client.event
async def on_message(message):
if message.auther.bot:
return
if '.status' in message.content:
await message.channel.send('SSSS')
client.run('ID')
I hope someone can help me out.
The name of your file is discord.py, rename the file
rename it to bot.py or main.py or anything you like and your issue will be fixed
Why does it happen?
Since your file name is discord.py, it is actually importing that file and not the actual discord.py module you installed with pip.