Compter les membres d'un serveur discord avec discord.js

Le problème exposé dans ce sujet a été résolu.

Bonsoir les agrumes ! :)

J’aimerais compter combien de membres se trouvent dans mon serveur, en dissociant les bots des vrais membres. Pour cela, j’ai écrit une fonction count(msg) qui prend en paramètre un message posté sur le serveur. Pas n’importe lequel : le message qui contient la commande !count.

Dans un premier temps, j’aimerais compter tous les membres (dont les bots) simplement en les listant un par un.
Le problème, c’est que les résultats renvoyés ne sont pas bons et je ne comprends pas pourquoi.

Ensuite, une fois ce problème résolu, j’essaierai de dissocier les vrai membres des bots.


Voici ma fonction :

/**
  * Liste tous les membres d'un
  * serveur, pour les compter.
  *
  * @param msg  Un message envoyé sur le serveur contenant la commande '!count'
  */
function count(msg) {

    const guild = msg.guild;
    console.log("Statistiques du serveur " + guild.name);

    // Nombre de membres
    let n = 0;
    
    console.log("Première approximation : " + guild.memberCount);

    // GuildMemberManager
    let m = guild.members;
    
    
    // 1) Avec le cache
    m.cache.each(
        () => {
            ++n;
        }
    );

    console.log("Nombre de membres dans le serveur via le cache : " + n);
    
    
    // 2) Avec le fetch
    n = 0;
    
    m.fetch().then(
        () => {
            ++n;
        }
    );
    
    console.log("Nombre de membres dans le serveur via le fetch : " + n);
}

Le résultat n’est pas bon malheureusement, voici la sortie :

Statistiques du serveur Anime World Fans
Première approximation : 54
Nombre de membres dans le serveur via le cache : 2
Nombre de membres dans le serveur via le fetch : 0

Je ne comprends pas, j’ai lu et relu la documentation sans comprendre pourquoi aucune des méthodes ne fonctionne.


Un gentil zeste aurait-il une idée svp ? :magicien:

m.fetch().then(
    () => {
        ++n;
    }
);

Je ne fais pas beaucoup de JS, mais j’aurais tendance à penser qu’il manque un await et qui fait que la lambda n’a pas encore été exécuter au moment du log suivant.


Edit: De plus d’après la documentation, lorsqu’il y a plusieurs membre, le fetch te retourne une collection. Donc ta lambda ne sera appelé qu’une seule fois, donc au mieux n => 1.


Edit2: pourquoi guild.memberCount ne te suffit pas ? Et pourquoi appelé ça approximation. Car d’après la documentation: The full amount of members in this guild, donc à priori pas une approximation.

La seul nécessité de fetch, est pour récupérer des informations supplémentaires sur les membres, pas de les compter.

+0 -0

Merci pour tes remarques, j’ai pu améliorer le code sans toutefois arriver au bon résultat.

Je te réponds point par point :

  • J’ai corrigé le code pour ce problème de await, bien vu
  • J’ai corrigé le problème avec le fetch pour travailler sur la collection
  • memberCount renvoie le bon résultat, mais ce que je veux, c’est pouvoir différencier les bots des vrais membres, d’où le besoin de les lister un par un, afin de regarder pour chaque membre s’il est un bot ou pas.

Le code corrigé :

/**
  * Liste tous les membres d'un
  * serveur, pour les compter.
  *
  * @param msg  Un message envoyé sur le serveur contenant la commande '!count'
  */
function count(msg) {

    const guild = msg.guild;
    console.log("Statistiques du serveur " + guild.name);

    // Nombre de membres
    let n = 0;
    
    console.log("Résultat attendu : " + guild.memberCount);

    // GuildMemberManager
    let m = guild.members;
    
    
    // 1) Avec le cache
    m.cache.each(
        () => {
            ++n;
        }
    );

    console.log("Nombre de membres dans le serveur via le cache : " + n);
    
    
    // 2) Avec le fetch
    n = 0;
    
    m.fetch().then(
        (coll) => {
            coll.each(() => {
                ++n;
            });
            console.log("Nombre de membres dans le serveur via le fetch : " + n);
        }
    );
}

Et l’output :

Statistiques du serveur Anime World Fans
Première approximation : 54
Nombre de membres dans le serveur via le cache : 2

(node:12392) UnhandledPromiseRejectionWarning: Error [GUILD_MEMBERS_TIMEOUT]: Members didn't arrive in time.
    at C:\Users\**************\Desktop\bot\node_modules\discord.js\src\managers\GuildMemberManager.js:317:16
    at Timeout._onTimeout (C:\Users\**************\Desktop\bot\node_modules\discord.js\src\client\BaseClient.js:83:7)
    at listOnTimeout (internal/timers.js:555:17)
    at processTimers (internal/timers.js:498:7)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:12392) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:12392) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
  • Bizarre que le code avec le cache ne fonctionne pas :(
  • Le fetch ne répond plus, je me demande si c’est une erreur chez moi ou discord ?
+0 -0

Bizarre que le code avec le cache ne fonctionne pas

Peut-être qu’il y a deux membres en cache uniquement, d’où le 2. Si tu fetch correctement une fois, probablement que le cache retournera 54 la fois suivante.

Le fetch ne répond plus, je me demande si c’est une erreur chez moi ou discord ?

peut-être un problème de droit:

https://stackoverflow.com/questions/65042476/guild-members-timeout-members-didnt-arrive-in-time

Merci à vous deux, le problème venait bien de cette histoire d’intent !
J’en ai profité pour nettoyer le code, c’est plus clair comme ça :

/**
  * Liste tous les membres d'un
  * serveur, pour les compter.
  *
  * @param msg Un message envoyé sur le serveur contenant la commande '!count'
  */
function count(msg) {

    const guild = msg.guild;
    console.log("Statistiques du serveur " + guild.name);
    console.log("Résultat attendu : " + guild.memberCount);

    guild.members.fetch().then(membersList => {
        console.log(`Nombre de membres dans ce serveur : ${membersList.size}`);
    });
}
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte