How To Create Action Based Messaging Extension As Teams App

Overview of Messaging Extension

One of the Microsoft Teams App capabilities is to create Messaging extensions that allow us to customize and extend Teams client. The messaging extension can search or initiate actions and allows us to show/write our logic through buttons and forms in Teams client. We can initiate a Messaging extension from composing message area, the command box, or in the context of a message. It will allow us to send back the results of the user input or our processing of data back in form of a formatted card which will be embedded in the message compose area. Users can then choose to modify this composed message and choose to send it to the conversation.

Below are some screenshots that will help you understand from which all places the Messaging extensions can be invoked

1. From the Search box on top

How to create Action based Messaging Extension as Teams App

2. From Message compose box

How to create Action based Messaging Extension as Teams App

3. From the context of Message, click on the context menu and click on more Actions.

How to create Action based Messaging Extension as Teams App

There are 3 types of Messaging extensions namely Action command, Search command, and link unfurling which we can create, you can read about it at this link

Today we are going to create our first Messaging extension of the action command, So let us get started.

Step 1 - Create Azure Bot

In this step, we are going to create Azure Bot because Messaging extension is dependent on the Bot framework to read the message/conversation context send results back in Messagebox.

From this step, we would have noted down App ID and App Secret to be used in the next steps.

Go to portal.azure.com

Click on Create resource

Search for 'Azure Bot' and click on create

How to create Action based Messaging Extension as Teams App

Provide below inputs

How to create Action based Messaging Extension as Teams App

Click on Review + Create

It will do validation and once validation passed, we will see Create button, click on it.

Once completed, we should see the below screen. Click on Go to resource

How to create Action based Messaging Extension as Teams App

Next, we would enable the Bot Teams Channel.

How to create Action based Messaging Extension as Teams App

Click on Save to enable Teams Channel.

How to create Action based Messaging Extension as Teams App

The next step would be App ID and Secret which we need. Click on Configuration on the left blade.

We would have to note down this App ID from here and Click on Manage as displayed in the below screenshot.

How to create Action based Messaging Extension as Teams App

It will take us to the below screen. Click on Certificate and secrets-> New client Secret and enter description and choose Expires. Click on Add button

How to create Action based Messaging Extension as Teams App

It will create a new Secret which we will have to copy now itself because this would be only displayed once.

How to create Action based Messaging Extension as Teams App

Keep this App ID and secret handy, we will use this in the next steps.

Step 2 - Create Teams App of type Messaging extension

We are going to use the Teams App Yoeman generator to scaffold our Teams App. You can refer to this link for setting up yo teams generator.

Open command prompt, create a new folder of your choice in your drive where you wish to create the solution. Run the below command.

yo teams

We would be asked with series of questions, please refer to the below screenshot for options you have to choose.

  • As we are going to create an Action command, make sure you choose 'Action based messaging extension'
  • Use Microsoft App ID as from the previous step.

How to create Action based Messaging Extension as Teams App

Once the above process is completed, we should see the below output.

How to create Action based Messaging Extension as Teams App

Use 'code .' to open the solution in Visual Studio Code.

Step 3 - Prepare Local Development environment to Test App

We would see the .env file on the root of the solution. If we would have added the correct App ID while running yo teams, we would see that APP id here

Paste the App Secret in the MICROSOFT_APP_PASSWORD variable.

How to create Action based Messaging Extension as Teams App

Please note that once you publish this App to Azure, we have to make sure that the App Service configuration has these values set up with exact same variable names.

Step 4 - Test the App

Before we go into details of project structure and understand how all the files etc are related. Let us quickly run it

Go to solution root path in command prompt and run below command

gulp ngrok-serve

It would take some time to compile and run the solution

How to create Action based Messaging Extension as Teams App

Once you see the above message the solution has run successfully.

Next, you would have to update the ngrok URL in the Azure AD app registration

How to create Action based Messaging Extension as Teams App

yo teams would have generated a teams app package for us in the below folder path...

\Code\Teams\messaging-ext\package\messagingext.zip

Step 5 - Test the App in Teams

Go to teams and click on Apps on the left panel and then select upload a custom app(this button will only be visible if sideloading is enabled by Teams Administrator)

How to create Action based Messaging Extension as Teams App

Click on Upload a custom app and select ‘Upload for me and my teams’,

Select the zip package at ‘D:\SP\samples\teamsapps\teams-graphtoolkit\package\teamsgraphtoolkit.zip’

Note - This zip file will be updated everything you run gulp ngrok-serve, so you have to make sure you upload the latest zip package whenever you have a new ngrok URL and also update the same in App Registration in the Azure portal.

Click on Add

How to create Action based Messaging Extension as Teams App

Once installed successfully, you will see below the output of the Teams Tab

How to create Action based Messaging Extension as Teams App

