Search code examples
node.jsbotframework

Using Microsoft Bot Framework, when I write on Messenger channel, how to push the result to a specific Slack channel ? (with Node)


Currently my users are using a Messenger channel.

Here is what it goes: my users type "Talk to a coach" in my bot, then they can write whatever they want, and then the result should be pushed to a specific private channel using Slack.

How can I achieve that ?

EDIT: The private channel is a list of users request that can be processed when coaches are available, so users don't have to be in a waiting list


Solution

  • I achieved it using directly Slack API. I tried with .sourceEvent, and it nearly worked: the bot only talked to me in private on Slack, he didn't accept any channel ID / name (private or not).

    Here is how I made it to work (a bit factorized): It starts with the user wanting to change anything in his planning (which has to be done manually by a coach), so it starts in dialog "/select_modify_planning"

    app.js:

    ...
    
    bot.dialog("/select_modify_planning", require("./dialogs/modifyPlanning").select);
    bot.dialog("/ask_for_request", require("./dialogs/modifyPlanning).askForRequest);
    
    ...
    

    modifyPlanning.js:

    const builder = require('botbuilder');
    const rp = require('request-promise');
    
    ...
    
    exports.select = [
     (session, args) => {
       session.sendTyping();
       builder.Prompts.choice(session, "What do you want to declare ? :)", "Internal hours|Update rendezvous");
     },
     (session, results) => {
      if (results.response) {
        switch (results.response.entity) {
          case "Internal hours":
            session.beginDialog("/ask_for_request");
            break;
          case "Update rendezvous":
            ...
        }
      }
    ]
    
    ...
    
    exports.askForRequest = [
     (session, args) => {
       session.sendTyping();
       builder.Prompts.text(session, "Type your demand please:");
     },
     async (session, results) => {
       try {
         if (results.response)
           await sendRequestToSlack(results.response);
           session.endDialog("Your demand has been sent successfully, thank you ;)");
       }
       .catch(err) {
         console.error(err);
         session.endDialog("There was a problem while sending your demand to a coach, sorry :(");
       }
     }
    ]
    
    ...
    
    const sendRequestToSlack = (textToSend) => {
      var options = {
        uri: "https://slack.com/api/chat.postMessage",
        form: {
          "token": "xoxb-XXXXXX-XXXXXX", // Your bot slack token
          "channel": "XXXXXXXXX", // Your channel id (or name)
          "text": textToSend
        },
        headers: {
          'content-type': 'application/x-www-form-urlencoded'
        }
      }
      return rp.post(options);
    }
    
    ...
    

    And here it is.

    If you want to know your channels ID (using name is a bad practice because they can be changed), you can use this method: https://api.slack.com/methods/channels.list for public channels, or this one: https://api.slack.com/methods/groups.list for private channels.

    If it's for private channels, you have to add good permissions in your bot scope settings ( groups.xxx ), and reinstall it (you have a green button dedicated to in bots settings)

    Hope everything is clear :)