DEV Community

Cover image for Getting Started with Azure Bot Framework — Build Your First Bot in C#
Nikhil Panchabhai
Nikhil Panchabhai

Posted on

Getting Started with Azure Bot Framework — Build Your First Bot in C#

By Nikhil | Azure Developer | Bot Framework Enthusiast


Introduction

So I was working on a project where I had to build a chatbot that could talk to users, understand what they are asking, and reply back intelligently. That is when I got introduced to Azure Bot Framework and Azure Bot Service.

Honestly, when I first started, I was confused — is Bot Framework and Bot Service the same thing? What is a Dialog? Why is there something called a Turn? It took me some time to connect all the dots.

In this blog I will try to explain everything from scratch — the way I wish someone had explained it to me when I started. I will keep it simple and practical so even if you are completely new to this, you can follow along.

Let's get started!


What is a Bot Anyway?

Before we jump into Azure stuff, let me explain what a bot actually is in simple terms.

A bot is just an application that can have a conversation with a user. Instead of a user clicking buttons and filling forms, they just type (or speak) naturally — and the bot understands and responds.

Some real world examples:

  • Customer support chatbot on a bank website
  • HR bot inside Microsoft Teams that answers employee queries
  • E-commerce bot that helps you track your order
  • Flight booking bot that asks you where you want to go

Bots are becoming very common in enterprise applications because they save time and reduce manual effort.


Azure Bot Framework vs Azure Bot Service — Are They Same?

This was my first confusion when I started. Let me clear it up.

Bot Framework is Microsoft's open source SDK (Software Development Kit) that you use to write the bot logic. Think of it as the toolkit you use to build your bot. It is available in C#, JavaScript and Python.

Azure Bot Service is the cloud platform on Azure that hosts and manages your bot. It connects your bot to different channels like Web Chat, Microsoft Teams, Slack etc.

Simple way to remember:

Bot Framework SDK  =  You build the bot here (code)
Azure Bot Service  =  You deploy and manage the bot here (cloud)
Enter fullscreen mode Exit fullscreen mode

You build with Bot Framework and then deploy through Azure Bot Service. They work together but they are different things.


Architecture Overview

Before writing any code, it is good to understand how all the pieces fit together.

Here is what happens when a user sends a message:

  1. User types a message on Web Chat or Teams
  2. Message reaches Azure Bot Service
  3. Bot Service authenticates the request and converts it into a standard format
  4. Bot Service sends the message to your Bot API (your C# code)
  5. Your bot processes the message and generates a reply
  6. Reply goes back to Bot Service
  7. Bot Service delivers it to the user on their channel

The beauty of this is — your bot code stays the same regardless of which channel the user is on. Bot Service handles all the translation.


Prerequisites

Before we start, make sure you have these installed:

  • Visual Studio 2022 with Azure development workload
  • Azure Account (free tier works fine for practice)
  • ngrok — for exposing your local bot to internet during development
  • .NET 6 or higher

Step 1 — Create Your First Bot Project

Open Visual Studio 2022 and follow these steps:

  • Click Create a new project
  • Search for Bot Framework
  • Select Core Bot template
  • Give it a name like MyFirstBot
  • Click Create

Architecture diagram showing User → Channel → Azure Bot Service → ngrok → Bot API → Bot Logic

Visual Studio will generate a complete bot project for you with a proper folder structure.


Step 2 — Understanding the Project Structure

When you open the generated project, you will see something like this:

Visual Studio Solution Explorer showing CoreBot project structure

Let me explain the important files:

appsettings.json — This is where you put your Azure credentials like App ID, Password and Tenant ID.

Startup.cs — This is where all services are registered including State, Dialogs and the Bot adapter.

Controllers/BotController.cs — This is the entry point. All incoming messages hit the /api/messages endpoint here.

Bots/DialogBot.cs — This is the main bot class that receives activities and passes them to dialogs.

Dialogs/MainDialog.cs — This is where your conversation logic lives.


Step 3 — Key Concepts You Must Know

Let me explain the most important concepts before we go further.

What is an Activity?

Everything that happens in a conversation is called an Activity. When a user sends a message — that is an Activity. When a user joins the conversation — that is also an Activity. Even the typing indicator is an Activity.

The most common Activity type is message — which carries the actual text from the user.

// You can check the Activity type like this
if (turnContext.Activity.Type == ActivityTypes.Message)
{
    // User sent a message
    var userMessage = turnContext.Activity.Text;
}
Enter fullscreen mode Exit fullscreen mode

Actual BotController.cs code from Visual Studio

What is a Turn?

A Turn is one complete round of conversation — the user sends one message and the bot sends one reply. That entire exchange is called a Turn.

User: "Hi"           ← Start of Turn 1
Bot:  "Hello!"       ← End of Turn 1

User: "Book a flight" ← Start of Turn 2
Bot:  "Where to?"    ← End of Turn 2
Enter fullscreen mode Exit fullscreen mode

What is TurnContext?

TurnContext is an object that is available during the entire Turn. It contains the incoming message, and methods to send a reply back.

// TurnContext gives you everything about the current turn
public async Task OnTurnAsync(ITurnContext turnContext, 
    CancellationToken cancellationToken)
{
    // Read user message
    var userMessage = turnContext.Activity.Text;

    // Send reply
    await turnContext.SendActivityAsync("Hello! How can I help?");
}
Enter fullscreen mode Exit fullscreen mode

DialogBot.cs OnTurnAsync method from Visual Studio


Step 4 — Understanding Dialogs

Dialogs are reusable components that manage a specific conversation flow. Think of a Dialog as a function that handles one specific task — like a registration flow, booking flow, or FAQ flow.

Types of Dialogs

WaterfallDialog — This is a step by step linear dialog. Each step asks something and moves to the next step.

// WaterfallDialog example — step by step flow
AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
{
    AskNameStepAsync,    // Step 1: Ask name
    AskAgeStepAsync,     // Step 2: Ask age
    ConfirmStepAsync,    // Step 3: Confirm details
    FinalStepAsync       // Step 4: Save and finish
}));
Enter fullscreen mode Exit fullscreen mode

