NOTE!
This project is not maintained actively.
This project is a message routing component for chatbots built with Microsoft Bot Framework C# SDK. It enables routing messages between users on different channels. In addition, it can be used in advanced customer service scenarios where the normal routines are handled by a bot, but in case the need arises, the customer can be connected with a human customer service agent.
For an example on how to take this code into use, see Intermediator Bot Sample.
- Routing messages between users/bots
- Customer service scenarios where (in tricky cases) the customer requires a human customer service agent
- Keeping track of users the bot interacts with
- Sending notifications
- For more information see this blog post and this sample
This is a .NET Core project compatible with Bot Framework v4. The .NET Framework based solution targeting Bot Framework v3.x can be found under releases here.
If you're looking to build your bot using the Node.js SDK instead, here's the Node.js/Typescript message routing project.
Term | Description |
---|---|
Aggregation (channel) | A channel where the chat requests are sent. The users in the aggregation channel can accept the requests. Applies only if the aggregation channel based approach is used! |
Connection | Is created when a request is accepted - the acceptor and the requester form a connection (1:1 chat where the bot relays the messages between the users). |
The ConversationReference class, provided by the Bot Framework, is used to define the user/bot identities. The instances of the class are managed by the RoutingDataManager class.
An interface for storing the routing data, which includes:
- Users
- Bot instances
- Aggregation channels
- Connection requests
- Connections
An implementation of this interface is passed to the constructor of the MessageRouter class. This solution provides two implementations of the interface out-of-the-box: InMemoryRoutingDataStore (to be used only for testing) and AzureTableRoutingDataStore.
The classes implementing the interface should avoid adding other than storage related sanity checks, because those are already implemented by the RoutingDataManager.
An interface used by the MessageRouter class to log events and errors.
MessageRouter is the main
class of the project. It manages the routing data (using the RoutingDataManager
together with the
provided IRoutingDataStore
implementation) and executes the actual message mediation between the
connected users/bots.
- RoutingDataManager: Provides the main interface for accessing and modifying the routing data (see IRoutingDataStore documentation for more information about the routing data details).
CreateSenderConversationReference
(static): A utility method for creating aConversationReference
of the sender in theActivity
instance given as an argument.CreateRecipientConversationReference
(static): A utility method for creating aConversationReference
of the recipient in theActivity
instance given as an argument. Note that the recipient is always expected to be a bot.SendMessageAsync
: Sends a message to a specified user/bot.StoreConversationReferences
: A convenient method for storing the sender and the recipient in theActivity
instance given as an argument. This method is idempotent; the created instances are added only if they are new.CreateConnectionRequest
: Creates a new connection request on behalf of the given user/bot.RejectConnectionRequest
: Removes (rejects) a pending connection request.ConnectAsync
: Establishes a connection between the given users/bots. When successful, this method removes the associated connection request automatically.Disconnect
: Ends the conversation and severs the connection between the users so that the messages are no longer relayed.RouteMessageIfSenderIsConnectedAsync
: Relays the message in theActivity
instance given as an argument, if the sender is connected with a user/bot.
RoutingDataManager
contains the main logic for routing data management while leaving the storage specific operation
implementations (add, remove, etc.) for the class implementing the IRoutingDataStore
interface.
This is the other main class of the solution and can be accessed via the MessageRouter
class.
AzureTableRoutingDataStore
implements the IRoutingDataStore
interface. The constructor takes the connection string of your
Azure Table Storage.
InMemoryRoutingDataStore
implements the IRoutingDataStore
interface. Note that this class is meant for testing. Do not
use this class in production!
AbstractMessageRouterResult
is the base class defining the results of the various operations implemented by the MessageRouter
and the RoutingDataManager
classes. The concrete result classes are:
For classes not mentioned here, see the documentation in the code files.
This is a community project and all contributions are more than welcome!
If you want to contribute, please consider the following:
- Use the development branch for the base of your changes
- Remember to update documentation (comments in code)
- Run the tests to ensure your changes do not break existing functionality
- Having an Azure Storage to test is highly recommended
- Update/write new tests when needed
- Pull requests should be first merged into the development branch
Please do not hesitate to report ideas, bugs etc. under issues!
Special thanks to the contributors (in alphabetical order):
- Syed Hassaan Ahmed
- Jorge Cupi
- Michael Dahl
- Jamie D
- Pedro Dias
- Drazen Dodik
- Lucas Humenhuk
- Lilian Kasem
- Edouard Mathon
- Gary Pretty
- Jessica Tibaldi
Note that you may not find (all of their) contributions in the change history of this project, because all of the code including this core functionality used to reside in Intermediator Bot Sample project.