To try Extension, go to any chat conversation with any user or in the Teams channel.

How to create Action based Messaging Extension as Teams App

As we have chosen yes to question while creating the solution "[extension] Do you need configuration or authorization when collecting the information? Yes"

It will allow us to get some configuration value from users to handle our logic, This would be a nice place to also authorize users with an external system.

How to create Action based Messaging Extension as Teams App

Once you click on setup, it will open another pop-up window to collect configuration input. In this is the case it is just a Checkbox to On and Off.

How to create Action based Messaging Extension as Teams App

Once you click ok, we will see the actual action command window, enter email address and click on Ok

How to create Action based Messaging Extension as Teams App

Enter any email address and click ok then it will send show below output in the message compose area.

If you see it has the same email is used to generate format message...

How to create Action based Messaging Extension as Teams App

So that's it, we have our Hello World Messaging for you...

Understanding the Project Structure and files

For real-world scenarios, we won't be using the default project structure and hence we should understand how this works.

First, let us how the Input form which asks for Email addresses comes from.

src\client\messagingExtMessageExtension\MessagingExtMessageExtensionAction.tsx

How to create Action based Messaging Extension as Teams App

I won't go into details of how to build UI and use of state etc to read values from user inputs etc. But it would be typical of using React framework concepts which we will have to use. This particular component is a functional component and not a class component so it is using a hook etc.

The important line here to understand is highlighted above, when the user clicks on the Ok button, it is calling the below method which we have to remember when we have to pass the data to Task Submission event on the server-side supported targeted action's supported which has a method to handle this event.

microsoftTeams.tasks.submitTask({
 email
 })

In the File - src\server\messagingExtMessageExtension\MessagingExtMessageExtension.ts 

We have the callBack method onSubmitAction which would be called when from client site microsoftTeams.tasks.submitTask method is called.

We will receive the data from the client site in the value object and the JSON object can be accessed by value.data class and then our object's attributes.

To access the email we would be using syntax 'value.data.email' as we are only passing email in JSON object from the client-side.

If you also notice, we are sending the MessagingExtensionResult  type which is required to be sent, and in this, we can send cards,

How to create Action based Messaging Extension as Teams App

By looking at the definition of MessagingExtensionResult, we can see that we have different possible values and combinations of what we can send back as result.

In the above case, the type is the result and the layout is a list but we are sending an array of attachments as cards. And the adaptive card is built by showing Email as Textblock and one random image :)

export interface MessagingExtensionResult {
    /**
     * @member {AttachmentLayout} [attachmentLayout] Hint for how to deal with
     * multiple attachments. Possible values include: 'list', 'grid'
     */
    attachmentLayout ? : AttachmentLayout;
    /**
     * @member {MessagingExtensionResultType} [type] The type of the result. Possible values include:
     * 'result', 'auth', 'config', 'message', 'botMessagePreview'
     */
    type ? : MessagingExtensionResultType;
    /**
     * @member {MessagingExtensionAttachment[]} [attachments] (Only when type is
     * result) Attachments
     */
    attachments ? : MessagingExtensionAttachment[];
    /**
     * @member {MessagingExtensionSuggestedAction} [suggestedActions]
     */
    suggestedActions ? : MessagingExtensionSuggestedAction;
    /**
     * @member {string} [text] (Only when type is message) Text
     */
    text ? : string;
    /**
     * @member {Activity} [activityPreview] (Only when type is botMessagePreview)
     * Message activity to preview
     */
    activityPreview ? : Activity;
}

So it is obvious now, that depending on our requirement we have to study above class and try the different combination on type of output we need

If we take a step back and have to understand how the MessagingExtMessageExtensionAction component was loaded when the user clicks the extension command. This is interesting and helps to also see how the configuration task module was invoked before the actual input form was loaded.

In the same file, src\server\messagingExtMessageExtension\MessagingExtMessageExtension.ts 

We have a method onFetchTask that takes care of controlling what to load. This method would be called from the server-side and we can either send an adaptive card or embedded web view...so in this case, we are displaying our action/config HTML page depending on if the configuration window has loaded or not.

If the state property is not empty it means the config.html has been loaded and the user has added configuration values, so next time load the action.html file

How to create Action based Messaging Extension as Teams App

Not it is again obvious that as this is server-side code it won't able to load the React components directly so it is actually loading pure HTML pages which are indirectly loaded our React components. This is not just true for Messaging extensions but if you are building any React-based application there would be always the HTML page that would be rendering react component using ReactDom.render method.

Let us see the code for action.html and config.html which is indirectly loading our React components.

These HTML files would be in the public folder, where we can add any public-facing HTML files.

How to create Action based Messaging Extension as Teams App

I hope this article will help you understand the messaging extension concept and also provide you with step-by-step guidance on how to create a basic messaging extension from your side...!!

Happy coding...!!!!