How to send a embed message discord.py - python

I am trying to send this embed message to a channel, I will keep trying and changing things around and it does not want to work, the problem is that it does not recognize the ".send", because it can not be called with channel. I would really appreciate it if someone would explain this to me. MY ERROR:
Traceback (most recent call last):
File "C:\Users\jaspe\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "c:\Users\jaspe\OneDrive\Desktop\DISCORD_BOT\zdiscord bot.py", line 19, in on_message_edit
await channel.send(embed=embed)
AttributeError: 'NoneType' object has no attribute 'send'
My code:
#bot.event
async def on_message_edit(message_before, message_after):
embed = discord.Embed(title="{} edited a message".format(message_before.author.name),description="", color=0xFF0000)
embed.add_field(name=message_before.content, value="This is the message before any edit",inline=True)
embed.add_field(name=message_after.content, value="This is the message after the edit",inline=True)
channel = bot.get_channel("My channel id")
await channel.send(embed=embed)

Change this part:
channel = bot.get_channel("My channel id")
To:
channel = discord.utils.get(message_before.guild.text_channels, id=put_id_here)
The way you are getting the channel is probably returning None, which of course has no method named send

The channel ID you are trying to provide must be an INTEGER, but you provided a STRING.
#bot.event
async def on_message_edit(message_before, message_after):
embed = discord.Embed(title="{} edited a message".format(message_before.author.name),description="", color=0xFF0000)
embed.add_field(name=message_before.content, value="This is the message before any edit",inline=True)
embed.add_field(name=message_after.content, value="This is the message after the edit",inline=True)
channel = bot.get_channel(1234567890)
await channel.send(embed=embed)```

Related

Im trying to write a bot that automaticly downloads images and then sends them into a diffrent channel, but im running into an Error

The full error Code is
Ignoring exception in on_message
Traceback (most recent call last):
File "C:\...\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "C:\...\DiscordBot\cogs\Post_image.py", line 33, in on_message
await self.bot.send(self.bot.get_channel("images")
file=discord.File(f"images/{picture}"))
AttributeError: 'Bot' object has no attribute 'send'
I tried moving the channel variable around but that didnt help and i didnt find any solution online.
For completion my code in rewrite
#commands.Cog.listener()
async def on_message(self, message):
if message.author == self.bot.user:
return
if message.author.bot:
return
image_types = ["png", "jpeg", "gif", "jpg"]
# channel = self.bot.get_channel("images")
for attachment in message.attachments:
if any(attachment.filename.lower().endswith(image) for image in image_types):
await attachment.save(f"./images/{attachment.filename}")
for picture in os.listdir("images"):
if picture.endswith(".png") or picture.endswith(".jpeg") or picture.endswith(".jpg"):
await self.bot.send(self.bot.get_channel("images"), file=discord.File(f"images/{picture}"))
os.remove(f"images/{picture}")
self.bot and send do not go together. What I would do is make a variable that defines the channel that you want the images to be sent to then make the bot send it. Something like this..
channel = self.bot.get_channel(imagechannelidhere)
await channel.send(file=discord.File(f"images/{picture}"))
channel will make the bot find the channel that you want the images to be sent to.
So we make the bot send the file to the channel by doing await channel.send
What I mean by imagechannelidhere is the channel ID of the channel you want the images to be sent to by your bot. You must put the ID, not the name. No quotation marks are needed.

Discord.py - How to get A's ID from B's message when B is sending a message that is replying to A's original message?

I'm trying to make a discord bot to automate playing my friend's bot's game. When my friend's bot sends a message replying to your message after you use a specific command. I want to be able to check if the message the bot sends is replying to my message specifically. This is what I've got so far:
#bot.event
async def on_message(message):
if message.author.id == botId:
content = str(message.content)
reference = message.reference
if reference.message_id.author.id == myId:
word = content.split('`')[1].split('`')[0]
await bot.send_message(message.channel, word)
I know reference.message_id.author.id will not work since author.id is incompatible with reference.message_id, but I cannot find something that will work with it.
The Error:
Ignoring exception in on_message
Traceback (most recent call last):
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "C:\Users\user\OneDrive\Desktop\User\Projects\Programming\Python\Discord Bot\Waterhole Dryer\bot.py", line 30, in on_message
if reference.message_id.author.id == myId:
AttributeError: 'int' object has no attribute 'author'
Thanks!
Alrighty, so... I found a bit of a workaround to this...
#bot.event
async def on_message(message):
if message.author.id == botId:
guild = bot.get_guild(guildId)
channel = guild.get_channel(message.reference.channel_id)
msg = await channel.fetch_message(message.reference.message_id)
if msg.author.id == myId:
word = content.split('`')[1].split('`')[0]
await channel.send(word)
Basically, I made a new message object. I hope this helps anyone else with my problem.

Discord bot on_join_guild dm everyone

I am trying to dm everyone in the server when the bot is added to the server using the on_join_guild().
The code for it
#client.event
async def on_guild_join(guild):
for member in guild.members:
await member.create_dm()
embedVar = discord.Embed(title="Hi", description="Hello", color=0x00ff00)
await member.dm_channel.send(embed=embedVar)
But whenever I add the bot to server, it dms everyone in the server which is expected but a error also pops in the console.
Ignoring exception in on_guild_join
Traceback (most recent call last):
File "C:\Users\Khusi\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File ".\time-turner.py", line 42, in on_guild_join
await member.create_dm()
File "C:\Users\Khusi\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\discord\member.py", line 110, in general
return getattr(self._user, x)(*args, **kwargs)
AttributeError: 'ClientUser' object has no attribute 'create_dm'
What am I doing wrong?
After replicating your code, I found that your error only appears to happen if the bot tries to message itself. You would also get an error if your bot attempts to message another bot (Cannot send messages to this user). You can just use pass if your bot can't message a user or if it tries to message itself.
#client.event
async def on_guild_join(ctx):
for member in ctx.guild.members:
try:
await member.create_dm()
embedVar = discord.Embed(title="Hi", description="Hello", color=0x00ff00)
await member.dm_channel.send(embed=embedVar)
except:
pass
If the above still doesn't work, just as NerdGuyAhmad had said, you need to enable intents, at the very least member intents. View this link here: How do I get intents to work?

How to make the bot send a message with a invite link of the guild to a specific channel in my guild whenever it joins a new server?

So basically what I want is whenever my bot joins any guild it should send a message to a particular channel in my server stating that it is invited to a server with its name and if possible also the invite link of that server. I tried a few things but they never really worked.
#client.event
async def on_guild_join(guild):
channel = client.get_channel('736984092368830468')
await channel.send(f"Bot was added to {guild.name}")
It didn't work and throws the following error:
Ignoring exception in on_guild_join
Traceback (most recent call last):
File "C:\Users\Rohit\AppData\Roaming\Python\Python37\site-packages\discord\client.py", line 312, in _run_event
await coro(*args, **kwargs)
File "c:\Users\Rohit\Desktop\discord bots\test bot\main.py", line 70, in on_guild_join
await channel.send(f"Bot was added to {guild.name}")
AttributeError: 'NoneType' object has no attribute 'send'
And I really don't have any idea how to make the bot send invite link of the guild with the guild name.
The reason why you get the 'NoneType' object has no attribute 'send' exception is because your bot failed to find the channel provided.
This line:
channel = client.get_channel('736984092368830468')
Will not work, this is because the channel ID must be an integer, you can try this:
channel = client.get_channel(int(736984092368830468))
If this still does not work, make sure the bot has access to the channel, the channel exists and the ID provided is correct.
Here's how you would get an invite, name and guild icon assuming your bot has the required permissions.
#client.event
async def on_guild_join(guild):
channel = client.get_channel(745056821777006762)
invite = await guild.system_channel.create_invite()
e = discord.Embed(title="I've joined a server.")
e.add_field(name="Server Name", value=guild.name, inline=False)
e.add_field(name="Invite Link", value=invite, inline=False)
e.set_thumbnail(url=guild.icon_url)
await channel.send(embed=e)

welcome/goodbye using discord.py

I'm trying to create a bot that greets a user that joins a server. But make it so that the person is greeted in the server itself rather than as a DM (which most tutorials I've found teach you how to do).
This is what I've come up with so far.
#bot.event
async def on_member_join(member):
channel = bot.get_channel("channel id")
await bot.send_message(channel,"welcome")
but, it doesn't work and instead throws up this error.
Ignoring exception in on_member_join
Traceback (most recent call last):
File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python36\lib\site-
packages\discord\client.py", line 307, in _run_event
yield from getattr(self, event)(*args, **kwargs)
File "C:\Users\Lenovo\Documents\first bot\bot.py", line 26, in
on_member_join
await bot.send_message(channel,"welcome")
File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python36\lib\site-
packages\discord\client.py", line 1145, in send_message
channel_id, guild_id = yield from self._resolve_destination(destination)
File "C:\Users\Lenovo\AppData\Local\Programs\Python\Python36\lib\site-
packages\discord\client.py", line 289, in _resolve_destination
raise InvalidArgument(fmt.format(destination))
discord.errors.InvalidArgument: Destination must be Channel, PrivateChannel,
User, or Object. Received NoneType
You aren't passing the correct id to get_channel, so it's returning None. A quick way to get it would be to call the command
from discord.ext import commands
bot = commands.Bot(command_prefix='!')
#bot.command(pass_context=True)
async def get_id(ctx):
await bot.say("Channel id: {}".format(ctx.message.channel.id))
bot.run("TOKEN")
You could also modify your command to always post in a channel with a particular name on the server that the Member joined
from discord.utils import get
#bot.event
async def on_member_join(member):
channel = get(member.server.channels, name="general")
await bot.send_message(channel,"welcome")
The answer by Patrick Haugh is probably your best bet, but here are a few things to keep in mind.
The Member object contains the guild (server), and the text channels the server contains.
By using member.guild.text_channels you can ensure the channel will exist, even if the server does not have a 'general' chat.
#bot.event
async def on_member_join(member):
channel = member.guild.text_channels[0]
await channel.send('Welcome!')
Try this:
#bot.event
async def on_member_join(member):
channel = discord.utils.get(member.guild.channels, name='the name of the channel')
await channel.send(f'Enjoy your stay {member.mention}!')

Categories