Message Extensions|Mastering Microsoft Teams Bots 4.3

4.3 Message Extensions

Until now, your bot has lived in chat — responding to messages, guiding conversations, or popping up in modals. But what if your users want to interact with your bot without leaving their current conversation? What if they want to search, trigger an action, or insert a card directly into a reply?

That’s what Message Extensions are for.

Message Extensions (also called Messaging Extensions or Compose Extensions) let users invoke your bot from the message composer bar — the place where people type their messages in Teams. Instead of typing a command or mentioning a bot, they can just click a button or type a keyword to search or run an action.

4.3.1 What Are Message Extensions?

Message Extensions allow your bot to provide a custom search or action experience inside the message input box in Teams. They support two main modes:

  • Search-based (Query): The user types a keyword or query, and your bot returns a list of cards or results to insert into a message.
  • Action-based: The user clicks a button (e.g., “Create Task”), fills out a Task Module form, and submits it back to the conversation as a card.

Think of it like building your own mini-Google, form tool, or content library — inside the Teams message box.

4.3.2 Use Cases

  • Search for a customer record and insert it into chat
  • Create a support ticket with summary fields
  • Share a status update or task from your own system
  • Browse recent documents or deals and post one

4.3.3 Example: Search Extension

When a user types into your message extension, Teams sends a composeExtension/query invoke to your bot. Your bot returns a list of cards for the user to choose from.


// Node.js
teams.onInvokeActivity(async (context) => {
  const query = context.activity.value.parameters[0].value;
  const results = await searchDatabase(query);

  return {
    composeExtension: {
      type: "result",
      attachmentLayout: "list",
      attachments: results.map(r => CardFactory.heroCard(r.title, r.subtitle))
    }
  };
});
  

4.3.4 Example: Action Extension

You can define an action button in your app manifest that opens a Task Module for input:


// App manifest entry
"composeExtensions": [{
  "commands": [{
    "id": "createTask",
    "title": "Create Task",
    "type": "action",
    "taskInfo": {
      "title": "New Task",
      "height": "medium",
      "width": "medium",
      "url": "https://yourdomain.com/taskForm"
    }
  }]
}]
  

When the form is submitted, your bot receives a composeExtension/submitAction and can return a card to insert into the chat.

4.3.5 Returning a Card into the Conversation


return {
  composeExtension: {
    type: "result",
    attachmentLayout: "list",
    attachments: [
      CardFactory.heroCard("Task Created", "Project Alpha - Due Friday")
    ]
  }
};
  

4.3.6 Registering a Message Extension

Unlike simple bots, Message Extensions require a well-structured app manifest with proper permissions and extension definitions. You’ll also need to ensure that your bot handles invoke activities and returns valid payloads.

4.3.7 UX Tips

  • Keep results fast and lightweight — users expect instant suggestions.
  • Use clear titles and icons for your commands.
  • Return cards that are visually clean and readable in Teams.
  • Use Task Modules for anything requiring more than one input field.

4.3.8 Summary

Message Extensions are a powerful way to let users reach into your system and surface useful data right from where they’re already working. When done right, they make your bot feel less like a helper, and more like an extension of Teams itself.

In the next section, we’ll tackle localization and multi-tenant support — the keys to making your bot work seamlessly across organizations and languages.

2025-04-13

Shohei Shimoda

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