Hello, I hope you enjoyed the previous two tutorials on how to get started with Microsoft Teams development, (Developing Tabs on Teams and Bots
This is the third one of the beginner series, and this time, I will walk you through how to invoke an action from a message.
There are many different paths to learn how to build Teams apps, and this tutorial uses a bare-minimum code and minimal toolsets. Also, this tutorial is independent of the hosting environment, so I am not starting the process with the Azure setup, and basically, this should run on any environment, as long as you can run a browser.
In this tutorial, I am introducing another Teams platform feature, Messaging Extensions. This feature comes with two different types, Action and Search, and it depends on how it interact with the UI elements and flows.
In this tutorial, I am showing how to built an Action command.
Teams features: Messaging Extensions - Action Command
Action commands allow you to present your users with a modal popup to collect or display information. When they submit the form, your web service can respond by inserting a message into the conversation directly, or by inserting a message into the compose message area and allowing the user to submit the message.
Building a Morse Code message action
The app we are going to build invokes an action from a user message, extract the text, and convert it to a Morse code!
How the app works is:
- A user hovers a message to open the message menu, and choose the Morse Bot from the menu
- When the user action is trigered, a payload is sent to your messaging endpoint (/api/messages)
- This invokes the fetchTask - the message text data is extracted
- A popup dialog is displayed. The user can edit the text content if they want, then submit
- The app translate the text into a morde code, and display the content as a reply
- The user can send the result to the client
This is how the result would look like:
📓 Prerequisites
To be able to install apps to Teams, your organization's admin needs to grant permission.
Otherwise, you can sign up for Microsoft 365 developer program, a free, renewable subscription that comes with a developer tenant sandbox and sample data pack, like mock user data!
- Permission to develop on Teams or developer tenant (Sign up for M365 developer program!)
- App Studio - look for the app from the Apps menu in Teams client and install to your workspace
- Experience with Node.js and basic understanding of Express.js
👾 Technology to be used in this tutorial
- Node.js
- Microsoft Bot Framework
- Adaptive Cards for building some UI snippets
Building an action
🎏 Grabbing the code sample
In this tutorial, I am using the 3rd party tool, Glitch to host and run this project and the rest of the tutorial series. For a little more details what Glitch is and why I am using it, please refer my previous tutorial!
First, let's just click this Glitch link to remix the project. Remixing is like the forking a repo on GitHub, so it generates a copy of the project for you, so you can modify the code in the way you want without messing with the original 🙌
Once you get your own project repo, it serves up the app automatically and you get your own web server URL. You will need the URL when you are setting up an app with App Studio later.
⚙️ App Configuration: Creating App Manifest with App Studio
The basic idea of App Package for Teams, please refer to the previous tutorial.
🎛 Using App Studio
Open App Studio app in Teams client.
In App Studio, click the Manifest Editor tab from the top, then select Create a new app and fill out all the required fields including the Bot names, descriptions, etc.
🔖 Configuring a Messaging Extension
From the left menu, select Capabilities > Massaging Extensions. Go ahead and click the Setup button to set up.
Give your app a name.
🔐 App credentials
Copy the ID next to your bot name (something looks like 2cd53e8a-e698-4exx-...
) and paste it as an environment variable in your .env file, which is supposed to be a hidden file (Rename the .env-sample
to .env
).
Under App Passwords, generate a new password, and copy it. Then paste it in your .env file.
These credentials are used to initialize your bot adapter. (See index.js).
(Step 3 in the screen image above will be explained at the next step.)
🎬 Configuring an Action
At Messaging Endpoint, enter your web server URL, like, https://[your project].glitch.me/api/messages
if you have remixed the sample repo.
Scroll to Command and click "Add".
In the dialog box -
- Select "Allow users to trigger actions in external service..."
- Select "Fetch a dynamic set of parameters from your bot"
- Fill out the command ID and title text. Click "Massage" (Unselect other checkboxes if they are pre-selected). Leave the rest blank, then save.
📦 Installing the app manifest package
Go to Finish > Test and distribute.
If you get any errors, go fix it, otherwise, click Install your client.
You can also download the zip file that contains manifest.json
, and two icon images to install later or distribute.
As long as you remixed the code sample, the bot should work already. But let me quickly explain how it is coded before trying the bot.
🤖 Microsoft Bot Framework
The Microsoft Bot Framework is an open source SDK that allows you to build intelligent, enterprise-grade bots.
This SDK is a powerful platform that not only for Teams, but also designed to work for wide types of chat bots, including web & mobile chat, Skype, Facebook, Amazon Alexa, Slack, Twilio, and more!
🔧 Initiating the bot service
First, there are two JS files in the Glitch code sample repo, index.js and bots.js.
I am using Express to set up an HTTP server and routing HTTP requests. And the way to initiate the service is the same as the previous Bots tutorial, but this is the recap of the initialization, and creating a bot adapter:
// Import bot services
const { BotFrameworkAdapter } = require('botbuilder');
// Bot's main dialog
const { ReverseBot } = require('./bot');
// App credentials from .env
const adapter = new BotFrameworkAdapter({
appId: process.env.MicrosoftAppId,
appPassword: process.env.MicrosoftAppPassword
});
// Create the main dialog
const myBot = new MorseBot();
Note: In this example, I am using botbuilder version 4.10.0. If your code doesn't work as expected, check the version you are using!
🦉 Forwarding requests to the bot logic
Use Express to handle the routing to listen for incoming requests:
app.post('/api/messages', (req, res) => {
adapter.processActivity(req, res, async context => {
await myBot.run(context);
});
});
You have set up the URL in App Studio in the previous step. The /api/messages
is your application’s endpoint URL to respond to client requests.
🙋♀️ Handling the request
Once a request is received at the endpoint and forwarded to the bot logic, your app receive the context of the request, then create a custom reply in bots.js.
See the TeamsActivityHandler
is extended to create an appropriate handler for the request:
class MorseBot extends TeamsActivityHandler {
// Triggers when the message action is invoked by a user
handleTeamsMessagingExtensionFetchTask(context, action) {
/*
We're going to create an adaptive card UI (modal dialog) here.
In the dialog, the user confirms what text to be encoded to Morse code.
*/
}
// Triggers when the dialog box is submitted from the FetchTask
handleTeamsMessagingExtensionSubmitAction(context, action) {
// display the result
}
The TeamsActivityHandler
is a Teams specific class that handles messages- such as messages events and sending replies.
In this scenario, when a user triggers an action from a message, handleTeamsMessagingExtensionFetchTask
gets invoked, so your bot received the information about the message when the action was made from.
You can learn more about it at Create and send the task module on Teams documentation
📇 Displaying a modal dialog with Adaptive Cards
The dialog UI is created with Adaptive Cards, which is a Microsoft open source to build snippets of UI in JSON, and can be used in Microsoft Teams, Outlook Actionable Messages, Cortana Skills, etc.
When handleTeamsMessagingExtensionFetchTask
is invoked, get the message content text, and display it in a Adaptive card as a modal dialog, as the response.
To defining an Adaptive card and the content:
const card = {
type: 'AdaptiveCard',
version: '1.0'
};
card.body = [
{ type: 'TextBlock', text: 'The message to be encoded to Morse code:', weight: 'bolder'},
{ id: 'editedMessage', type: 'Input.Text', value: content },
];
card.actions = [{
data: { submitLocation: 'messagingExtensionFetchTask'},
title: 'Encode to Morse!',
type: 'Action.Submit'
}];
const adaptiveCard = CardFactory.adaptiveCard(card);
return {
task: {
type: 'continue',
value: {
card: adaptiveCard
}
}
I am displaying the extracted message text in the type: 'Input.Text'
so that the user can edit the text to be Morse-coded!
To view the full code, please see the bot.js file in the code sample in Glitch.
📮 Handling the user submission
Once a user submits the task module, handleTeamsMessagingExtensionSubmitAction
gets triggered and your web service will receive an object with the command id and parameter values set.
In this sample code, it just checks if the custom data, editedMessage
is there. And if so, grab the value (should be a string) and convert it and display the content to be composed as a new message.
async handleTeamsMessagingExtensionSubmitAction(context, action) {
if(action.data.editedMessage) {
const text = action.data.editedMessage;
const morseText = await encodeToMorse(text);
return {
composeExtension: {
type: 'result',
attachmentLayout: 'list',
attachments: [
// The message UI component here
// Please refer to the sample code on Glitch to see the entire code
]
}
}
}
}
In the code sample shown in the bots.js, I am using the simple UI "card" called Thumbnail Card that comes with Bot Framework to compose the result message, but you can use Adaptive Card too!
🤖💬 Trying your Message Action
Now, let's try the action! Go to the Teams client, and click one of the text messages (not in rich format or image).
If everything works as expected, you should be able to convert any text messages into a Morse code!
I hope you get some good ideas about what you can do with Microsoft Teams platform with this tutorial, I hope you find better use cases than this and create something amazing!
The next tutorial will walk you through how to build another type of Messaging Extension, which is a search command. See you next time 👋