How we can extend Microsoft Teams with custom apps — the non-technical explanation

How we can extend Microsoft Teams with custom apps — the non-technical explanation
A small heads-up: Some organizations are using this blog post for marketing their own services on social media by giving the impression that I’d somehow be connected to their company. While it is not illegal, I think it still falls into the morally grey area and hence wanted to clarify that the company I work for is called Sulava. I have no connections to any other suppliers.

Based on my experience, Teams app development isn’t common yet. Have you noticed the same? I imagine many developers are eagerly waiting to get to work on some cool customer projects on the Teams platform, but customer cases are just not coming in.

There is one underlying reason why we aren’t seeing more Teams app development for real customer scenarios today: people don’t know enough about it. Either they don’t know that extending Teams is possible, or they don’t know what the exact options that are available are. This leads to…

  • Customers don’t know to ask for something to be developed as a Teams app. It does not even cross their minds because they’ve never seen it done before! Instead, they do what they’ve always done and have the customization implemented outside of Teams. And that is fine when it feels more natural to use the piece of software outside of Teams. But what if Teams were the most natural place, and they just don’t think of it as an option? That’d be such a shame.
  • Consultants don’t come to suggest implementing something as a Teams app. Again, they’ve not seen it being done before, they are unsure about what is possible, and are reluctant to suggest anything. However, one of the key things that make consultants so valuable is their constant communication with customers. They are hyperaware of cues that indicate possible pain-points in the customer organization’s processes. Sometimes, implementing a custom Teams application could be the best solution for solving those problems, and for those situations, it would be in everyone’s best interests to be aware of the possibilities.

Typically consultants talk to the customers — not developers. To get to the point of developing a custom Teams application, the consultant first needs to either recommend it to the customer or involve a developer in the conversation. Quite often, when a customer asks whether a feature exists in Teams or not, the consultant simply says “No, that’s not possible” or directs the customer to create a user voice request. But that’s not how it should be!

The correct way of responding in those situations is: “No, it does not exist out-of-the-box, but we might be able to implement it for you as customization. Let me involve a developer in this conversation”. This kind of approach is vital, especially in the situations in which the need is very business-specific. It is also essential when the details regarding the functionality (how exactly people want it to work) vary greatly between organizations (Teams provisioning is an excellent example of this). That kind of “rarer” features are unlikely to ever make it to the core product. And even if the feature would be more general and could be used by multiple organizations, getting your hands on the feature years earlier can save tremendous time and effort. When you are able to spend that time on tasks that are less easily automated, implementing such features can even be considered profitable.

The purpose of this blog post is to explain to everyone — devs, consultants, customers, and everyone in between — how we can implement customizations for Teams and extend its out-of-the-box capabilities. Make sure also to share this post with your friends! Let’s educate as many people as possible about the topic! I hope that soon, Teams will be better known as a development platform. 🙂

Table of Contents

  1. The extension points of Teams
  2. Tabs
  3. Bots
  4. Messaging extensions
  5. Outgoing webhooks
  6. Incoming webhooks
  7. Connectors
  8. Adaptive cards
  9. Task modules

The extension points of Teams

Indeed, we can’t customize Teams in just any way we please. However, it works in a very similar manner to the modern sites on SharePoint Online. There are extension points that allow us to insert our custom content and behaviours to “enrich” the core product.

The key things to identify before implementing Teams apps are:

  • Do we want to display information or trigger a background process (or both)?
  • What place in Teams feels the most natural for the user to view the information or trigger the process?

Here’s a picture of all of the available extension points. I’ll also be presenting a similar image when going through the individual app types, so you’ll know which extension points apply to that particular type of app.

Tabs

Tabs allow us to add new views to Teams. They are our most broad option for “editing the user interface” as you can’t extensively modify how Teams looks outside of them.

Tabs typically work in the context of a team. You add them to a channel, and they appear as a tab there the same way as Posts and Files do.

However, you can also add tabs to the Teams left-hand navigation. These are called “static tabs” (vs “configurable tabs” that are on a team channel) or personal apps. They are basically tabs outside of the team context — hence “personal”. A user can use them regardless of what teams they belong to. They are great when you want to offer a tab to a large number of users who don’t necessarily belong to any one team.

The custom app icon is pinned to the left-hand navigation in the same ways as Chats, Teams, and other apps are. Less frequently used apps that aren’t pinned, can be found behind the three dots. You can use the Teams app setup policies in the Teams admin centre to define which apps show as pinned to which users.

Behind the scenes, both of these tab types work essentially the same way and are basically web pages. If you can imagine something you’d like to get done as a web page, it can be brought into Teams as a tab. The same applies to already existing web pages. If you already have a website and you’d just like to bring it closer to the users in Teams, it is merely a matter of configuration to make that happen.

Channel tabs are good when:

  • You want to show content that is related to the team or the channel where the tab is added.

Personal tabs are good when:

  • You want the view to be easily accessible regardless of which teams the user belongs to.
  • The displayed content is not related to any team-level activities, but is more independent.

Bots

