Message Handling|Mastering Microsoft Teams Bots 3.1

3.1 Core Features of Teams Bots – Message Handling

Now that your bot knows who it's talking to, it's time to teach it how to listen — and respond intelligently.

In this section, we dive into message handling, the most fundamental capability of any Teams bot. Whether you're building a virtual assistant, a notification agent, or a full-blown workflow orchestrator, it all begins with how your bot handles incoming messages.

3.1.1 Types of Messages in Teams

A user can interact with your bot in different ways, and each interaction arrives as a different type of Activity via the Bot Framework. The most common are:

  • Message: A user sends a chat message (text or command).
  • ConversationUpdate: Someone is added to a chat or team.
  • MessageReaction: A user reacts (e.g., 👍) to a bot message.
  • Invoke: User submits an Adaptive Card or opens a Task Module.

For this section, we’ll focus on handling standard messages.

3.1.2 Basic Message Handling

Every Teams bot includes an OnMessageActivityAsync (C#) or onMessage (Node.js) handler. This is where your bot reads user input and decides how to respond.

Example in .NET:


public override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
    var text = turnContext.Activity.Text?.ToLowerInvariant();
    if (text.Contains("hello"))
    {
        await turnContext.SendActivityAsync(MessageFactory.Text("Hi there! 👋"), cancellationToken);
    }
    else
    {
        await turnContext.SendActivityAsync(MessageFactory.Text("I'm not sure what you mean."), cancellationToken);
    }
}
  

Example in Node.js:


this.onMessage(async (context, next) => {
    const text = context.activity.text.trim().toLowerCase();
    if (text.includes("hello")) {
        await context.sendActivity("Hi there! 👋");
    } else {
        await context.sendActivity("I'm not sure what you mean.");
    }
    await next();
});
  

3.1.3 Mention Detection and Channel Context

In group chats or Teams channels, your bot may be mentioned with @YourBot. The message payload will include an Entities array with the mention, and your bot must strip this before interpreting the user message.

Example in JavaScript:


const removeMention = (text, botId) => {
    const mentionRegex = new RegExp(`<at>.*?</at>`, 'g');
    return text.replace(mentionRegex, '').trim();
};
  

You can also detect the type of conversation (personal chat vs team channel) with:

context.activity.conversation.conversationType

3.1.4 Message Formatting

Bots can respond with:

  • Plain text – Simple strings
  • Markdown – Basic formatting (bold, italics, links)
  • Adaptive Cards – Interactive, JSON-defined UI (see Section 3.2)

Example with Markdown:


await turnContext.SendActivityAsync("**Bold message** with [link](https://example.com)");
  

3.1.5 Keyword vs Natural Language

Most bots begin with keyword matching (e.g., checking for “hello”, “help”, “status”). It’s easy and fast, but brittle. For a better user experience, consider integrating:

  • LUIS (Language Understanding): Microsoft’s NLU service
  • OpenAI or GPT-based services: For flexible, conversational bots
  • Regex: For controlled, pattern-based matching

3.1.6 Common Use Case: Help Command

Many bots implement a simple help command that summarizes what they can do. It’s good practice to guide users up front.


if (text.includes("help")) {
    await context.sendActivity("I can help you with:\n- `hello`\n- `status`\n- `report`");
}
  

3.1.7 Summary

Message handling is the backbone of any Teams bot. It starts simple — “If user says X, respond with Y” — but grows into complex patterns of recognition, personalization, and workflow initiation.

In the next section, we’ll enhance our responses by using Adaptive Cards — making our bot feel more like an app than a chat window.

2025-04-08

Shohei Shimoda

I organized and output what I have learned and know here.