๐ Link unfurling
Link unfurling lets your app respond when users paste URLs into Teams. When a URL from your registered domain is pasted, your app receives the URL and can return a card with additional information or actions. This works like a search command where the URL acts as the search term.
Users can use link unfurling even before they discover or install your app in Teams. This is called Zero install link unfurling.
In this scenario, your app will receive a message.ext.anon-query-link
activity instead of the usual message.ext.query-link
.
Setting up your Teams app manifestโ
"composeExtensions": [
{
"botId": "${{BOT_ID}}",
"messageHandlers": [
{
"type": "link",
"value": {
"domains": [
"www.test.com"
]
}
}
]
}
]
When a user pastes a URL from your registered domain (like www.test.com
) into the Teams compose box, your app will receive a notification. Your app can then respond by returning an adaptive card that displays a preview of the linked content. This preview card appears before the user sends their message in the compose box, allowing them to see how the link will be displayed to others.
Handle link unfurlingโ
Handle link unfurling when a URL from your registered domain is submited into the Teams compose box.
using Microsoft.Teams.Api.Activities.Invokes.MessageExtensions;
using Microsoft.Teams.Api.MessageExtensions;
using Microsoft.Teams.Apps.Annotations;
//...
[MessageExtension.QueryLink]
public Response OnMessageExtensionQueryLink(
[Context] QueryLinkActivity activity,
[Context] IContext.Client client,
[Context] ILogger log)
{
log.Info("[MESSAGE_EXT_QUERY_LINK] Link unfurling received");
var url = activity.Value?.Url;
log.Info($"[MESSAGE_EXT_QUERY_LINK] URL: {url}");
if (string.IsNullOrEmpty(url))
{
return CreateErrorResponse("No URL provided");
}
return CreateLinkUnfurlResponse(url, log);
}
CreateLinkUnfurlResponse()
method
using Microsoft.Teams.Api;
using Microsoft.Teams.Api.MessageExtensions;
using Microsoft.Teams.Cards;
//...
private static Response CreateLinkUnfurlResponse(string url, ILogger log)
{
var card = new AdaptiveCard
{
Schema = "http://adaptivecards.io/schemas/adaptive-card.json",
Body = new List<CardElement>
{
new TextBlock("Link Preview")
{
Weight = TextWeight.Bolder,
Size = TextSize.Medium
},
new TextBlock($"URL: {url}")
{
IsSubtle = true,
Wrap = true
},
new TextBlock("This is a preview of the linked content generated by the message extension.")
{
Wrap = true,
Size = TextSize.Small
}
}
};
var attachment = new Microsoft.Teams.Api.MessageExtensions.Attachment
{
ContentType = new ContentType("application/vnd.microsoft.card.adaptive"),
Content = card
};
return new Response
{
ComposeExtension = new Result
{
Type = ResultType.Result,
AttachmentLayout = Layout.List,
Attachments = new List<Microsoft.Teams.Api.MessageExtensions.Attachment> { attachment }
}
};
}
// Helper method to create error responses
private static Response CreateErrorResponse(string message)
{
return new Response
{
ComposeExtension = new Result
{
Type = ResultType.Message,
Text = message
}
};
}
The link unfurling response includes both a full adaptive card and a preview card. The preview card appears in the compose box when a user pastes a URL:
The user can expand the preview card by clicking on the expand button on the top right.
The user can then choose to send entire the preview or the full adaptive card as a message.