C #: building a single bot service to support multiple bot apps

This code was on this website https://www.microsoft.com/reallifecode/2017/01/10/creating-a-single-bot-service-to-support-multiple-bot-applications/#comment-148
I am new to bot framework and have written a bot in C # and want to deploy the same bot for n number of users as shown in the web page. But the given code is in Node.js

. Is there a way to write the same code in c # asp.net

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

      

+3


source to share


1 answer


Summary:

  • Create a class and inherit from the ICredentialProvider class.

  • Then add your Microsoft appId and password to the dictionary.

  • Add your method to check if this application is valid; also get the password for your app.

  • Add custom authentication to your controller api/messages

    .


First change your WebApiConfig

:

Should be:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { action = RouteParameter.Optional, id = RouteParameter.Optional }
);

      

Then your custom authentication class starting at YourNameSpace:



namespace YourNameSpace {
    public class MultiCredentialProvider : ICredentialProvider
    {
        public Dictionary<string, string> Credentials = new Dictionary<string, string>
        {
            { MicrosoftAppID1, MicrosoftAppPassword1},
            { MicrosoftAppID2, MicrosoftAppPassword2}
        };

        public Task<bool> IsValidAppIdAsync(string appId)
        {
            return Task.FromResult(this.Credentials.ContainsKey(appId));
        }

        public Task<string> GetAppPasswordAsync(string appId)
        {
            return Task.FromResult(this.Credentials.ContainsKey(appId) ? this.Credentials[appId] : null);
        }

        public Task<bool> IsAuthenticationDisabledAsync()
        {
            return Task.FromResult(!this.Credentials.Any());
        }
    }

      

After that add your controller (api / messages) using a custom BotAuthentication

one as well as your static constructor to update the container to use the correct one MicorosftAppCredentials

based on the id set by BotAuthentication:

[BotAuthentication(CredentialProviderType = typeof(MultiCredentialProvider))]
public class MessagesController : ApiController
{
    static MessagesController()
    {
        var builder = new ContainerBuilder();

        builder.Register(c => ((ClaimsIdentity)HttpContext.Current.User.Identity).GetCredentialsFromClaims())
            .AsSelf()
            .InstancePerLifetimeScope();
        builder.Update(Conversation.Container);
    }

      

Now you can process messages:

[BotAuthentication(CredentialProviderType = typeof(MultiCredentialProvider))]
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
    if (activity.Type == ActivityTypes.Message)
    { 
        ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
        Activity reply = activity.CreateReply("it Works!");                       
        await connector.Conversations.ReplyToActivityAsync(reply);
    }
}

      

This code has been tested and works for my bots.
Hope this helps :)

+8


source







All Articles