Microsoft Teams has become the operating system for modern work, but its real power lies in extensibility. While chat is great, having a bot that can automate workflows, acknowledge meeting attendees, or pull real-time data into a conversation takes productivity to the next level.
In this guide, we’re going to walk through building a Multitenant Microsoft Teams Bot using the Azure Bot Service. We’ll cover everything from the initial Azure setup to the C# code that powers the bot’s logic.
Let’s be honest: Microsoft Teams is the operating system for modern work. But if you are just using it for chat, you are leaving a lot of power on the table. The real magic happens when you start building extensions—specifically, bots.
Imagine a bot that doesn’t just reply with text but actually automates your workflow, acknowledges meeting attendees, or pulls live data right into your meeting window. That is exactly what we are going to build today.
I’m going to walk you through creating a Multitenant Microsoft Teams Bot using the Azure Bot Service. We will cover the whole process, from the initial “click-ops” in the Azure Portal to the C# code that makes it tick.
Step 1: Give Your Bot an Identity
Before we write any code, our bot needs a digital ID card. We handle this in the Azure Portal by registering an application.
- Register the App Head over to the Azure Portal, sign in, and search for “App registrations”. Hit that + New registration button to get things moving.

- Fill in the Blanks You will see a form pop up. Here is what you need to do:
-
- Name: Pick something easy to identify, like MyMultitenantApp.
- Account Type: This is the important part. Since we want this bot to work for different organizations (not just your own), make sure you select “Accounts in any organizational directory (Multitenant)”.
- Redirect URI: You can leave this optional for now, or just throw in https://localhost if you are testing on your local machine.
Once you hit Register, Azure will generate a few keys for you. Stop right there and copy two things: the Application (Client) ID and the Directory (Tenant) ID. If you lose these, you’ll have to come back and dig for them later.

Step 2: Create the Bot Service
Now that we have an identity, we need the actual bot infrastructure to back it up.
- Spin up the Resource Go back to the Azure search bar, type “Azure Bot”, and create a new resource.

- The Critical Link This is where most people get tripped up. When you are filling out the details (like your bot handle and resource group), look for the Microsoft App ID section. Do not ask it to create a new ID. Instead, select “Use existing app registration” and paste in that Client ID you grabbed in Step 1.

- Point it in the Right Direction Once your bot is deployed, it needs to know where to send incoming messages. Go to Settings > Configuration and find the Messaging endpoint field. This is where you paste your API URL (something like https://yourdomain.com/api/messages).

- Turn on Teams By default, your bot is just floating in the void. You need to tell it which channels to listen to. Go to the Channels blade and flip the switch for Microsoft Teams. Now it’s ready to talk.

Step 3: Lock Down the Security
We need to make sure the handshake between your app and the bot service is secure.
- Generate a Secret Head back to your App Registration and look for Certificates & secrets. Create a New client secret. Pro tip: Copy the “Value” immediately. Azure hides this permanently once you navigate away, and you don’t want to regenerate it if you don’t have to.

- Permissions If your bot needs to read user profiles (which it probably does), go to API permissions. Add a permission for Microsoft Graph, select User.Read, and—this is crucial—click Grant admin consent. If you skip the consent step, the permissions won’t actually work.

Step 4: The Code (Making it Smart)
Okay, infrastructure is done. Let’s talk code. We are using C# to build an EchoBot that listens for messages and decides what to do with them.
The Main Logic Everything centers around the OnMessageActivityAsync method. Think of this as the bot’s front door. When a message knocks, here is what happens:
- Cleanup: First, we scrub the message. The bot usually receives text like “@BotName Hello”. We use RemoveRecipientMention() to strip out the name so we are just left with “Hello”.
- Context Check: We grab the meeting details using TeamsInfo.GetMeetingInfoAsync to see exactly where this conversation is happening.
- Subscription Check: We don’t want just anyone using the bot. We inject a service called _offersService to verify if the user’s organization has a valid subscription.
- The Response: If they are clear, we send a notification payload back to the chat.
Here is a snippet of how we construct that notification:
C#
var activity = MessageFactory.Text(“Notification”);
activity.ChannelData = new
{
Notification = new
{
AlertInMeeting = true,
ExternalResourceUrl = $”https://teams.microsoft.com/l/bubble/{_config[“MicrosoftAppId”]}?url=…”
}
};
await turnContext.SendActivityAsync(activity);
The Manifest To make your bot show up properly in Teams, you need a manifest.json file. This tells Teams your app’s name, where it lives, and what it can do. One specific setting to watch: make sure scopes includes groupChat if you want this bot to work inside meetings.
Step 5: The User Interface (Razor Pages)
Sometimes text isn’t enough. We used a Razor Page to pop up a rich HTML window when a user interacts with the bot.
The page is pretty simple: it grabs query parameters (like the organization ID) from the URL and fetches the content it needs to display. We also use Html.Raw() to render the content so we can include formatted text and images.
Note: We inject the Microsoft Teams SDK (MicrosoftTeams.min.js) right into the head of the page. This ensures the page knows it is running inside Teams and can initialize correctly.
Wrapping Up
Building a Teams bot might feel like a lot of moving parts—you are juggling Azure resources, app registrations, and code all at once. But once you get the pipeline set up, it is incredibly powerful. You are effectively putting your custom software right into the tool your team uses every single day.
Ready to try it?
-
- Deploy your code to the messaging endpoint you set up.
- Use the Test in Web Chat button in the Azure Portal to make sure it’s alive.
- Sideload the manifest into your Teams client and see it in action!
