0

I had made a discord bot a while back for a purpose involving message embeds that my friends and I needed. Long story short the bot went offline for like a year because the host (a raspberry pi) died. Fast forwarding today, we needed it again so I tried it firing it up, but noticed that most of my code doesn't work anymore, because the async branch of discord.py has been updated to v1.0 which brings major changes and requiers migration in code to comply with the new library. Looking at the documentation, I was able to figure everything out, except the embed part of my bot. Which is the most important.

This is the code I will focus on, there is more after, but it's irrelevant to this part, because if I can sucessfully store the values I am aiming for in the string, then the rest should work.

async def on_message(message):
    serverid = message.guild.id
    channel = message.channel
    messagecontent = message.content
    if message.embeds:
        try:
            charaname = message.embeds[0]['author']['name']
            charaseries = message.embeds[0]['description']
        except AttributeError:
            return

What I am basically trying to do, is if a message has an embed, then I need to store the name and description values in seperate strings, for later on use in the code. But I get this trying to do so:

Ignoring exception in on_message
Traceback (most recent call last):
  File "C:\discord\client.py", line 270, in _run_event
    await coro(*args, **kwargs)
  File "C:\path_to_script", line 35, in on_message
    charaseries = message.embeds[0]['description']
TypeError: 'Embed' object is not subscriptable

Some research showed to me that 'subscriptable' means when an object can contain multiple other objects, such as lists. It's explained here better. If it's not subscriptable, then I am guessing the new library has a whole new way of handling this, which I cannot seem to figure out. So I need help understanding what exactly is going on here, so I can adapt my code and get this part working again.

Help is appreciated alot, thank you!

Myronaz
  • 183
  • 1
  • 1
  • 10

1 Answers1

1

TypeError: 'Embed' object is not subscriptable as you can see Embed is a object and it is not subscriptable.

One of the examples of the subscriptable object is a standard dictionary. This means it's atribbutes can be accessed with ["key_name"].

For other objects to be subscriptable they need to implement the __getitem__() dunder method. Since you're getting object not subscriptable error it means that your Embed object does not implement this method.

You used to be able to access them in that way but if you look at d.py migrating page you will see that they state:

Message.embeds is now a list of Embed instead of dict objects.

So it's a list of Embed objects and if you look at current Embed documentation you will see how to access it's atributtes - for your case:

charaname = message.embeds[0].author.name
charaseries = message.embeds[0].description

So for clarification message.embeds is a list of Embed objects so with [0] we get the first element from that list, which is a Embed object.

As you can see from the documentation we can access it's description with description attribute, simple isn't it?

And if we do .author ,as seen from the documentation, we will access it's author EmbedProxy object. Now what can we access from this? If you look up the previous documentation link it states See set_author() for possible values you can access.

So let's see the documentation for set_author() , as we can see it's parameters are

name (str)
url (str)
icon_url (str)

So going by previous statement from the docs we know we can access those 3.

So this is all valid:

message.embeds[0].author.name
message.embeds[0].author.url 
message.embeds[0].author.icon_url 

If any of those are not set it will return Embed.Empty as seen from the docs

So if they are not set you will get Embed.Empty , one example of such embed is:

embed = discord.Embed(title="Test embed #1", description="Some description")
await ctx.send(embed=embed)

As you see the author is not set so if you fetch message.embeds[0].author.name you will get Embed.Empty while for message.embeds[0].description you will get Some description because it was set.

One example for setting author in embed:

embed = discord.Embed(title="Test embed #2", description="Some description").set_author(name=ctx.author.name)
await ctx.send(embed=embed)

(we used set_author()) - this will get us string for author name since it is set during Embed initialization.

BrainDead
  • 786
  • 7
  • 16