Bots allow users to trigger background operations in a conversational manner. A bot can potentially be triggered via all the different types of conversations (this can be narrowed down via settings):

  • 1-to-1 chat
  • Group chat
  • Channel conversation

In the picture below, the user is using the bot via the private chat. The bot typically has a set of commands the user can choose from, which helps the bot to understand, what the user wants it to do. In this example, when the user either clicks on the “New request” button or types in “New request” to the chat, the bot proceeds to offer the user a form to fill.

Note that the bot can also be made more easily accessible as a personal app! This way a conversation with the bot can be opened via a separate icon in the left-hand side navigation instead of looking for it in chat conversations.

The “core” of a bot is the background web service that does the actual work behind the scenes. When a user talks to the bot, the user’s message is sent to the background service, which then does something (nearly anything you want it to do) based on the message. The bot is primarily simply a way for us to trigger the process.

After doing whatever we want the background process to do, it can send a response back to the Teams user. Again, we can define the reply to be whatever we want. The whole background service can be coded precisely the way we want it. The “bot” is just a way for the user to use the service.

In this case, the Remote Support bot first returned the form to the user (upon getting the “New request” command). Upon form submission, it directed the request to the support team. I love this use case, and it is something a few of my customers have been very interested in. The Remote Support bot is an open-source app available on GitHub, and it can be further customized to your needs.

Bots are good when:

  • The task feels the most natural to perform in a conversational manner.
  • You want to create a personal incoming webhook for notifications. The “normal” incoming webhooks are only available within teams.
  • You want to create a chat relay application. For example, a customer could talk to an employee via a webchat, and the employee could receive messages and reply to them in Teams. This approach also offers us the option to have conversations within Teams while the users remain anonymous to each other. Both of them are talking to the bot, which just relays the messages between the users. This can be useful in feedback and support scenarios if users are afraid to bring up some topics with their name, or we don’t want users to contact individual support team members directly.

Messaging extensions

Behind the scenes, messaging extensions work in a very similar way to bots. There is a background service that is triggered by Teams. Then it does something and then sends a response back to Teams if appropriate. However, bots and messaging extensions are triggered in a very different manner.

You can trigger messaging extensions in the following ways:

  • By @mentioning the extension app in the command/search box at the top.
  • By @mentioning the extension app in the compose message box.
  • Via the “more actions” menu that opens when you click on the three dots on the top-right corner of an existing message (supported by all the different types of chats).
  • By selecting the app icon below the compose box (possibly behind the three dots).
  • When someone posts a URL address from a specific website to the chat. (not included in the picture below)

When a messaging extension is triggered, it can (but doesn’t necessarily need to) open a popup (a task module – more about this later). You can use the task module to collect additional information from the user before sending the data to the background service for processing. In the example above, clicking on Add a To-Do would open a popup first where the user would then specify the title and dates for the task (you will see a picture of this in the “task modules” section).

When the messaging extension background service sends a reply back to Teams, it is possible to display a popup again (e.g., saying “Success!”). Or include some specific text or an adaptive card in the compose box where the user is typing a message.

How the messaging extension should work can be quite different depending on which extension point you are going to use. I recommend you try out some of the existing messaging extensions that are available out-of-the-box. See what their user experience is like to get some ideas for your solution.

Messaging extensions are good when:

  • You simply want to trigger a background process without implementing an extensive user interface.
  • Triggering the process feels the most natural from one of the possible locations: the command/search box, the message compose box, or an existing message.
  • You want to trigger a process when someone posts a link from a specific website to the chat.

Webhooks & connectors

