Introduction
Messaging extensions are a powerful way for users to engage with your app from Microsoft Teams. With this capability, users can query or post information to and from your service and post that information, in the form of cards, right into a message.
Messaging extensions appear along the bottom of the compose box. A few are built in, such as Emoji, Giphy, and Sticker. Choose the More Options (⋯) button to see other messaging extensions, including those you add from the app gallery or upload yourself.

How would you use messaging extensions? Here are a few possibilities:
- Work items and bugs
- Customer support tickets
- Usage charts and reports
- Images and media content
- Sales opportunities and leads
Types of Message Extension
- Search based messaging extensions
- Action-based messaging extensions
Create custom Microsoft Teams messaging extensions to get book information and share via chat
Output

Cards
A card is a user-interface container for short or related pieces of information. Cards can have multiple properties and attachments. Cards can include buttons which can trigger Card actions

You can find additional information on how to use cards here
Add a messaging extension to your app
A messaging extension is a cloud-hosted service that listens to user requests and responds with structured data, such as a card. You integrate your service with Microsoft Teams via Bot Framework Activity objects.
In this example, I am using ngrok to share our local host to publicly
Ngrok creates a secure tunnel to expose local networked services (like a web server) at a publicly-accessible URL. Simply put, we can run a local Node.js app on our computer at localhost:8080 and have someone across the world and outside our network access this local web server at a URL such as http://d594cf96.ngrok.io
Important : If you plan to use ngrok at work, you should also have a talk about what ngrok is with your system administrator or whomever is responsible for network security. Punching a hole in a corporate firewall or NAT can be disastrous, especially if malicious users of your publicly-accessible app can manipulate your file system or access other computers on your network.
In this post I am showing how to create Messaging extension using nodejs Step by step
Step 1: Create new Nodejs Project
First, open a command prompt and create a new directory for our code, then navigate into it:
md MessagingExtensions
cd MessagingExtensions
Create a new Node.js project by creating our package.json file with the following command:
npm init

Enter your project details and then install ngrok
npm install ngrok
then open the project using Visual studio code, type below command
code ..
Create a file called getBooks.js and paste the following code:
const ngrok = require('ngrok');
var request = require('request');
var util = require("util");
var restify = require('restify');
var builder = require('botbuilder');
var teams = require('botbuilder-teams');
var connector = new teams.TeamsChatConnector({
appId: "<update the bot ID>",
appPassword: "<update the bot ID password>"
});
const port = 8080;
var server = restify.createServer();
server.listen(port, function() {
console.log(`Node.js server listening on ${port}`);
ngrok.connect(port, function(err, url) {
console.log(`Node.js local server is publicly-accessible at ${url}`);
});
console.log('%s listening to %s', server.name, util.inspect(server.address()));
});
// this will reset and allow to receive from any tenants
connector.resetAllowedTenants();
var bot = new builder.UniversalBot(connector);
server.post('/api/composeExtension', connector.listen());
server.post('/api/messages', connector.listen());
server.post('/', connector.listen());
var composeExtensionHandler = function(event, query, callback) {
var attachments = [];
var url = "https://www.googleapis.com/books/v1/volumes?q=" + query.parameters[0].value + "&limit=100&offset=0";
if (query.parameters[0].value == undefined | query.parameters[0].value == '') {
url = "https://www.googleapis.com/books/v1/volumes?q=ISBN:9780789748591&limit=10";
}
request(url, {
json: true
}, (err, res, body) => {
if (err) {
return console.log(err);
}
var data = body;
for (var o of data.items) {
try {
console.log(o.volumeInfo.title);
var logo = {
alt: o.volumeInfo.title,
url: o.volumeInfo.imageLinks.thumbnail
};
var card = new builder.HeroCard()
.title("Title: " + o.volumeInfo.title)
.text("" + o.volumeInfo.description)
.subtitle("Publisher: " + o.volumeInfo.publisher)
.images([logo])
.buttons([{
type: "openUrl",
title: "View Image",
value: o.volumeInfo.imageLinks.thumbnail
}]);
attachments.push(card.toAttachment());
} catch (err) {
console.log(err);
}
};
var response = teams.ComposeExtensionResponse
.result('list')
.attachments(attachments)
.toResponse();
// Send the response to teams
callback(null, response, 200);
//}
});
};
connector.onQuery('searchCmd', composeExtensionHandler);
var composeInvoke = function(event) {
console.log(event);
};
connector.onInvoke('composeInvoke');
The code above is fairly straightforward, I am searching books and building as Hero card and sent to chat window by attachment object and I am using Google API to get books by ISBN number
Then install below headers to refer the objects
npm install restify
npm install botbuilder@3.13.1
npm install botbuilder-teams
Now we completed the get books messaging extension coding.
Step 2: Create manifest.json file using AppStudio
Go to https://teams.microsoft.com
Login with your office 365 credencials
go to apps and find App Studio, refer below picture
Note: if App Studio is not available, then install it.

Move to Manifest editor, and create new app

Update Appdetails and Messaging extensions under capabilities section
In Messaging extension –> Click Setup and provide bot name
Then get the bot ID and app password(generate new password) from messaging extension section

go to getBooks.js file to update AppID and Password refer below section
var connector = new teams.TeamsChatConnector({
appId: "d2052104-0d83-40ad-b7b4-19cf537a6c99",
appPassword: "123456@JnZSoaRQVzfWg@242323-333"
});
Then add Messaging endpoint URL, to get public URL with https we need ngrok
Step 3: Use ngrok to start listening on port 8080
Go to Command prompt and type below command to start the application
node getBooks.js

Open ngrok.com and login with your credentials
Then open new browser and access
http://localhost:4040/inspect/http
Then you can able to see the public url example
https://24af2b2f.ngrok.io/
Then go to AppStudio and update the Bot endpoint address, refer below image
https://24af2b2f.ngrok.io/api/messages

Then add command to search books

Click Test and distribute to test the app
It is open new window, click install and add the app to verify
Then Download the app package to test from your channel

Step 4: Install the app to your Team
Go to you team –> navigate to Manage Team
Then Click App tab and upload a custom app (select the downloaded zip file to upload)
Now it is available in our Teams

Then go to your channel and test it
Click dot’s … and see your message extension

Select your app and click to search books based on ISBN number

Select the Book and it will build Hero Card with title, publisher, image and description

manifest.json file FYR
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.5/MicrosoftTeams.schema.json",
"manifestVersion": "1.5",
"version": "1.0.0",
"id": "afc28e3f-0b57-4478-b368-92744c1f93cb",
"packageName": "jpower4.msteams.messagingextension",
"developer": {
"name": "Jenkins NS",
"websiteUrl": "https://github.com/jenkinsns",
"privacyUrl": "https://github.com/jenkinsns",
"termsOfUseUrl": "https://github.com/jenkinsns"
},
"icons": {
"color": "color.png",
"outline": "outline.png"
},
"name": {
"short": "Get Books App",
"full": "To get books using ISBN number"
},
"description": {
"short": "Messaging extension Teams App development",
"full": "Messaging extension Teams solution development"
},
"accentColor": "#FFFFFF",
"composeExtensions": [
{
"botId": "d2052104-0d83-40ad-b7b4-19cf537a6c99",
"canUpdateConfiguration": false,
"commands": [
{
"id": "searchCmd",
"type": "query",
"title": "Search",
"description": "Search for your Book",
"initialRun": true,
"fetchTask": false,
"context": [
"commandBox",
"compose",
"message"
],
"parameters": [
{
"name": "searchKeyword",
"title": "ISBN Number",
"description": "Enter your ISBN Number",
"inputType": "text"
}
]
}
]
}
],
"permissions": [
"identity",
"messageTeamMembers"
],
"validDomains": []
}
“Sharing is caring” #MicrosoftTeams #jpower4 #sharepoint