public static void Register(HttpConfiguration config) { // Json settings config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); config.Formatters.JsonFormatter.SerializerSettings.Formatting = Formatting.Indented; JsonConvert.DefaultSettings = () => new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver(), Formatting = Newtonsoft.Json.Formatting.Indented, NullValueHandling = NullValueHandling.Ignore, }; // Web API configuration and services config.EnableCors(); // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); // Message routing MessageRouterManager = new MessageRouterManager(new LocalRoutingDataManager()); MessageRouterResultHandler = new MessageRouterResultHandler(); CommandMessageHandler = new CommandMessageHandler(MessageRouterManager, MessageRouterResultHandler); BackChannelMessageHandler = new BackChannelMessageHandler(MessageRouterManager.RoutingDataManager); }
public async Task OnTurnAsync(ITurnContext context, NextDelegate next, CancellationToken ct) { Activity activity = context.Activity; if (activity.Type is ActivityTypes.Message) { bool.TryParse( Configuration[KeyRejectConnectionRequestIfNoAggregationChannel], out bool rejectConnectionRequestIfNoAggregationChannel); // Store the conversation references (identities of the sender and the recipient [bot]) // in the activity MessageRouter.StoreConversationReferences(activity); AbstractMessageRouterResult messageRouterResult = null; // Check the activity for commands if (await CommandHandler.HandleCommandAsync(context) == false) { // No command detected/handled // Let the message router route the activity, if the sender is connected with // another user/bot messageRouterResult = await MessageRouter.RouteReachMessageIfSenderIsConnectedAsync(activity); if (messageRouterResult is MessageRoutingResult && (messageRouterResult as MessageRoutingResult).Type == MessageRoutingResultType.NoActionTaken) { // No action was taken by the message router. This means that the user // is not connected (in a 1:1 conversation) with a human // (e.g. customer service agent) yet. // Check for cry for help (agent assistance) if (!string.IsNullOrWhiteSpace(activity.Text) && activity.Text.ToLower().Contains("human")) { // Create a connection request on behalf of the sender // Note that the returned result must be handled messageRouterResult = MessageRouter.CreateConnectionRequest( MessageRouter.CreateSenderConversationReference(activity), rejectConnectionRequestIfNoAggregationChannel); } else { // No action taken - this middleware did not consume the activity so let it propagate await next(ct).ConfigureAwait(false); } } } // Uncomment to see the result in a reply (may be useful for debugging) //if (messageRouterResult != null) //{ // await MessageRouter.ReplyToActivityAsync(activity, messageRouterResult.ToString()); //} // Handle the result, if necessary await MessageRouterResultHandler.HandleResultAsync(messageRouterResult); } }
/// <summary> /// Constructor. /// </summary> /// <param name="messageRouter">The message router.</param> /// <param name="messageRouterResultHandler">A MessageRouterResultHandler instance for /// handling possible routing actions such as accepting connection requests.</param> /// <param name="connectionRequestHandler">The connection request handler.</param> /// <param name="permittedAggregationChannels">Permitted aggregation channels. /// Null list means all channels are allowed.</param> public CommandHandler( MessageRouter messageRouter, MessageRouterResultHandler messageRouterResultHandler, ConnectionRequestHandler connectionRequestHandler, IList <string> permittedAggregationChannels = null) { _messageRouter = messageRouter; _messageRouterResultHandler = messageRouterResultHandler; _connectionRequestHandler = connectionRequestHandler; _permittedAggregationChannels = permittedAggregationChannels; }
/// <summary> /// Responds back to the sender with the simple instructions. /// </summary> /// <param name="dialogContext">The dialog context.</param> /// <param name="result">The result containing the message sent by the user.</param> private async Task OnMessageReceivedAsync(IDialogContext context, IAwaitable <IMessageActivity> result) { IMessageActivity messageActivity = await result; string messageText = messageActivity.Text; var activity = (Activity)context.Activity; if (!string.IsNullOrEmpty(messageText)) { MessageRouterResultHandler messageRouterResultHandler = WebApiConfig.MessageRouterResultHandler; await context.PostAsync($"Veuillez patienter, vous allez être mis en contact avec un humain."); messageActivity.Text = "human"; var messageRouterResult = WebApiConfig.MessageRouterManager.RequestConnection((messageActivity as Activity)); messageRouterResult.Activity = messageActivity as Activity; await messageRouterResultHandler.HandleResultAsync(messageRouterResult); context.Done(this); } }
public HandoffMiddlewareBase(IConfiguration configuration, ILoggerFactory loggerFactory) { Configuration = configuration; _logger = loggerFactory.CreateLogger <HandoffMiddlewareBase>(); string connectionString = Configuration[KeyAzureTableStorageConnectionString]; IRoutingDataStore routingDataStore = null; if (string.IsNullOrEmpty(connectionString)) { _logger.LogDebug($"WARNING!!! No connection string found - using {nameof(InMemoryRoutingDataStore)}"); routingDataStore = new InMemoryRoutingDataStore(); } else { _logger.LogDebug($"Found a connection string - using {nameof(AzureTableRoutingDataStore)}"); routingDataStore = new AzureTableRoutingDataStore(connectionString, new Underscore.Bot.MessageRouting.Logging.ConsoleLogger(loggerFactory.CreateLogger <AzureTableRoutingDataStore>())); } MessageRouter = new MessageRouter( routingDataStore, new MicrosoftAppCredentials(Configuration["MicrosoftAppId"], Configuration["MicrosoftAppPassword"]), logger: new Underscore.Bot.MessageRouting.Logging.ConsoleLogger(loggerFactory.CreateLogger <MessageRouter>()) ); //MessageRouter.Logger = new Logging.AggregationChannelLogger(MessageRouter); MessageRouterResultHandler = new MessageRouterResultHandler(MessageRouter); ConnectionRequestHandler connectionRequestHandler = new ConnectionRequestHandler(GetChannelList(KeyNoDirectConversationsWithChannels)); CommandHandler = new CommandHandler( MessageRouter, MessageRouterResultHandler, connectionRequestHandler, GetChannelList(KeyPermittedAggregationChannels), new Underscore.Bot.MessageRouting.Logging.ConsoleLogger(loggerFactory.CreateLogger <CommandHandler>())); MessageLogs = new MessageLogs(connectionString, new Underscore.Bot.MessageRouting.Logging.ConsoleLogger(loggerFactory.CreateLogger <MessageLogs>())); }
/// <summary> /// Creates and sets up the instances required for message routing. /// </summary> public static void InitializeMessageRouting() { Settings = new BotSettings(); string connectionString = Settings[BotSettings.KeyRoutingDataStorageConnectionString]; IRoutingDataManager routingDataManager = null; if (string.IsNullOrEmpty(connectionString)) { System.Diagnostics.Debug.WriteLine($"WARNING!!! No connection string found - using {nameof(LocalRoutingDataManager)}"); routingDataManager = new LocalRoutingDataManager(); } else { System.Diagnostics.Debug.WriteLine($"Found a connection string - using {nameof(AzureTableStorageRoutingDataManager)}"); routingDataManager = new AzureTableStorageRoutingDataManager(connectionString); } MessageRouterManager = new MessageRouterManager(routingDataManager); MessageRouterResultHandler = new MessageRouterResultHandler(MessageRouterManager); CommandMessageHandler = new CommandMessageHandler(MessageRouterManager, MessageRouterResultHandler); BackChannelMessageHandler = new BackChannelMessageHandler(MessageRouterManager.RoutingDataManager); }
public HandoffMiddleware(IConfiguration configuration, ConversationState conversationState, UserState userState) { Configuration = configuration; _conversationState = conversationState; _userState = userState; string connectionString = Configuration[KeyAzureTableStorageConnectionString]; IRoutingDataStore routingDataStore = null; if (string.IsNullOrEmpty(connectionString)) { System.Diagnostics.Debug.WriteLine($"WARNING!!! No connection string found - using {nameof(InMemoryRoutingDataStore)}"); routingDataStore = new InMemoryRoutingDataStore(); } else { System.Diagnostics.Debug.WriteLine($"Found a connection string - using {nameof(AzureTableRoutingDataStore)}"); routingDataStore = new AzureTableRoutingDataStore(connectionString); } MessageRouter = new MessageRouter( routingDataStore, new MicrosoftAppCredentials(Configuration["MicrosoftAppId"], Configuration["MicrosoftAppPassword"])); //MessageRouter.Logger = new Logging.AggregationChannelLogger(MessageRouter); MessageRouterResultHandler = new MessageRouterResultHandler(MessageRouter); ConnectionRequestHandler connectionRequestHandler = new ConnectionRequestHandler(GetChannelList(KeyNoDirectConversationsWithChannels)); CommandHandler = new CommandHandler( MessageRouter, MessageRouterResultHandler, connectionRequestHandler, GetChannelList(KeyPermittedAggregationChannels)); MessageLogs = new MessageLogs(connectionString); }
public static void Register(HttpConfiguration config) { // Json settings config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); config.Formatters.JsonFormatter.SerializerSettings.Formatting = Formatting.Indented; JsonConvert.DefaultSettings = () => new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver(), Formatting = Newtonsoft.Json.Formatting.Indented, NullValueHandling = NullValueHandling.Ignore, }; // Web API configuration and services config.EnableCors(); // Web API configuration and services // Configure Web API to use only bearer token authentication. //config.SuppressDefaultHostAuthentication(); // config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); // Web API routes config.MapHttpAttributeRoutes(); config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream")); config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("multipart/form-data")); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); // Message routing MessageRouterManager = new MessageRouterManager(new LocalRoutingDataManager()); MessageRouterResultHandler = new MessageRouterResultHandler(); CommandMessageHandler = new CommandMessageHandler(MessageRouterManager, MessageRouterResultHandler); BackChannelMessageHandler = new BackChannelMessageHandler(MessageRouterManager.RoutingDataManager); }
/// <summary> /// Constructor. /// </summary> /// <param name="messageRouterManager">The message router manager.</param> /// <param name="messageRouterResultHandler"/>A MessageRouterResultHandler instance for /// handling possible routing actions such as accepting a 1:1 conversation connection.</param> public CommandMessageHandler(MessageRouterManager messageRouterManager, MessageRouterResultHandler messageRouterResultHandler) { _messageRouterManager = messageRouterManager; _messageRouterResultHandler = messageRouterResultHandler; }
/// <summary> /// Handles the received message. /// </summary> public async Task <HttpResponseMessage> Post([FromBody] Activity activity) { if (activity.Locale != null) { ConversationText.Culture = new CultureInfo(activity.Locale); } if (activity.Type == ActivityTypes.Message) { MessageRouterManager messageRouterManager = WebApiConfig.MessageRouterManager; MessageRouterResultHandler messageRouterResultHandler = WebApiConfig.MessageRouterResultHandler; bool rejectConnectionRequestIfNoAggregationChannel = WebApiConfig.Settings.RejectConnectionRequestIfNoAggregationChannel; messageRouterManager.MakeSurePartiesAreTracked(activity); // First check for commands (both from back channel and the ones directly typed) MessageRouterResult messageRouterResult = WebApiConfig.BackChannelMessageHandler.HandleBackChannelMessage(activity); if (messageRouterResult.Type != MessageRouterResultType.Connected && await WebApiConfig.CommandMessageHandler.HandleCommandAsync(activity) == false) { // No valid back channel (command) message or typed command detected // Let the message router manager instance handle the activity messageRouterResult = await messageRouterManager.HandleActivityAsync( activity, false, rejectConnectionRequestIfNoAggregationChannel); if (messageRouterResult.Type == MessageRouterResultType.NoActionTaken) { // No action was taken by the message router manager. This means that the // user is not connected (in a 1:1 conversation) with a human // (e.g. customer service agent) yet. // // You can, for example, check if the user (customer) needs human // assistance here or forward the activity to a dialog. You could also do // the check in the dialog too... // // Here's an example: if (!string.IsNullOrEmpty(activity.Text) && activity.Text.ToLower().Contains(Commands.CommandRequestConnection)) { messageRouterResult = messageRouterManager.RequestConnection( activity, rejectConnectionRequestIfNoAggregationChannel); } else { await Conversation.SendAsync(activity, () => new RootDialog()); } } } // Uncomment to see the result in a reply (may be useful for debugging) //await MessagingUtils.ReplyToActivityAsync(activity, messageRouterResult.ToString()); // Handle the result, if required await messageRouterResultHandler.HandleResultAsync(messageRouterResult); } else { HandleSystemMessage(activity); } var response = Request.CreateResponse(HttpStatusCode.OK); return(response); }
public async Task OnTurnAsync(ITurnContext context, NextDelegate next, CancellationToken ct) { Activity activity = context.Activity; var conversationStateAccessors = _conversationState.CreateProperty <Conversacion>(nameof(Conversacion)); var conversationData = await conversationStateAccessors.GetAsync(context, () => new Conversacion()); var userStateAccessors = _userState.CreateProperty <Conversacion>(nameof(Conversacion)); var conversacion = await userStateAccessors.GetAsync(context, () => new Conversacion()); if (activity.Type is ActivityTypes.Message) { bool.TryParse( Configuration[KeyRejectConnectionRequestIfNoAggregationChannel], out bool rejectConnectionRequestIfNoAggregationChannel); // Store the conversation references (identities of the sender and the recipient [bot]) // in the activity MessageRouter.StoreConversationReferences(activity); AbstractMessageRouterResult messageRouterResult = null; // Check the activity for commands if (await CommandHandler.HandleCommandAsync(context) == false) { // No command detected/handled // Let the message router route the activity, if the sender is connected with // another user/bot messageRouterResult = await MessageRouter.RouteMessageIfSenderIsConnectedAsync(activity); if (messageRouterResult is MessageRoutingResult && (messageRouterResult as MessageRoutingResult).Type == MessageRoutingResultType.NoActionTaken) { // No action was taken by the message router. This means that the user // is not connected (in a 1:1 conversation) with a human // (e.g. customer service agent) yet. // Check for cry for help (agent assistance) if (!string.IsNullOrWhiteSpace(activity.Text) && activity.Text.ToLower().Contains("agente")) { conversacion.Eleccion = activity.Text.ToLower(); await _conversationState.SaveChangesAsync(context, false, ct); await _userState.SaveChangesAsync(context, false, ct); // Create a connection request on behalf of the sender // Note that the returned result must be handled await context.SendActivityAsync($"{context.Activity.From.Name}, te voy a comunicar con un agente"); await context.SendActivityAsync("Por favor esperame unos segundos a que uno de nuestros agentes esté disponible para atenderte..."); messageRouterResult = MessageRouter.CreateConnectionRequest( MessageRouter.CreateSenderConversationReference(activity), rejectConnectionRequestIfNoAggregationChannel); } else { // No action taken - this middleware did not consume the activity so let it propagate await next(ct).ConfigureAwait(false); } } } // Uncomment to see the result in a reply (may be useful for debugging) //if (messageRouterResult != null) //{ // await MessageRouter.ReplyToActivityAsync(activity, messageRouterResult.ToString()); //} // Handle the result, if necessary await MessageRouterResultHandler.HandleResultAsync(messageRouterResult); } else { // No action taken - this middleware did not consume the activity so let it propagate await next(ct).ConfigureAwait(false); } }