Source Code


Proper set up of environment is one of most important things during development. Leverage ngrok tunneling service to speed up development process.


When developing bots for public chatting platforms like Microsoft Teams, Facebook, Slack etc. it is very that often not all features are available and therefore can’t be tested using Microsoft Bot Framework Emulator. Public chatting platforms need public endpoints which removes ability for developers to debug applications which extends development process greatly. A solution to this problem is a Software as a Service solution called ngrok.

What is ngrok?

Ngrok is secure introspectable tunnel service to localhost webhook development tool and debugging tool. Service provides public DNS for applications to use and tunnels all the messages to the developer local machine. This way developer can still use public platforms to develop and test and still retain ability to debug entire solution live.

Setting up environment

In order to develop effectively a developer should be able to create bots locally and publish them easily to the web.

Best way to achieve this is by creating two bots

  1. Localhost bot which points to ngrok tunneling endpoint
  2. Public Azure bot which points to Azure Bot Service

In this article a Microsoft Teams bot example will be presented. Microsoft Teams is a great example of bot channel which does allow for development of extra features and as such making bot framework emulator useless in terms of proper development.


Starting this article requires

  1. Microsoft Teams (electron app) Client for Windows
  2. Visual Studio (Visual Studio Code can also be used as only publishing to Azure is different)
  3. Git
  4. Azure subscription
  5. ngrok

Register Localhost bot in Teams

  1. Run ngrok using command line. Use the proper port number that will be set up on your local machine.
    ngrok http 3333 -host-header=localhost:3333
    Which should output something similar to
    ngrok by @inconshreveable                      
    Session Status                online
    Session Expires               7 hours, 55 minutes
    Version                       2.2.8
    Region                        United States (us)
    Web Interface       
    Forwarding           -> localhost:3333
    Forwarding           -> localhost:3333
    Connections                   ttl     opn     rt1     rt5     p50     p90
                                  0       0       0.00    0.00    0.00    0.00
    This basically means that bot app will be available under endpoint.
  • With free pricing tier developers get random subdomain on ngrok service every time they run the application. This is very troublesome for longer development because during bot registration developer must supply publicly visible endpoint. This means every time developer restarts ngrok they will need to edit bot endpoint on bot framework portal. For commercial uses it is very recommended to purchase license so that developer can register custom domains using command below which will allow for static bot routing under endpoint.
    ngrok http 3333 -subdomain=marczakio-dev-local -host-header=localhost:3333
  1. Register a bot by using this Note this is crucial to use this link as the button on the site no Longer points to form creation. Instead it redirects user to Azure Bot Service creation form.
  • Bot Profile
  • Display name name for the bot, this is only display name in the Bot Framework Portal for developers to recognize their bots by name. This does not affect bot functionality in any way.
  • Bot handle reference to bot, does not matter in this example.
  • Long description bot description. Does not affect functionality.
  • Configuration
  • Messaging endpoint public url endpoint for bot framework to redirect messages to. This is built by combining public endpoint and /api/messages route. In this example url is
  • Microsoft App ID unique identifier for application registered from Microsoft App portal. Click on the create Microsoft App button to register the app or provide already existing app id. Do NOT share same ID across multiple bot instances.
    And by clicking Generate password new password will be generated. Copy password as it won’t be shown anywhere later on.
  • Analytics
  • Application insights section. Leave this empty for localhost development. In case of bot service Azure fill this for developer during bot creation process.
  • Admin Section
  • Owners list of accounts which have administrative access to the bot.
  1. Click Create button
  2. Go to bot settings tab
  3. Add Teams Channel
    Agree to TOS (terms of use)
  4. Run git clone to copy solution and start development
    git clone
    cd msteams-samples-hello-world-csharp
  5. Restore packages by right clicking the solution and clicking
  6. Edit Web.config file and supply Microsoft App ID and password
    <add key="MicrosoftAppId" value="d008dfca-c5d7-4b1b-a074-ad76081d6e3b" />
    <add key="MicrosoftAppPassword" value="eymiSZXF86||%ktzWFP781!" />
  7. Start Solution (keep it running dont close it)
  8. Configure Manifest
  • Replace id and botId fields with Microsoft App ID
  • Give unique package ID for **
  • Final JSON should look like below
      "$schema": "",
      "manifestVersion": "1.0",
      "version": "1.0.0",
      "id": "d008dfca-c5d7-4b1b-a074-ad76081d6e3b",
      "packageName": "io.marczak.teambot",
      "developer": {
        "name": "MarczakIO",
        "websiteUrl": "",
        "privacyUrl": "",
        "termsOfUseUrl": ""
      "name": {
        "short": "Local MarczakIO Teams Bot",
        "full": "Local MarczakIO Teams Bot"
      "description": {
        "short": "Local MarczakIO Teams Bot",
        "full": "Local MarczakIO Teams Bot"
      "icons": {
        "outline": "contoso20x20.png",
        "color": "contoso96x96.png"
      "accentColor": "#60A18E",
      "staticTabs": [
          "entityId": "io.marczak.teambot.hellotab",
          "name": "Hello Tab",
          "contentUrl": "",
          "scopes": [
      "configurableTabs": [
          "configurationUrl": "",
          "canUpdateConfiguration": true,
          "scopes": [
      "bots": [
          "botId": "d008dfca-c5d7-4b1b-a074-ad76081d6e3b",
          "needsChannelSelector": false,
          "isNotificationOnly": false,
          "scopes": [
      "permissions": [],
      "validDomains": []
  1. Zip the manifest file with the icons

Upload bot and test it in Teams

  1. Open Teams app and create new team
  2. Supply name for the Team
  3. Add bot to the team
  4. Go to manage Team option
  5. Go to Apps tab and click on Upload a custom app and select file
  6. Check if the app uploaded successfully
  7. Talk to bot by mentioning it by typing @Local and pressing tab
  8. Say hey to the bot
  9. Put a breakpoint in EchoBot.cs file at line 17 and say something to the bot
  10. Check ngrok and check bot responses coming through
    ngrok by @inconshreveable   
    Session Status                online
    Session Expires               7 hours, 22 minutes
    Version                       2.2.8
    Region                        United States (us)
    Web Interface       
    Forwarding           -> localhost:3333
    Forwarding           -> localhost:3333
    Connections                   ttl     opn     rt1     rt5     p50     p90
                                  35      0       0.02    0.01    1.30    102.18
    HTTP Requests
    POST /api/messages             202 Accepted
    POST /api/messages             202 Accepted

What’s next?

Follow the same process and publish bot to Azure. While the Azure UI changed a bit, it is still very easy to follow Introduction to chatbots post. With that setup everyone can deliver DevOps for bots effectively.

Source Code

Adam Marczak

Programmer, architect, trainer, blogger, evangelist are just a few of my titles. What I really am, is a passionate technology enthusiast. I take great pleasure in learning new technologies and finding ways in which this can aid people every day. My latest passion is running an Azure 4 Everyone YouTube channel, where I show that Azure really is for everyone!

Did you enjoy the article?

Share it!

More tagged posts