ComponentDialog — This is a container that groups related dialogs together. Your MainDialog is a ComponentDialog.

PromptDialogs — These are specialized dialogs for collecting specific types of input from user:

  • TextPrompt — for any text input
  • NumberPrompt — for numbers only
  • ChoicePrompt — for multiple choice options
  • ConfirmPrompt — for yes/no questions
  • DateTimePrompt — for dates and times

DialogBot.cs OnTurnAsync method from Visual Studio


Step 5 — State Management

This is a very important concept. By default, a bot has no memory — every Turn is independent. If you ask the user their name in Turn 1, the bot will forget it by Turn 2.

That is where State Management comes in.

Bot Framework provides three types of state:

UserState — Remembers data for a specific user across all conversations. Good for storing user profile, preferences etc.

ConversationState — Remembers data for the current conversation. Good for tracking which step of a dialog the user is on.

PrivateConversationState — Remembers data that is private to one user in one specific conversation.

// Register state in Startup.cs
services.AddSingleton<IStorage, MemoryStorage>(); // Use for local dev only
services.AddSingleton<UserState>();
services.AddSingleton<ConversationState>();
Enter fullscreen mode Exit fullscreen mode

Startup.cs showing state registration

⚠️ Important: Use MemoryStorage only for local development and testing. It stores data in RAM and loses everything when the bot restarts. For production, always use Azure Blob Storage or Azure Cosmos DB.


Step 6 — Middleware Pipeline

Middleware in Bot Framework works exactly like ASP.NET Core middleware. Every Activity passes through the middleware pipeline before reaching your bot logic and after your bot sends a response.

Incoming Activity
      ↓
Logging Middleware
      ↓
State Middleware
      ↓
Your Bot Logic
      ↓
(Same pipeline in reverse for response)
Enter fullscreen mode Exit fullscreen mode

Some built-in middleware:

  • AutoSaveStateMiddleware — automatically saves state after each turn
  • ShowTypingMiddleware — shows typing indicator while bot is processing
  • TranscriptLoggerMiddleware — logs all conversations

You can also write your own custom middleware for things like logging, translation, or profanity filtering.


Step 7 — Setup Azure Bot Service

Now that our bot code is ready, we need to connect it to Azure Bot Service.

Create App Registration

  • Go to Azure Portal
  • Navigate to Azure Active Directory → App Registrations
  • Click New Registration
  • Give it a name
  • Select appropriate account type
  • Click Register

Azure Portal App Registration creation screen

After creating, note down:

  • Application (client) ID — this is your MicrosoftAppId
  • Directory (tenant) ID — this is your MicrosoftAppTenantId

Then go to Certificates & Secrets and create a new Client Secret. Copy the Value immediately — you won't see it again!

⚠️ Common Mistake: People often copy the Secret ID instead of Secret Value. Always copy from the VALUE column, not the ID column.

Create Azure Bot Resource

  • Azure Portal → Create a resource → Search Azure Bot
  • Fill in bot handle and resource group
  • Select appropriate App type
  • Click Create

Azure Bot creation screen in Azure Portal

Update appsettings.json

{
  "MicrosoftAppType": "SingleTenant",
  "MicrosoftAppId": "your-app-id-here",
  "MicrosoftAppPassword": "your-client-secret-value-here",
  "MicrosoftAppTenantId": "your-tenant-id-here"
}
Enter fullscreen mode Exit fullscreen mode

