Цикл по Botkit метод startPrivateConversation для многих пользователей - PullRequest
0 голосов
/ 12 ноября 2018

Я пытаюсь отправить обновление всем своим пользователям в отдельном js-файле, поэтому для того, чтобы сделать это правильно, мне нужно было создать новый контроллер бота. В настоящее время я пытаюсь вызвать функцию уведомления внутри моей функции controller.on rtm_open. Затем я пытаюсь перебрать хранилище пользователей моего контроллера и отправить каждому из них сообщение в их DM. Это код, который я использую для этого подхода.

controller.on('rtm_open',function(bot) {
console.log('** The RTM api just connected!');
controller.storage.users.all(function(err, users) {
  if (err) {
    throw new Error(err);
    console.log('Error hit in user storage')
  })
 updateInstallers(bot, users)
}


function updateInstallers(bot, users) {
console.log('Hello World', users)
var msg = 'Welcome to...., here is a list of our new features that you can try out with a reinstallation...'
for (var u in users) {
  var installer = users[u].id
  console.log('checking installer', installer)
  bot.startPrivateConversation({user: installer}, function(err, convo) {     
   console.log('Why is installer the SAME?', installer)
   if (err) {
     console.log(err)
   } else {
     console.log('Bot should say something', installer)
     convo.say(msg)
    }
  })
 }
}

После игр и попыток запустить мой цикл разными способами, конечный результат всегда таков для массива из 2 или более пользователей. Последний / последний пользовательский объект в массиве всегда является единственным пользователем, который правильно проходит через функцию bot.startPrivateConversation.

checking installer U0T1AL5CN
checking installer UCSPVKE0H
Why is installer the SAME? UCSPVKE0H
Bot should say something UCSPVKE0H
Why is installer the SAME? UCSPVKE0H
user_not_found
Why is installer the SAME? UCSPVKE0H
Bot should say something UCSPVKE0H
Why is installer the SAME? UCSPVKE0H
user_not_found

Есть идеи, как это исправить? Я предполагаю, что это асинхронная проблема со стеком вызовов, но я также обеспокоен тем, что этот тип цикла может не работать с этой функцией botkit. Если есть какой-то код, то любой может реорганизовать его так, чтобы он работал лучше, что было бы здорово. Огромное спасибо заранее.

1 Ответ

0 голосов
/ 12 ноября 2018

Вы должны попробовать следующее:

for (let u in users) {
   const installer = users[u].id

Или избегайте цикла и используйте forEach:

users.forEach(
  (user)=>{
    var installer = user.id;
    //...rest of the code
  }
)

Но, вероятно, наилучшим способом будет сопоставление массива пользователей с обещаниями:

//start conversation as promise
const startPrivateConversationPromise = (installer) =>
  new Promise((resolve, reject) =>
    bot.startPrivateConversation(
      { user: installer },
      (err, convo) => (err ? reject(err) : resolve(convo)),
    ),
  );
//special value for rejected promise
const Fail = function(reason) {
  this.reason = reason;
};
const isFail = (o) => o && o.constructor === Fail;
const isNotFail = (o) => !o.isFail(o);

Promise.all(
  users.map(
    (user) =>
      startPrivateConversationPromise(user.id).catch(
        (e) => new Fail(e)//still resolve even if it rejects
      ), 
  ),
).then((results) => {
  const convos = results.filter(isNotFail); //resolved instances
  const failed = reslts.filter(isFail); //rejected instances
  convos.forEach((convo) => convo.say(message));
});
...