Looping over Botkit startPrivateConversation method for many users












0














I'm trying to send an update to all my users in a separate js file, so in order to do this properly I needed to create a new bot controller. I'm currently attempting to call a notification function inside my controller.on rtm_open function. I am then trying to iterate through my controller storage of users and send each of them a message in their DM's. This is the code I am using for this approach.



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)
}
})
}
}


After playing around and trying to start my loop in different ways the end result is always this for an array of 2 or more users. The last/final user object in the array is always the only user that goes through the bot.startPrivateConversation function properly.



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


Any idea on how to fix/resolve this? My guess is this is an async issue with the call stack, but I'm also worried that this type of loop may not work with this botkit function. If there's some code anyone can refactor this to that would work better that would be awesome. Thank you so much in advance.










share|improve this question





























    0














    I'm trying to send an update to all my users in a separate js file, so in order to do this properly I needed to create a new bot controller. I'm currently attempting to call a notification function inside my controller.on rtm_open function. I am then trying to iterate through my controller storage of users and send each of them a message in their DM's. This is the code I am using for this approach.



    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)
    }
    })
    }
    }


    After playing around and trying to start my loop in different ways the end result is always this for an array of 2 or more users. The last/final user object in the array is always the only user that goes through the bot.startPrivateConversation function properly.



    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


    Any idea on how to fix/resolve this? My guess is this is an async issue with the call stack, but I'm also worried that this type of loop may not work with this botkit function. If there's some code anyone can refactor this to that would work better that would be awesome. Thank you so much in advance.










    share|improve this question



























      0












      0








      0







      I'm trying to send an update to all my users in a separate js file, so in order to do this properly I needed to create a new bot controller. I'm currently attempting to call a notification function inside my controller.on rtm_open function. I am then trying to iterate through my controller storage of users and send each of them a message in their DM's. This is the code I am using for this approach.



      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)
      }
      })
      }
      }


      After playing around and trying to start my loop in different ways the end result is always this for an array of 2 or more users. The last/final user object in the array is always the only user that goes through the bot.startPrivateConversation function properly.



      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


      Any idea on how to fix/resolve this? My guess is this is an async issue with the call stack, but I'm also worried that this type of loop may not work with this botkit function. If there's some code anyone can refactor this to that would work better that would be awesome. Thank you so much in advance.










      share|improve this question















      I'm trying to send an update to all my users in a separate js file, so in order to do this properly I needed to create a new bot controller. I'm currently attempting to call a notification function inside my controller.on rtm_open function. I am then trying to iterate through my controller storage of users and send each of them a message in their DM's. This is the code I am using for this approach.



      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)
      }
      })
      }
      }


      After playing around and trying to start my loop in different ways the end result is always this for an array of 2 or more users. The last/final user object in the array is always the only user that goes through the bot.startPrivateConversation function properly.



      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


      Any idea on how to fix/resolve this? My guess is this is an async issue with the call stack, but I'm also worried that this type of loop may not work with this botkit function. If there's some code anyone can refactor this to that would work better that would be awesome. Thank you so much in advance.







      javascript node.js express slack-api botkit






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 12 at 8:10

























      asked Nov 12 at 7:39









      Vijay Raju

      11




      11
























          1 Answer
          1






          active

          oldest

          votes


















          0














          You should try the following:



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


          Or avoid the loop and use forEach:



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


          But the best way would probably be mapping your users array to promises:



          //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));
          });





          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53257675%2flooping-over-botkit-startprivateconversation-method-for-many-users%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            You should try the following:



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


            Or avoid the loop and use forEach:



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


            But the best way would probably be mapping your users array to promises:



            //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));
            });





            share|improve this answer




























              0














              You should try the following:



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


              Or avoid the loop and use forEach:



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


              But the best way would probably be mapping your users array to promises:



              //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));
              });





              share|improve this answer


























                0












                0








                0






                You should try the following:



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


                Or avoid the loop and use forEach:



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


                But the best way would probably be mapping your users array to promises:



                //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));
                });





                share|improve this answer














                You should try the following:



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


                Or avoid the loop and use forEach:



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


                But the best way would probably be mapping your users array to promises:



                //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));
                });






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Nov 12 at 9:28

























                answered Nov 12 at 8:30









                HMR

                13.5k113898




                13.5k113898






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53257675%2flooping-over-botkit-startprivateconversation-method-for-many-users%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Florida Star v. B. J. F.

                    Danny Elfman

                    Lugert, Oklahoma