简体   繁体   中英

How can I detect when a user enters or leaves a game and get the game name they entered/left?

Discord.js has a presenceUpdate event with oldPresence and newPresence objects. Various posts I've seen here and elsewhere say to use these to detect when a user enters/leaves a game and what game it is, but v14 presenceUpdate objects don't make this information clear.

I've sort of gotten around this, but my solution isn't stable or reliable. The oldPresence object has a frozenPresence property which will list a game if the user was playing it in the oldPresence . The newPresence object has a map of all presences on the guild, so I can find the user the presence applies to with their userID and find the game listed in that presence.

But sometimes presenceUpdate fires when a user hasn't left or entered a game, so this results in funky behavior and sometimes crashes. Actual code below. Welcome any suggestions.

discordClient.on("presenceUpdate", (oldMember, newMember) => {
    let user = oldMember.user.username;
    let userID = newMember.user.id

    if(oldMember.frozenPresence.game != null && newMember.frozenPresence == null) {
        if(oldMember.frozenPresence.game.name != null) {
            let game = oldMember.frozenPresence.game.name;
            sendGroupMeMessage(user + " has stopped playing " + game, () => {});
        }
    }
    else {
        newMember.guild.presences.forEach((value, key) => {
        if (key == userID) {
            sendGroupMeMessage(user + " is playing " + value.game.name, () => {});
        }
    });
    }
});

The newer version of discord.js takes Presence as arguments in presence update event, but you were using GuildMember type which is incorrect.

The following function does -

  • Verify if the oldPresence was undefined and if the number of new activities is more than the number of old activities - if so then probably that user joined the game
  • Verify if the newPresence was undefined and if the number of old activities is more than the number of new activities - if so then probably that user left the game
async onPresenceUpdate(oldPresence, newPresence) {
    const oldActivitiesCount = oldPresence.activities.filter(
      (x) => x.type === ActivityType.Playing
    ).length;
    const newActivitiesCount = newPresence.activities.filter(
      (x) => x.type === ActivityType.Playing
    ).length;
    // Enter new game
    if (
      (!oldPresence && newPresence) ||
      newActivitiesCount > oldActivitiesCount
    ) {
      const newUserActivity = newPresence.activities
        .filter((x) => x.type === ActivityType.Playing)
        .at(0);
      if (newUserActivity) {
        console.log('New game:' + newUserActivity.name);
      }
    }
    // Leave game
    else if (
      (oldPresence && !newPresence) ||
      newActivitiesCount < oldActivitiesCount
    ) {
      const oldUserActivity = oldPresence.activities
        .filter((x) => x.type === ActivityType.Playing)
        .at(0);
      if (oldUserActivity) {
        console.log('Leave game:' + oldUserActivity.name);
      }
    }
  }

Possible improves:

  • Save in key value pairs the id and the name of the game and then be sure that the user left the correct game

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM