Skip to content

Feature Request: A Script API to Request All Members From a Guild #27

@Imred-Gemu

Description

@Imred-Gemu

A discussion on the Botloader Discord laid out some basic requirements for an implementation of this API, which I believe would check off the "List Guild Members" and possibly "Search Guild Members" from #1. I intend to contribute these changes when I'm able to finish them, and I am creating this issue to track the requirements, progress, and request further feedback.

I'm proposing an implementation which would look something like this:

import { Commands, Discord } from "botloader";

script.createCommand(Commands.slashCommand(
    "list_channel_members",
    "Lists 20 members with access to the current channel in the console."
))
    .build(async (ctx, args) => {
        
        let memberQuery = (await Discord.getGuild()).getMembers()
            .inChannel(ctx.channelId)
            //.withRoles(...)
            //.whoseNameStartsWith("...")
            // ...
            .upToNumberOfMembers(20)
            .query(); // Gateway command is sent down the pipe here.
        
        for await (const member in memberQuery){
            
            console.log(member.name());
            
        }
        
    });

The concept of filtering can be excluded and left up to script developers if desired, but I am assuming that doing that part natively probably has some benefit to reducing CPU usage for larger servers at least. I'd like to benchmark that and come back with the results unless you're against it entirely. Requesting all members that can be requested would then be (await Discord.getGuild()).getMembers().query();. Maybe a shorthand (await Discord.getGuild()).getAllMembers(); which would just be an alias to the former would be appropriate?

The requirements as discussed:

  • Need to forward the guild member chunks event from the gateway handler to the scheduler.
    -- I assume this would be similar to what was implemented in 0eabd0b, with more care given to the possibility that the gateway will reply with a lot more data.
  • Unique nonce generation, could probably use a random number with a nanosecond timestamp, would be good enough.
    -- In the aforementioned commit, you had just used a number being incremented as a nonce. I'm not sure if that was changed later, but I take that as there currently is not a utility for generating unique nonces in the codebase? Should this be implemented in one of the common crates for future use in other parts of the code, or possibly should we use an existing crate for this?
  • Create internal and sdk models for it, internal ts models are generated from their rust types. See the runtime models folder.
  • Add a rate limit for requesting guild members, ideally we need a rate limit on the gateway side as there's a max amount of commands you can issue per minute (I think 120?) but can skip it for the first iteration.
    -- Yes, 120 per minute per shard if I'm reading the documentation correctly or you risk having your token disabled.
    -- That being said, should guilds be rate limited further such that one guild can't hog the entire shard's available requests?
    -- Should caching be used to allow guilds to make requests more frequently? I think I'd prefer to leave this to script developers, but it would be nice if they could hook into this API somehow to provide their cache through the native filtered API?
  • Hold chunks and send members to the JS VMs when requested, providing an op call to read each entry and wrap that in an async iterator.
    -- A potential implementation using channels was discussed. It looks like for other implementations using gateway commands, HTTP API calls are used. Perhaps an HTTP stream could be used with each read returning a single member then?
    -- You also mentioned having a timeout, was this referring to a timeout if the script does not consume the the iterator to avoid the member list sitting in the backend for too long?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions