hikari-py/hikari

No roles stored with fetch_members REST API call

jtatum opened this issue · 2 comments

Summary

I'm using hikari.impl.rest.fetch_members(guild). I can see that Discord is sending back a list of roles with each member object in this API call. So, I'd expect something like this to work:

    async with rest.acquire(discord_token, "Bot") as client:
        server = await client.fetch_guild(guild_id)
        members = await client.fetch_members(server)
        for member in members:
            roles = members.get_roles() # or maybe roles = members.roles

However, get_roles() always returns an empty list, and there is no roles property on member objects.

Why is this needed?

Without this, I need to do separate member.fetch_roles() calls, which is a round trip that I shouldn't need to do since Discord already sent the roles with the member list.

Ideal implementation

Not sure - I don't know enough about the implementation to answer that. Should it be added to the cache so get_roles() works? Is there a cache with the REST API? If not, might need a separate type for REST API Members.

I'm happy to submit a PR for this, if someone can give me some pointers on the best way to accomplish it. Is there similar code in another call I can reference?

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

Oops - after looking at entity_factory.deserialize_member, I see that role_ids is an attribute, and I must be blind because it's also in the docs. Sorry! Closing.

Discord does not in fact send the roles as part of the members when you iterate over them through fetch_members. The members there have a .role_ids attributes you can access to get the IDs of the roles that the members has, which is all the information Discord provide.

Furthermore, the reason get_roles returns a empty sequence is because you are using a cacheless application (a RestApp) and get_roles attempts to get the roles off cache using the .role_ids.


And if you allow me, a little thing you can improve in your code is changing it to the following:

async for member in client.fetch_members(server_id):
    # do something with member

This way not all members are fetched at once, rather in chunks of 100 members at a time, saving you a bunch of members. Furthermore, I recommend you have a look at the documentation for LazyIterator, as you will find a lot of helpful methods (like filter) which I hope help you out!

You can always join our Discord server at https://discord.gg/hikari for more help and answering any questions you may have :)