{"id":20003298,"url":"https://github.com/tompaana/intermediator-bot-sample","last_synced_at":"2025-05-04T15:34:51.505Z","repository":{"id":65282272,"uuid":"70902237","full_name":"tompaana/intermediator-bot-sample","owner":"tompaana","description":"A sample bot, built with the Microsoft Bot Framework (v4), that routes messages between two users on different channels.","archived":false,"fork":false,"pushed_at":"2021-10-17T18:46:54.000Z","size":1483,"stargazers_count":123,"open_issues_count":20,"forks_count":66,"subscribers_count":20,"default_branch":"master","last_synced_at":"2025-04-08T08:06:06.012Z","etag":null,"topics":["azure","azure-table-storage","chatbots","csharp","microsoft-bot-framework"],"latest_commit_sha":null,"homepage":"https://tompaana.github.io/content/chatbots_as_middlemen.html","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tompaana.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-10-14T11:01:39.000Z","updated_at":"2025-01-14T19:57:42.000Z","dependencies_parsed_at":"2023-01-16T15:01:43.703Z","dependency_job_id":null,"html_url":"https://github.com/tompaana/intermediator-bot-sample","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tompaana%2Fintermediator-bot-sample","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tompaana%2Fintermediator-bot-sample/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tompaana%2Fintermediator-bot-sample/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tompaana%2Fintermediator-bot-sample/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tompaana","download_url":"https://codeload.github.com/tompaana/intermediator-bot-sample/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252357347,"owners_count":21735125,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["azure","azure-table-storage","chatbots","csharp","microsoft-bot-framework"],"created_at":"2024-11-13T05:25:02.436Z","updated_at":"2025-05-04T15:34:51.158Z","avatar_url":"https://github.com/tompaana.png","language":"C#","readme":"# Intermediator Bot Sample #\n\n[![Build status](https://ci.appveyor.com/api/projects/status/i1u8puahyxl79ha6?svg=true)](https://ci.appveyor.com/project/tompaana/intermediator-bot-sample)\n\nThis is a sample bot, built with the [Microsoft Bot Framework](https://dev.botframework.com/) (v4),\nthat routes messages between two users on different channels. This sample utilizes the\n[Bot Message Routing (component) project](https://github.com/tompaana/bot-message-routing).\nThe general gist of the message routing is explained in this article:\n[Chatbots as Middlemen blog post](https://tompaana.github.io/content/chatbots_as_middlemen.html).\n\nA possible use case for this type of a bot would be a customer service scenario where the bot relays\nthe messages between a customer and a customer service agent.\n\nThis is a C# sample targeting the latest version (v4) of the Microsoft Bot Framework. The sample\ndid previously target the v3.x and you can find that last release\n[here](https://github.com/tompaana/intermediator-bot-sample/releases/tag/v1.1).\n\nIf you prefer **Node.js**, fear not, there are these two great samples to look into:\n\n* [botframework-v4-handoff](https://github.com/GeekTrainer/botframework-v4-handoff)\n* [Bot-HandOff (v3)](https://github.com/palindromed/Bot-HandOff)\n\n#### Contents ####\n\n* [Getting started](#getting-started)\n* [Deploying the bot](#deploying-the-bot)\n* [App settings and credentials](#app-settings-and-credentials)\n* [Testing the hand-off](#testing-the-hand-off)\n* [About the implementation](#implementation)\n* [Custom agent portal](#what-if-i-want-to-have-a-custom-agent-portalchannel)\n* [Helpful links](#see-also)\n\n## Getting started ##\n\nSince this is an advanced bot scenario, the prerequisites include that you are familiar with the\nbasic concepts of the Microsoft Bot Framework and you know the C# programming language. Before\ngetting started it is recommended that you have the following tools installed:\n\n* [Visual Studio IDE](https://www.visualstudio.com/vs/)\n* [ngrok](https://ngrok.com/)\n* [Bot Framework Emulator](https://github.com/Microsoft/BotFramework-Emulator) ([download](https://github.com/Microsoft/BotFramework-Emulator/releases))\n    * [Debug bots with the Bot Framework Emulator](https://docs.microsoft.com/en-us/azure/bot-service/bot-service-debug-emulator?view=azure-bot-service-4.0)\n\nAltough the bot can be practically hosted anywhere, the deployment instructions (below) are for\nAzure. If you don't have an Azure subscription yet, you can get one for free here:\n[Create your Azure free account today](https://azure.microsoft.com/en-us/free/).\n\n## Deploying the bot ##\n\nThis sample demonstrates routing messages between different users on different channels. Hence,\nusing only the emulator to test the sample may prove difficult. To utilize other channels, you must\nfirst compile and publish the bot:\n\n1. Open the solution (`IntermediatorBotSample.sln`) in Visual Studio/your IDE and make sure it\n   compiles without any errors (or warnings)\n2. Follow the steps in this article carefully:\n   [Deploy your bot to Azure](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-howto-deploy-azure?view=azure-bot-service-4.0)\n   * Top tip: Create a new [Azure resource group](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-overview#resource-groups)\n     for the app so that if stuff goes wrong, it's really easy to just delete the whole group and\n     start over\n   * Having issues testing the bot (as in \"The dang thing doesn't work!!\") - check the following:\n     * Did you remember to include `/api/messages` in the messaging endpoint\n       (Bot Channels Registration/Settings)?\n     * Did you remember to create and add the credentials (`MicrosoftAppId` and `MicrosoftAppPassword`)?\n3. Add the credentials (`MicrosoftAppId` and `MicrosoftAppPassword`) to the\n   [`appsettings.json` file](/IntermediatorBotSample/appsettings.json) and republish the bot - now\n   all you need to do to republish is to right-click the app project in the **Solution Explorer** in\n   Visual Studio, select **Publish...** and click the **Publish** button on the tab (named in the\n   sample \"IntermediatorBotSample\").\n\n## App settings and credentials ##\n\nApp settings and credentials are available in the\n[`appsettings.json`](/IntermediatorBotSample/appsettings.json)\nfile of this sample. The file contains both bot and storage credentials as well as the settings that\ncan be used to tailor the experience. The default content of the file looks something like this:\n\n```json\n{\n  \"MicrosoftAppId\": \"\",\n  \"MicrosoftAppPassword\": \"\",\n  \"BotBasePath\": \"/api\",\n  \"BotMessagesPath\": \"/messages\",\n  \"AzureTableStorageConnectionString\": \"\",\n  \"RejectConnectionRequestIfNoAggregationChannel\": true,\n  \"PermittedAggregationChannels\": \"\",\n  \"NoDirectConversationsWithChannels\": \"emulator, facebook, skype, msteams, webchat\"\n}\n```\n\n### Settings ###\n\n* `BotBasePath` and `BotMessagesPath` can be used to define the messaging endpoint of the bot. The\n  endpoint by default is `http(s)://\u003cbot URL\u003e/api/messages`.\n* `RejectConnectionRequestIfNoAggregationChannel` defines whether to reject connection requests\n  automatically if no aggregation channel is set or not. Pretty straightforward, don't you think?\n* `PermittedAggregationChannels` can be used to rule out certain channels as aggregation channels.\n  If, for instance, the list contains `facebook`, the bot will refuse to set any Facebook\n  conversation as an aggregation channel.\n* The solution allows the bot to try and create direct conversations with the accepted \"customers\".\n  `NoDirectConversationsWithChannels` defines the channels where the bot should not try to do this.\n\n### Credentials ###\n\n* `MicrosoftAppId` and `MicrosoftAppPassword` should contain the bot's credentials, which you\n  acquire from the [Azure portal](https://portal.azure.com) when you publish the bot.\n* The bot needs to have a centralized storage for routing data. When you insert a valid Azure Table\n  Storage connection string as the value of the `AzureTableStorageConnectionString` property, the\n  storage automatically taken in use.\n\n## Testing the hand-off ##\n\nThis scenario utilizes an aggregation concept (see the terminology table in this document). One or\nmore channels act as aggregated channels where the customer requests (for human assistance) are\nsent. The conversation owners (e.g. customer service agents) then accept or reject the requests.\n\nOnce you have published the bot, go to the channel you want to receive the requests and issue the\nfollowing command to the bot (given that you haven't changed the default bot command handler or the\ncommand itself):\n\n```\n@\u003cbot name\u003e watch\n```\n\nIn case mentions are not supported, you can also use the command keyword:\n\n```\ncommand watch\n```\n\nNow all the requests from another channels are forwarded to this channel.\nSee the default flow below:\n\n| Teams | Slack |\n| ----- | ----- |\n| ![Setting the aggregation channel](Documentation/Screenshots/msteams-1-watch.png?raw=true) | |\n| | ![Connection request sent](/Documentation/Screenshots/slack-1-connection-request.png?raw=true) | |\n| ![Connection request accepted](/Documentation/Screenshots/msteams-2-accept-connection-request.png?raw=true) | |\n| ![Conversation in Teams](/Documentation/Screenshots/msteams-3-conversation.png?raw=true) | ![Conversation in Slack](/Documentation/Screenshots/slack-2-conversation.png?raw=true) |\n\n### Commands ###\n\nThe bot comes with a simple command handling mechanism, which supports the commands in the table\nbelow.\n\n| Command | Description |\n| ------- | ----------- |\n| `showOptions` | Displays the command options as a card with buttons (convenient!) |\n| `Watch` | Marks the current channel as **aggregation** channel (where requests are sent). |\n| `Unwatch` | Removes the current channel from the list of aggregation channels. |\n| `GetRequests` | Lists all pending connection requests. |\n| `AcceptRequest \u003cuser ID\u003e` | Accepts the conversation connection request of the given user. If no user ID is entered, the bot will render a nice card with accept/reject buttons given that pending connection requests exist. |\n| `RejectRequest \u003cuser ID\u003e` | Rejects the conversation connection request of the given user. If no user ID is entered, the bot will render a nice card with accept/reject buttons given that pending connection requests exist. |\n| `Disconnect` | Ends the current conversation with a user. |\n\nTo issue a command use the bot name:\n\n```\n@\u003cbot name\u003e \u003ccommand\u003e \u003coptional parameters\u003e\n```\n\nIn case mentions are not supported, you can also use the command keyword:\n\n```\ncommand \u003ccommand\u003e \u003coptional parameters\u003e\n```\n\nAlthough not an actual command, typing `human` will initiate a connection request, which an agent\ncan then reject or accept.\n\n## Implementation ##\n\nThe core message routing functionality comes from the\n[Bot Message Routing (component)](https://github.com/tompaana/bot-message-routing) project.\nThis sample demonstrates how to use the component and provides the necessary \"plumbing\" such as\ncommand handling. Here are the main classes of the sample:\n\n* **[HandoffMiddleware](/IntermediatorBotSample/Middleware/HandoffMiddleware.cs)**: Contains all the\n  components (class instances) required by the hand-off and implements the main logic flow. This\n  middleware class will check every incoming message for hand-off related actions.\n* **[CommandHandler](/IntermediatorBotSample/CommandHandling/CommandHandler.cs)**:\n  Provides implementation for checking and acting on commands in messages before they are passed to\n  a dialog etc.\n* **[MessageRouterResultHandler](/IntermediatorBotSample/MessageRouting/MessageRouterResultHandler.cs)**:\n  Handles the results of the operations executed by the **`MessageRouter`** of the Bot Message\n  Routing component.\n* **[ConnectionRequestHandler](/IntermediatorBotSample/MessageRouting/ConnectionRequestHandler.cs)**:\n  Implements the main logic for accepting or rejecting connection requests.\n\n## What if I want to have a custom agent portal/channel? ##\n\nWell, right now you have to implement it. There are couple of different ways to go about it. It's\nhard to say which one is the best, but if I were to do it, I'd propably start by...\n\n1. ...implementing a REST API endpoint\n   (see for instance [Create a Web API with ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-2.1)).\n   Then I'd hook the REST API into the message routing code and finally removed the text based\n   command handling altogether.\n2. Another options is to use back channel messages and hook them up into the current command\n   pipeline. Granted some changes would need to be made to separate the direct commands from the\n   back channel ones. Also, the response would likely need to be (or recommended to be) in JSON.\n3. Something else - remember, it's just a web app!\n\n## See also ##\n\n* [Bot Message Routing (component) project](https://github.com/tompaana/bot-message-routing)\n    * [NuGet package](https://www.nuget.org/packages/BotMessageRouting)\n* [Chatbots as Middlemen blog post](https://tompaana.github.io/content/chatbots_as_middlemen.html)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftompaana%2Fintermediator-bot-sample","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftompaana%2Fintermediator-bot-sample","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftompaana%2Fintermediator-bot-sample/lists"}