Appsettings.json from Visual Studio with masked credentials


Step 8 — Local Testing with ngrok

During development your bot runs on localhost. But Azure Bot Service needs a public HTTPS URL to reach your bot. This is where ngrok comes in.

ngrok creates a public tunnel to your localhost.

# Start ngrok to expose port 3978
ngrok http 3978
Enter fullscreen mode Exit fullscreen mode

ngrok terminal showing the https forwarding URL

Copy the HTTPS URL from ngrok and paste it in Azure Bot Service:

  • Azure Portal → Your Bot → Configuration
  • Set Messaging Endpoint to: https://your-ngrok-url.ngrok-free.app/api/messages
  • Click Apply

Azure Bot Configuration page with messaging endpoint filled

⚠️ Important: Every time you restart ngrok the URL changes. You need to update it in Azure Bot Configuration every time.


Step 9 — Test Your Bot

Now run your project in Visual Studio (F5) and go to:

Azure Portal → Your Bot → Test in Web Chat

Type Hi and your bot should respond!

Azure Web Chat showing bot responding to Hi message

If you see a response — congratulations! Your first bot is working!


Common Errors and How I Fixed Them

I faced quite a few errors while setting this up. Here are the most common ones and how to fix them:

Operation returned an invalid status code 'Unauthorized'

  • Check your MicrosoftAppId and MicrosoftAppPassword in appsettings.json
  • Make sure you copied Secret VALUE not Secret ID
  • Verify App type matches between Azure Bot and appsettings.json

Application was not found in the directory 'Bot Framework'

  • This usually means App type mismatch — SingleTenant vs MultiTenant
  • Verify your MicrosoftAppType in appsettings.json matches the Bot Service configuration

ngrok — Upgrade to WebSocket is required

  • This is normal! It appears when you open the ngrok URL directly in browser
  • The bot endpoint only accepts POST requests from Bot Framework
  • Test through Azure Web Chat, not by opening the URL in browser

What is LUIS / CLU?

Most real bots need to understand what the user is saying in natural language. For example if user types "I want to book a ticket to Mumbai for next Friday" — your bot needs to understand:

  • Intent — user wants to book a ticket (BookFlight)
  • Entity — destination is Mumbai, date is next Friday

This is where LUIS (Language Understanding Intelligent Service) comes in. You train LUIS with example phrases and it learns to identify intents and entities from user messages.

⚠️ Note for interviews: LUIS is being retired and replaced by Azure AI Language — CLU (Conversational Language Understanding) in 2025. Mention this in interviews to show you are up to date.


Channels — Deploy Your Bot Everywhere

One of the best things about Azure Bot Service is Channels. You write your bot code once and connect it to multiple platforms.

Azure Bot Channels page showing available channels

Some popular channels:

  • Web Chat — embed on any website
  • Microsoft Teams — enterprise users
  • Direct Line — for custom applications and mobile apps
  • Slack — team collaboration
  • Facebook Messenger — social platform
  • WhatsApp — mobile users

For custom web or mobile apps, Direct Line is the recommended approach. You get a secret key and use the Direct Line SDK to connect your custom UI to the bot.


What I Learned from This Experience

Building my first bot was a great learning experience. A few things I want to highlight:

Start simple — Don't try to add LUIS, state management and everything at once. First get a simple echo bot working, then add features one by one.

Use Bot Framework Emulator — For local testing, the emulator is much easier than setting up ngrok and Azure. Connect directly to http://localhost:3978/api/messages with empty credentials.

Understand the flow — Once you understand the Turn, Activity, Dialog stack flow — everything else falls into place. It took me some time but once it clicked, it became easy.

State management is important — Don't underestimate this. A bot without proper state management will forget everything between turns and create a terrible user experience.


Next Steps

If you have got your first bot working, here is what you can explore next:

  • Add LUIS / CLU — Make your bot understand natural language
  • Adaptive Cards — Create rich UI cards with buttons, images and forms inside the chat
  • Proactive Messaging — Make your bot send notifications without user initiating
  • OAuth Authentication — Let users login through your bot
  • Deploy to Azure App Service — Move from ngrok to proper production deployment
  • Direct Line Integration — Embed your bot in a custom React or mobile app

Conclusion

Azure Bot Framework and Bot Service is a really powerful combination for building enterprise grade chatbots. Once you understand the core concepts — Activity, Turn, TurnContext, Dialogs, State — building bots becomes quite straightforward.

I hope this blog helped you get started. If you have any questions or faced any errors during setup, drop them in the comments — I will try to help based on my experience.

Happy coding!


If you found this helpful, do share it with your developer friends. Follow me for more Azure and .NET content.


Tags: #azure #botframework #dotnet #csharp #chatbot #azurebotservice #beginners

Top comments (0)