Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One bot to support thousands of Facebook pages

I love the bot framework, but I want to scale to support hundreds if not thousands of Facebook pages all pointing to my single bot instance. My bot instance differentiates functionality by the incoming page id, or I guess by the MSFT App/Secret IDs.

The framework appears to require a 1:1 correspondence between logical bot hosted by MSFT and a FB page, but my single bot instance can handle thousands of such pages and apps.

It looks like I might need to create a unique ChatConnector and associated UniversalBot instance for every logical bot-page. This is horribly inefficient at the scale I'm suggesting.

One way to solve this might be to extend UniversalBot to accept a list of all MSFT App and Secret IDs that I create, but I haven't tried this yet. After reviewing the API, looks like it might be possible to register more connectors with a single UniversalBot instance.

UniversalBot:

/** 
 * Registers or returns a connector for a specific channel. 
 * @param channelId Unique ID of the channel. Use a channelId of '*' to reference the default connector.
 * @param connector (Optional) connector to register. If ommited the connector for __channelId__ will be returned. 
 */    
connector(channelId: string, connector?: IConnector): IConnector;

But not sure what I pass for channelId unless that's an arbitrary unique local value.

I have reviewed other/similar posts here, but not found specifically anything that I believe addresses my issue. If I'm mistaken I apologize and would appreciate a reference.

I am hoping someone might have a better idea. I am using Node btw. Thanks.

like image 786
Jackpile Avatar asked Oct 31 '16 23:10

Jackpile


1 Answers

Taken from here:

Creating a Single Bot Service to Support Multiple Bot Applications

var express = require('express');
var builder = require('botbuilder');
var port = process.env.PORT || 3978;
var app = express();

// a list of client ids, with their corresponding 
// appids and passwords from the bot developer portal.
// get this from the configuration, a remote API, etc.
var customersBots = [
  { cid: 'cid1', appid: '', passwd: '' }, 
  { cid: 'cid2', appid: '', passwd: '' }, 
  { cid: 'cid3', appid: '', passwd: '' }, 
];

// expose a designated Messaging Endpoint for each of the customers
customersBots.forEach(cust => {

  // create a connector and bot instances for 
  // this customer using its appId and password
  var connector = new builder.ChatConnector({
    appId: cust.appid,
    appPassword: cust.passwd
  });
  var bot = new builder.UniversalBot(connector);

  // bing bot dialogs for each customer bot instance
  bindDialogsToBot(bot, cust.cid);

  // bind connector for each customer on it's dedicated Messaging Endpoint.
  // bot framework entry should use the customer id as part of the
  // endpoint url to map to the right bot instance
  app.post(`/api/${cust.cid}/messages`, connector.listen());

});

// this is where you implement all of your dialogs 
// and add them on the bot instance
function bindDialogsToBot (bot, cid) {
  bot.dialog('/', [
    session => {
      session.send(`Hello... I'm a bot for customer id: '${cid}'`);
    }
  ]);
}

// start listening for incoming requests
app.listen(port, () => {
  console.log(`listening on port ${port}`);
});

We are creating different bot and connector instances that capture the App ID and password for each customer, and binding it to the corresponding REST API that is used by the Bot Framework as the Messaging Endpoint.

When we create the bot instance, we call the bindDialogsToBot method, passing the bot instance and the customer ID. By doing that, we capture the customer ID in its closure making it accessible to the internal dialogs.

When a call is made to one of the REST APIs, the relevant bot instance is used, and the correct customer ID can be utilized by the dialog’s internal logic to process the request (for example, to retrieve a customer’s configuration/rules and act upon them).

like image 95
Mor Shemesh Avatar answered Nov 09 '22 08:11

Mor Shemesh