If you are just looking for a simple way of integrating an existing external system to Teams, webhooks can offer you a very quick and easy solution for that. There are three different types of webhooks:

  • Outgoing webhooks (for sending a message from Teams to an external system
  • Incoming webhooks (for sending a message from an external system to Teams)
  • Connectors (productized/packaged webhooks by you, Microsoft or third parties)

Outgoing webhooks

Outgoing webhooks allow you to send messages to external systems from Teams. They are used in a very similar way to bots: you @mention them on a chat or channel, and then type your message. The difference is that when you send the message, it will go directly to the external system or service (e.g., your HR system). There isn’t a custom-built bot background service in between. The external service then completes a task based on the message and can reply back to the user in Teams. This reply message can even be shown as an adaptive card if desired (more about adaptive cards later).

This means that you can offer a bot-like-experience to a user. Still, the user is merely talking to an existing system or, e.g. an Azure function.

It’s excellent if your external system already offers the URL where you can send the message. It knows how to process it, and send a message back in the format that you want. However, it is possible that the functionality does not yet exist. In those cases, it needs to be implemented. It is then down to the organization who offers this external system (and it’s application programming interfaces) to implement the functionality — if they are open to the idea.

Outgoing webhooks are good when:

  • An external system or service already exists and offers a URL where we can send the message (an API endpoint) for processing.
  • An external system or service with an API already exists, and we can create new API endpoints to it for our purposes.
  • We are creating a brand new system or service, and it makes more sense to create an API than a bot (other systems could also use the API).

If the external system does not offer the functionality in quite the format that you want, it is always possible to have a “middle layer” in between Teams and the external system. In that case, you would not be using a webhook but, for example, a bot from Teams. It would then talk to the external system while performing additional operations — e.g. message formatting — in between.

You can easily set up an outgoing webhook by clicking on “Manage team” — apps — Create an outgoing webhook.

Incoming webhooks

Incoming webhooks work in the opposite way to outgoing webhooks. They allow an external service to send information to Teams channels.

It is straightforward to add an incoming webhook to a channel. You add the Incoming webhook app to the team (or click on “Connectors” for the channel), and specify which channel you want to add it to, and what do you want to call it. You can optionally also upload an image as its icon. Upon creation, you will receive the URL address, where the external system needs to send their messages for them to appear on that team channel.

That’s all there is to it on Teams’ side. However, some code changes might need to be made to the external system for it to construct and send messages to that URL. Take a look at the Office 365 connector cards for the JSON schema for creating messages like in the picture below.



Incoming webhooks are useful when an external system already exists. We only need to add a small piece of code there to have it send messages to the channel URL.

Please note that incoming webhooks can’t be added to 1:1 or group chats. To allow an external service to send messages to chat, you need to create a bot. Check proactive messaging for more information.

Connectors

Connectors are productized incoming webhooks. They can be created by you, Microsoft or a third party. The webhook has been packaged into a Teams app and (optionally) made publicly available in AppSource. There is, e.g., a GitHub connector, which can send notifications from GitHub to a Teams channel. The Incoming Webhook app is also considered as a connector.

Connectors are good when:

  • There already exist a connector in AppSource for the external service you want to receive information from.
  • You want to package your incoming webhook into an app so that it is more easily discoverable and usable.

Additional things you can incorporate in your apps

In this post, I’ve already mentioned adaptive cards and task modules. Those are not stand-alone app types themselves, but they can be included as a part of your app for displaying information to the user in a certain way.

Adaptive cards

If you’ve read this blog post from the very beginning, you’ve already seen quite a few adaptive cards along the way. Adaptive cards offer a way to format the messages we want to display on chats and channels to the user. They can be used from bots, messaging extensions, webhooks — all the different kinds of apps that allow us to send messages to chats and channels (even via Microsoft Graph). They allow us to define the structure of the message: what info to show, in which order and in what format. It is also possible for us to include buttons and links in the messages that the user can click for further actions.

You can create card layouts by using the adaptive card designer. It will automatically generate the JSON code which you can then use in your app. You can also check if one of the already available card templates matches to your needs.

Adaptive cards are good when:

  • You want to show a chat or a channel message in a certain format
  • You want to offer the user buttons for quickly performing additional tasks

Task modules

Task modules are popups/modal windows you can open in Teams. We can open them by:

  • Clicking on buttons, links or other elements we’ve included in a tab.
  • Clicking on buttons or links on adaptive cards. These could have been sent to a chat or a channel conversation by a bot or a messaging extension.
  • By clicking on a Teams deep link. The link can be clicked by the user anywhere, even outside of teams (e.g. in an email, on an intranet site etc.) and it then takes the user to the task module view in Teams.

Task modules are good when:

  • You want to display or collect information to/from the user via that kind of a temporary popup/modal/dialog view.

Afterword

I hope that after reading this article, you’ve gained a better understanding of all the types of functionality we can bring into Teams. You should now know what the access points from where we can use the custom applications are. Feel free to share this post also with your friends, colleagues and customers! Let’s educate them on all of the possibilities. We won’t see a significant increase in Teams app development until people are more aware of what can be done.

If you’ve already gotten to create Teams applications for real customer scenarios, please comment below! I’d love to know more about other people’s customer cases. 🙂

Did you enjoy this content and would like to consume more? Feel free to subscribe to my Insider (news)letter and follow me on your favourite social media platforms (Twitter, YouTube, LinkedIn, Github). I share different types of content on each of the platforms.

Thank you for reading, it is always appreciated, and until next time!

Laura



3 thoughts on “How we can extend Microsoft Teams with custom apps — the non-technical explanation”

  • Hi Laura,

    It was a very nice and detailed explanation for a beginner to start with Teams App and I recently was surfing and studying about Teams App and was checking on how can I trigger a Teams App after a Meeting Ends and give some kind of a Popup to Take A feedback on the Meeting.

    Can you guide me on what combination on apps I would need to develop that kind of app for teams.

  • Hi Laura,

    My organisation has asked me to create a MOM tracker mechanism for the complete organisation. That means I need to track it function wise and datewise whenever the meeting happens. Can you please suggest the effective way of doing it through task on team??

    • Hi Sandeep,

      If I were you, I’d ask a bit more specifications from the organization to get a better idea/more detailed description of how they want the feature to work exactly and what data they want to collect. Those things can have a major impact on what kind of a solution architecture you need to design. In addition to considering what Teams apps you could take advantage of, also look into what endpoints Microsoft Graph offers for implementing such functionality. Be prepared that you might not be able to offer them a solution that matches their requirements exactly, but instead craft a proposal for the next best option.

      Laura

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.