How to avoid duplicate users from being mentioned by a bot in Slack?

So, I'm working on a Slack bot that mentions a random user every week. I'm getting to the point where the bot does exactly that, but I'm not sure how to avoid duplicates. As you can see in the screenshot below, duplicate names are displayed:

duplicate names

Here is my code:

// Handle events related to the websocket connection to Slack
controller.on('rtm_open', function (bot) {
  console.log('** The RTM api just connected!');

  // Get all users
  bot.api.users.list({}, function(err, list){

    // If list and members exist
    if (list && list.members) {

      list.members = list.members.filter(function(member) {
        return (member.real_name != undefined && member.real_name != "" && member.real_name != null && member.real_name != "slackbot");
      });

      // console.log(list.members);
      var previousRandomNumber = -1;

      // Every X amount of milliseconds
      var interval = setInterval(function() {
        var members = list.members;

        // Generating random number from 0 to how many members exist (exclusive) in the member list
        var randomNumber = Math.floor(Math.random() * members.length);

        console.log('1) previous: ' + previousRandomNumber + '  randomNumber ' + randomNumber);
        if (previousRandomNumber == randomNumber) {
          randomNumber = Math.floor(Math.random() * members.length);
        }
        console.log('2) previous: ' + previousRandomNumber + '  randomNumber ' + randomNumber);

        previousRandomNumber = randomNumber;

        // Get random name
        var randomName = members[randomNumber].name;

        //console.log(randomName);

        // If random name is null or undefined, reshuffle.
        if (randomName == null || randomName == "" || randomName == undefined) {
          console.log('user has been deleted');

          // clearInterval(interval);

        } else {
          console.log('actual person - ' + randomName);
          // Configuring webhook and sending message to channel
          bot.configureIncomingWebhook({url: 'https://hooks.slack.com/services/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'});
          bot.sendWebhook({
            text: '@' + randomName + ", you've been selected for #snapshot! ",
            channel: '#test',
          },function(err,res) {
            // handle error
          });
        }
      }, 3000); // 604800000 ms = 1 week
      console.log("message");
    }
  })
});

      

Link to repo on GitHub

Does anyone know how I could somehow combine the names that were already mentioned in the array?

+3


source to share


2 answers


To avoid duplication, you will need to keep the user IDs already mentioned and remove them from your copy of the user list every time you launch it (for example, once a week). Until all users are mentioned, you should reset.



There are many ways to store identifiers. for example you can put them in a database or you can protect them in a JSON file stored on the server.

+4


source


First, I agree with Erik that you need to explicitly make sure that you don't select the same item twice. This can be done by saving the items that you have already selected (or still need to select) in the database. We don't have enough information to help you with this.

I want to add, however, that the best way to select random members without repeating is not randomly selecting a user, and make sure you haven't selected that member before. This can take a long time. You can remove an element from an array, but there is another way.

Shuffle (in the right way !) An array of members and then just collapse them in order. You can shuffle again when all participants have been selected. Below is an example using ES6 syntax and generator because it is the ideal use case for it. If browser support (no IE, other major browsers is ok) is not a problem, you can use that by passing in your list.members

before uniqueRandomIterate

and use iterator.next().value

in your spacing.



function shuffle(a) {
  for (let i = a.length; i; i--) {
    let j = Math.floor(Math.random() * i);
    [a[i - 1], a[j]] = [a[j], a[i - 1]];
  }
}

function* uniqueRandomIterate(array) {
  var ind = 0;
  while (true) {
    shuffle(array);
    for (let i = 0; i < members.length; ++i) {
      yield array[i];
    }
    console.log('got everyone, starting over');
  }
}

var members = ['a', 'b', 'c', 'd', 'e', 'f'],
    iterator = uniqueRandomIterate(members);
for (let i = 0; i < 3 * members.length; ++i) {
  console.log(iterator.next().value);
}
      

.as-console-wrapper {
  max-height: 100% !important;
}
      

Run codeHide result


+2


source







All Articles