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 C# solution, but don't worry if you prefer the Node.js SDK; in that case check out this sample!
Term | Description |
---|---|
Aggregation (channel) | Only applies if aggregation approach is used! A channel where the chat requests are sent. The users in the aggregation channel can accept the requests. |
Connection | Is created when a request is accepted - the acceptor and the one accepted form a connection (1:1 chat where the bot relays the messages between the users). |
Party | A user/bot in a specific conversation or can represent a channel (e.g. specific conversation channel in Slack) itself. |
Conversation client | A reqular user e.g. a customer. |
Conversation owner | E.g. a customer service agent. |
An interface for managing the parties (users/bot), aggregation channel details, the list of connected parties and pending requests.
MessageRouterManager is the main
class of the project. It manages the routing data (using the provided IRoutingDataManager
implementation) and executes the actual message mediation between the parties connected in a
conversation.
RoutingDataManager
: The implementation of theIRoutingDataManager
interface in use. This property is set by passing the instance to the constructor of theMessageRouterManager
class. This project provides two implementations of this interface:LocalRoutingDataManager
for testing andAzureTableStorageRoutingDataManager
. You can implement your own routing data management by using theIRoutingDataManager
interface as the base or deriving fromAbstractRoutingDataManager
.
HandleActivityAsync
: In very simple cases this is the only method you need to call (in addition toDiconnect
). It will track the users (stores their information), forward messages between users connected in a conversation automatically. The return value (MessageRouterResult
) will indicate whether the message routing logic consumed the activity or not. If the activity was ignored by the message routing logic, you can e.g. forward it to your dialog.SendMessageToPartyByBotAsync
: Utility method to make the bot send a given message to a given user.MakeSurePartiesAreTracked
: A convenient method for adding parties. The given parties are added, if they are new. This method is called byHandleActivityAsync
so you don't need to bother calling this explicitly yourself unless your bot code is a bit more complex.RemoveParty
: Removes all the instances related to the given party from the routing data (since there can be multiple - one for each conversation). Will also remove any pending requests of the party in question as well as end all conversations of this specific user.RequestConnection
: Creates a request on behalf of the given party/sender of the activity.RejectPendingRequest
: Removes the pending request of the given user.ConnectAsync
: Establishes a connection between the given parties. This method should be called when a chat request is accepted (given that requests are necessary).Disconnect
: Ends the conversation and severs the connection between the users so that the messages are no longer relayed.RouteMessageIfSenderIsConnectedAsync
: Relays the messages between connected parties.
AbstractRoutingDataManager
implements the IRoutingDataManager
interface partially and is the base class for both
LocalRoutingDataManager
and AzureTableStorageRoutingDataManager
. It contains the main logic for
routing data management while leaving the storage specific operation implementations
(add, remove, etc.) for the subclasses.
AzureTableStorageRoutingDataManager
implements the IRoutingDataManager
interface. The constructor takes the connection string to your
Azure Storage.
LocalRoutingDataManager
implements the IRoutingDataManager
interface. Note that this class is meant for testing and
provides only an in-memory solution. Do not use this class in production!
Party holds the details of specific user/bot in a specific
conversation. One can think of Party
as a full address the bot needs in order to send a message to
the user in a conversation. The Party
instances are stored in the routing data.
MessageRouterResult is the return
value for more complex operations of the MessageRouterManager
class and methods of the
IRoutingDataManager
implementation. You are responsible to handle these in your bot code.
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):
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.