This article demonstrates how to create a Spring Boot web app in Java that replicates the functionality of the “Universal Bots” sample app on GitHub.
In the first article of this three-part series, we discussed how to build a messaging extension for search. In this article, we’ll learn how to make a link unfurling messaging extension.
Exploring Link Unfurling
Link unfurling enables you to invoke a method in your app whenever the user pastes a link with a particular domain to the Microsoft Teams message compose area. This action is helpful in many situations. For instance, you can parse the URL and provide the user with additional buttons so the user can perform a task without visiting the website and reading its contents. This ability accelerates many tasks your users perform within Microsoft Teams while minimizing distractions.
Here’s an example of automatic link unfurling for azure.microsoft.com:
After the user pastes the link, Microsoft Teams automatically displays the most relevant information.
This article will explore how to build the link unfurling using Java and Spring MVC. Adding link unfurling is similar to building messaging extensions: we first register and implement the bot, then prepare the application manifest. We add at least one command for the messaging extension (otherwise, the manifest won’t be installable). Then, we configure the message handlers to provide the list of domains that trigger link unfurling.
As before, we will use a local environment with ngrok. The application’s complete source code is available on GitHub.
Creating a Project
We can use the Yeoman generator to create the project:
yo botbuilder-java
We configure the bot as follows:
- Name:
link-unfurling
- Package name:
db.teams.linkunfurling
- Template: Empty Bot
This command creates the new project with an EmptyBot
class (src/main/java/EmptyBot.java):
public class EmptyBot extends ActivityHandler { }
Let’s rename the file and the class name to LinkUnfurling
, then modify the base class to TeamsActivityHandler
:
public class LinkUnfurling extends TeamsActivityHandler { }
To make this work, we also need to modify the getBot
method in Application.java:
@Bean
public Bot getBot() {
return new LinkUnfurling();
}
Implementing the Bot
We now need to register the bot. It’s essential to implement the bot before creating the manifest. Otherwise, the link unfurling might cache the results. If you change anything in the method handling the link unfurling invoke, you often need to re-install the Teams application.
We proceed the same as in the previous article to register the bot. So, let’s register the new bot link-unfurling-bot and configure its endpoint to either a local ngrok forwarding URL or the actual URL if you decide to deploy the bot to the Internet — for example, using Azure Spring Cloud.
Then, generate the bot password and paste it and the bot ID to application.properties
:
Using the Search Command
We need to have at least one command for the messaging extension to make the manifest installable. So, we use the previously developed echo-like search command handler. The only difference here is that we have the hard-coded hero card text ("Link unfurling
"):
@Override
protected CompletableFuture<MessagingExtensionResponse> onTeamsMessagingExtensionQuery(
TurnContext turnContext,
MessagingExtensionQuery query
) {
String queryText = GetQueryText(query);
HeroCard card = new HeroCard();
card.setTitle("Echo");
card.setSubtitle(queryText);
card.setText("Link unfurling");
MessagingExtensionAttachment attachment = new MessagingExtensionAttachment();
attachment.setContent(card);
attachment.setContentType(HeroCard.CONTENTTYPE);
attachment.setPreview(card.toAttachment());
MessagingExtensionResult result = new MessagingExtensionResult();
result.setAttachmentLayout("list");
result.setType("result");
result.setAttachment(attachment);
return CompletableFuture.completedFuture(new MessagingExtensionResponse(result));
}
GetQueryText
is the helper method. It extracts the search query text from the parameters it received from the messaging extension. It works as the previous article explains.
The above code generates results like the screenshot below:
Implementing Link Unfurling
When the user pastes a link containing a domain registered under the message handlers, the Bot Framework invokes the onTeamsAppBasedLinkQuery
method. To implement link unfurling, all you need to do is to override the onTeamsAppBasedLinkQuery
method in your Bot’s class. Here’s the example for the LinkUnfurling
class:
public class LinkUnfurling extends TeamsActivityHandler {
@Override
protected CompletableFuture<MessagingExtensionResponse> onTeamsAppBasedLinkQuery(
TurnContext turnContext,
AppBasedLinkQuery query
) { }
}
As shown above, the Framework provides you with two objects: TurnContext
and AppBasedLinkQuery
. TurnContext
supplies the information needed to process the incoming request. Specifically, you can use it to send responses back to the user. The AppBasedLinkQuery
class represents the request body for the app-based link query. It contains two properties:
Url
, which contains the URL pasted by the user State
, which contains the magic code for OAuth flow
Here, we’ll use only the first property. More specifically, we first create the ThumbnailCard
, and set its title to CodeProject and the text to the URL that the user pasted. Additionally, we set the image to the CodeProject logo:
ThumbnailCard card = new ThumbnailCard();
card.setTitle("CodeProject");
card.setText(query.getUrl());
final String logoLink =
"https://codeproject.freetls.fastly.net/App_Themes/CodeProject/Img/logo250x135.gif";
CardImage cardImage = new CardImage(logoLink);
card.setImages(Collections.singletonList(cardImage));
Then, we create an attachment (in the same way as for the messaging extension):
MessagingExtensionAttachment attachments = new MessagingExtensionAttachment();
attachments.setContentType(HeroCard.CONTENTTYPE);
attachments.setContent(card);
We attach the attachment to the MessagingExtensionResult
class instance as follows:
MessagingExtensionResult result = new MessagingExtensionResult();
result.setAttachmentLayout("list");
result.setType("result");
result.setAttachments(Collections.singletonList(attachments));
Finally, we generate and return the response:
return CompletableFuture.completedFuture(new MessagingExtensionResponse(result));
Here’s the complete method:
@Override
protected CompletableFuture<MessagingExtensionResponse> onTeamsAppBasedLinkQuery(
TurnContext turnContext,
AppBasedLinkQuery query
) {
ThumbnailCard card = new ThumbnailCard();
card.setTitle("CodeProject");
card.setText(query.getUrl());
final String logoLink =
"https://codeproject.freetls.fastly.net/App_Themes/CodeProject/Img/logo250x135.gif";
CardImage cardImage = new CardImage(logoLink);
card.setImages(Collections.singletonList(cardImage));
MessagingExtensionAttachment attachments = new MessagingExtensionAttachment();
attachments.setContentType(HeroCard.CONTENTTYPE);
attachments.setContent(card);
MessagingExtensionResult result = new MessagingExtensionResult();
result.setAttachmentLayout("list");
result.setType("result");
result.setAttachments(Collections.singletonList(attachments));
return CompletableFuture.completedFuture(new MessagingExtensionResponse(result));
}
Creating the Manifest
To test our link unfurling app, we need to create the manifest and install the Microsoft Teams app. We proceed precisely the same as the previous article to make the manifest. We just need to enable link unfurling by adding message handlers. Message Handlers is the last configuration option you see in the Messaging Extensions screen. You can configure the domains as explained in Microsoft’s documents. Here, we add only one domain: www.codeproject.com.
For your convenience, I uploaded the final manifest and the companion code on GitHub. You’ll still need to update line 28 with your bot identifier. Then, zip the manifest.json along with the attached icons. Afterward, use Import an existing app in App Studio or the Developer Portal.
Putting Everything Together
Now build (mvn clean install
) and start your web service (java -jar target/link-unfurling-1.0.0-SNAPSHOT.jar
). Then, open Microsoft Teams, go to the chat window and paste any link from codeproject.com.
For example:
https://www.codeproject.com/Articles/5299822/Java-on-Azure-Adding-Containers
You’ll see the following result:
Next Steps
Here, we learned how to use Java and Spring MVC to implement link unfurling in Microsoft Teams apps. We started by creating the Empty Bot project template, then added a handler for link unfurling. Finally, we prepared the app manifest.
Creating the link unfurling is a two-step process. You first build the messaging extension with at least one command, then specify the list of domains. When a user pastes a link containing one of those domains, the Bot Framework invokes the onTeamsAppBasedLinkQuery
method of your bot’s class. In this method, you can prepare the response in the form of a card.
Continue to the third and final part of this three-part series, where we’ll explore building webhooks and notification connectors.
To learn how you can build, migrate and scale Java applications on Azure using Azure services, check out Get started with Java on Azure.