Skip to content
Advertisement

Getting an error when trying to get an attachment url in discord.py

I’m trying to make a discord bot that would repost art submissions to the art channel after they are approved by the moderators. Every time I try to extract the attachment URL, I get this error:

Ignoring exception in on_message
Traceback (most recent call last):
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/client.py", line 343, in _run_event
    await coro(*args, **kwargs)
  File "main.py", line 32, in on_message
    url = message.attachments[0].url
IndexError: list index out of range

I tried searching this up on the Internet, but there is nothing. The only thing I found was this post, but I did everything right. Can someone explain to me what’s happening? My code:

@client.event
async def on_message(message):
  channel = client.get_channel(#id-here)
  channel2 = client.get_channel(#id-here)
  artName = message.content
  attachment = message.attachments[0]
  print(attachment)

  embed = discord.Embed(
    title = message.content,
    colour = discord.Colour.red()
  )
  
  embed.set_author(name = message.author,
  icon_url = message.author.avatar_url)
  embed.set_image(url = attachment)

Also, I tried to use message.attachments[0].url but got the same thing

Advertisement

Answer

This can be appear for some reasons:

  1. Your bot don’t check for attachments at all, so if user will send messages without image in it, bot will crash
  2. You don’t check who sended message and where (for example, bot can reply on it’s own message or on message which isn’t from #arts-request channel)
  3. You should use url attribute, to get image url for embed

So the final code will look like this:

@client.event
async def on_message(message):
     arts_request = client.get_channel(some_id1)
     arts_approve = client.get_channel(some_id2)

     if message.author.bot or message.channel != arts_request:
          # Stop command if the channel isn't #arts-request or user is bot
          return

     if not message.content or message.attachments:
          # You can use message.channel.send() if you don't want to mention user
          await message.reply("message should contain name and image of art!")

     artName = message.content
     attachment = message.attachments[0].url

     embed = discord.Embed(
          title = message.content,
          colour = discord.Colour.red()
     )
  
     embed.set_author(name = message.author,
     icon_url = message.author.avatar_url)
     embed.set_image(url = attachment)
    
     await arts_approve.send(embed)
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement