diff --git a/samples/javascript_nodejs/51.teams-messaging-extensions-action/bots/teamsMessagingExtensionsActionBot.js b/samples/javascript_nodejs/51.teams-messaging-extensions-action/bots/teamsMessagingExtensionsActionBot.js index f35995261c..9bd5ad67c4 100644 --- a/samples/javascript_nodejs/51.teams-messaging-extensions-action/bots/teamsMessagingExtensionsActionBot.js +++ b/samples/javascript_nodejs/51.teams-messaging-extensions-action/bots/teamsMessagingExtensionsActionBot.js @@ -1,19 +1,104 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -const { TeamsActivityHandler, CardFactory } = require('botbuilder'); +const { TeamsActivityHandler, CardFactory, TeamsInfo } = require('botbuilder'); class TeamsMessagingExtensionsActionBot extends TeamsActivityHandler { handleTeamsMessagingExtensionSubmitAction(context, action) { switch (action.commandId) { - case 'createCard': - return createCardCommand(context, action); - case 'shareMessage': - return shareMessageCommand(context, action); - default: - throw new Error('NotImplemented'); + case 'createCard': + return createCardCommand(context, action); + case 'shareMessage': + return shareMessageCommand(context, action); + default: + throw new Error('NotImplemented'); } } + + async handleTeamsMessagingExtensionFetchTask(context, action) { + try { + const member = await this.getSingleMember(context); + return { + task: { + type: 'continue', + value: { + card: GetAdaptiveCardAttachment(), + height: 400, + title: 'Hello ' + member, + width: 300 + }, + }, + }; + } catch (e) { + if (e.code === 'BotNotInConversationRoster') { + return { + task: { + type: 'continue', + value: { + card: GetJustInTimeCardAttachment(), + height: 400, + title: 'Adaptive Card - App Installation', + width: 300 + }, + }, + }; + } + throw e; + } + + } + async getSingleMember(context) { + try { + const member = await TeamsInfo.getMember( + context, + context.activity.from.id + ); + return member.name; + } catch (e) { + if (e.code === 'MemberNotFoundInConversation') { + context.sendActivity(MessageFactory.text('Member not found.')); + return e.code; + } + throw e; + } + } +} + +function GetJustInTimeCardAttachment() { + return CardFactory.adaptiveCard({ + actions: [ + { + type: 'Action.Submit', + title: 'Continue', + data: { msteams: { justInTimeInstall: true } } + }, + ], + body: [ + { + text: 'Looks like you have not used Action Messaging Extension app in this team/chat. Please click **Continue** to add this app.', + type: 'TextBlock', + wrap: 'bolder' + }, + ], + type: 'AdaptiveCard', + version: '1.0', + }); +} + +function GetAdaptiveCardAttachment() { + return CardFactory.adaptiveCard({ + actions: [{ type: 'Action.Submit', title: 'Close' }], + body: [ + { + text: 'This app is installed in this conversation. You can now use it to do some great stuff!!!', + type: 'TextBlock', + isSubtle: false, + warp: true + }, + ], + type: 'AdaptiveCard', + version: '1.0', + }); } function createCardCommand(context, action) { @@ -21,25 +106,25 @@ function createCardCommand(context, action) { const data = action.data; const heroCard = CardFactory.heroCard(data.title, data.text); heroCard.content.subtitle = data.subTitle; - const attachment = { contentType: heroCard.contentType, content: heroCard.content, preview: heroCard }; + const attachment = { + contentType: heroCard.contentType, + content: heroCard.content, + preview: heroCard, + }; return { composeExtension: { type: 'result', attachmentLayout: 'list', - attachments: [ - attachment - ] - } + attachments: [attachment] + }, }; } function shareMessageCommand(context, action) { // The user has chosen to share a message by choosing the 'Share Message' context menu command. let userName = 'unknown'; - if (action.messagePayload.from && - action.messagePayload.from.user && - action.messagePayload.from.user.displayName) { + if (action.messagePayload?.from?.user?.displayName) { userName = action.messagePayload.from.user.displayName; } @@ -48,28 +133,34 @@ function shareMessageCommand(context, action) { let images = []; const includeImage = action.data.includeImage; if (includeImage === 'true') { - images = ['https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQtB3AwMUeNoq4gUBGe6Ocj8kyh3bXa9ZbV7u1fVKQoyKFHdkqU']; + images = [ + 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQtB3AwMUeNoq4gUBGe6Ocj8kyh3bXa9ZbV7u1fVKQoyKFHdkqU', + ]; } - const heroCard = CardFactory.heroCard(`${ userName } originally sent this message:`, + const heroCard = CardFactory.heroCard( + `${userName} originally sent this message:`, action.messagePayload.body.content, - images); + images + ); - if (action.messagePayload.attachments && action.messagePayload.attachments.length > 0) { + if (action.messagePayload.attachments?.length > 0) { // This sample does not add the MessagePayload Attachments. This is left as an // exercise for the user. - heroCard.content.subtitle = `(${ action.messagePayload.attachments.length } Attachments not included)`; + heroCard.content.subtitle = `(${action.messagePayload.attachments.length} Attachments not included)`; } - const attachment = { contentType: heroCard.contentType, content: heroCard.content, preview: heroCard }; + const attachment = { + contentType: heroCard.contentType, + content: heroCard.content, + preview: heroCard + }; return { composeExtension: { type: 'result', attachmentLayout: 'list', - attachments: [ - attachment - ] - } + attachments: [attachment] + }, }; } diff --git a/samples/javascript_nodejs/51.teams-messaging-extensions-action/teamsAppManifest/manifest.json b/samples/javascript_nodejs/51.teams-messaging-extensions-action/teamsAppManifest/manifest.json index bf26138930..e68727d6d1 100644 --- a/samples/javascript_nodejs/51.teams-messaging-extensions-action/teamsAppManifest/manifest.json +++ b/samples/javascript_nodejs/51.teams-messaging-extensions-action/teamsAppManifest/manifest.json @@ -23,6 +23,18 @@ "color": "icon-color.png" }, "accentColor": "#FFFFFF", + "bots": [ + { + "botId": "<>", + "needsChannelSelector": false, + "isNotificationOnly": false, + "scopes": [ + "team", + "personal", + "groupchat" + ] + } + ], "composeExtensions": [ { "botId": "<>", @@ -30,7 +42,9 @@ { "id": "createCard", "type": "action", - "context": [ "compose" ], + "context": [ + "compose" + ], "description": "Command to run action to create a Card from Compose Box", "title": "Create Card", "parameters": [ @@ -57,7 +71,9 @@ { "id": "shareMessage", "type": "action", - "context": [ "message" ], + "context": [ + "message" + ], "description": "Test command to run action on message context (message sharing)", "title": "Share Message", "parameters": [ @@ -68,6 +84,16 @@ "inputType": "toggle" } ] + }, + { + "id": "FetchRoster", + "description": "Fetch the conversation roster", + "title": "FetchRoster", + "type": "action", + "fetchTask": true, + "context": [ + "compose" + ] } ] }