Skip to content
This repository was archived by the owner on Jan 5, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Teams;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Microsoft.BotBuilderSamples.Bots
Expand All @@ -26,15 +28,15 @@ protected override async Task<MessagingExtensionActionResponse> OnTeamsMessaging
case "shareMessage":
return ShareMessageCommand(turnContext, action);
default:
throw new NotImplementedException($"Invalid CommandId: {action.CommandId}");
return await Task.FromResult(new MessagingExtensionActionResponse());
}
}

private MessagingExtensionActionResponse CreateCardCommand(ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action)
{
// The user has chosen to create a card by choosing the 'Create Card' context menu command.
var createCardData = ((JObject)action.Data).ToObject<CreateCardData>();

var card = new HeroCard
{
Title = createCardData.Title,
Expand All @@ -49,7 +51,7 @@ private MessagingExtensionActionResponse CreateCardCommand(ITurnContext<IInvokeA
ContentType = HeroCard.ContentType,
Preview = card.ToAttachment(),
});

return new MessagingExtensionActionResponse
{
ComposeExtension = new MessagingExtensionResult
Expand All @@ -76,7 +78,7 @@ private MessagingExtensionActionResponse ShareMessageCommand(ITurnContext<IInvok
// exercise for the user.
heroCard.Subtitle = $"({action.MessagePayload.Attachments.Count} Attachments not included)";
}

// This Messaging Extension example allows the user to check a box to include an image with the
// shared message. This demonstrates sending custom parameters along with the message payload.
var includeImage = ((JObject)action.Data)["includeImage"]?.ToString();
Expand Down Expand Up @@ -115,5 +117,68 @@ private class CreateCardData

public string Text { get; set; }
}

protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync(ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
{
// we are handling two cases within try/catch block
//if the bot is installed it will create adaptive card attachment and show card with input fields
string memberName;
try
{
// Check if your app is installed by fetching member information.
var member = await TeamsInfo.GetMemberAsync(turnContext, turnContext.Activity.From.Id, cancellationToken);
memberName = member.Name;
}
catch (ErrorResponseException ex)
{
if (ex.Body.Error.Code == "BotNotInConversationRoster")
{
return new MessagingExtensionActionResponse
{
Task = new TaskModuleContinueResponse
{
Value = new TaskModuleTaskInfo
{
Card = GetAdaptiveCardAttachmentFromFile("justintimeinstallation.json"),
Height = 200,
Width = 400,
Title = "Adaptive Card - App Installation",
},
},
};
}
throw; // It's a different error.
}

return new MessagingExtensionActionResponse
{
Task = new TaskModuleContinueResponse
{
Value = new TaskModuleTaskInfo
{
Card = GetAdaptiveCardAttachmentFromFile("adaptiveCard.json"),
Height = 200,
Width = 400,
Title = $"Welcome {memberName}",
},
},
};
}


/// Returns adaptive card attachment which allows Just In Time installation of app.
private static Attachment GetAdaptiveCardAttachmentFromFile(string fileName)
{
//Read the card json and create attachment.
string[] paths = { ".", "Resources", fileName };
var adaptiveCardJson = File.ReadAllText(Path.Combine(paths));

var adaptiveCardAttachment = new Attachment()
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = JsonConvert.DeserializeObject(adaptiveCardJson),
};
return adaptiveCardAttachment;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ or

2) Selecting the **Share Message** command from the Message command list.

or

3) Selecting the **Fetch Roster** command from the Compose Box command list. You will presented with prompt for Just In Time installation if app is not already added to current team/chat.

## Deploy the bot to Azure

To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0",
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"text": "This app is installed in this conversation. You can now use it to do some great stuff!!",
"isSubtle": false,
"wrap": true
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Close"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"text": "Looks like you haven't used Action Messaging Extension app in this team/chat. Please click **Continue** to add this app.",
"wrap": true
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Continue",
"data": {
"msteams": {
"justInTimeInstall": true
}
}
}
],
"version": "1.0"
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@
"color": "icon-color.png"
},
"accentColor": "#FFFFFF",
"bots": [
{
"botId": "<<YOUR-MICROSOFT-APP-ID>>",
"needsChannelSelector": false,
"isNotificationOnly": false,
"scopes": [
"team",
"personal",
"groupchat"
]
}
],
"composeExtensions": [
{
"botId": "<<YOUR-MICROSOFT-APP-ID>>",
Expand Down Expand Up @@ -68,6 +80,14 @@
"inputType": "toggle"
}
]
},
{
"id": "FetchRoster",
"description": "Fetch the conversation roster",
"title": "FetchRoster",
"type": "action",
"fetchTask": true,
"context": [ "compose" ]
}
]
}
Expand Down