Create and send dialogs
Article 12/28/2023
22 contributors
Feedback
In this article
The initial invoke request
Payload activity properties when a dialog is invoked from 1:1 chat
Payload activity properties when a dialog is invoked from a group chat
Payload activity properties when a dialog is invoked from a meeting chat
Payload activity properties when a dialog is invoked from a channel (new post)
Payload activity properties when a dialog is invoked from a channel (reply to thread)
Payload activity properties when a dialog is invoked from a command box
Initial invoke request from a message
Respond to the fetchTask
Code sample
Next step
See also
Show 8 more
Important
The code samples in this section are based on v4.6 and later versions of the Bot Framework SDK. If you're looking for documentation for earlier versions, see the Message Extensions - v3 SDK section in the Resources folder of the documentation.
You can create a modal dialog (referred as task module in TeamsJS v1.x) using an Adaptive Card or an embedded web view. To create a dialog, you must perform the process called the initial invoke request. This document covers
the initial invoke request, payload activity properties when a dialog is invoked from 1:1 chat, group chat, channel (new post), channel (reply to thread), and command box.
Note
If you are not populating the dialog with parameters defined in the app manifest, you must create the dialog for users with either an Adaptive Card or an embedded web view.
The initial invoke request
In the process of the initial invoke request, your service receives an Activity
object of type composeExtensions/fetchTask
, and you must respond with a task
object containing either an Adaptive Card or a URL to the embedded web view. Along with the standard bot activity properties, the initial invoke payload contains the following request metadata:
Expand table
Property name
Purpose
type
Type of request. It must be invoke
.
name
Type of command that is issued to your service. It must be composeExtension/fetchTask
.
from.id
ID of the user that sent the request.
from.name
Name of the user that sent the request.
from.aadObjectId
Microsoft Entra object ID of the user that sent the request.
channelData.tenant.id
Microsoft Entra tenant ID.
channelData.channel.id
Channel ID (if the request was made in a channel).
channelData.team.id
Team ID (if the request was made in a channel).
value.commandId
Contains the ID of the command that was invoked.
value.commandContext
The context that triggered the event. It must be compose
.
value.context.theme
The user's client theme, useful for embedded web view formatting. It must be default
, contrast
or dark
.
The code for the initial invoke request is given in the following example:
{
"type" : "invoke" ,
"id" : "f:bc319b1d-571a-194d-9ffb-11d7ab37c9ff" ,
"from" : {
"id" : "29:1aBjVi5MwCFfhPIV03E5uDdfpBFXp_2Yz-sjrvVg12oavg96cqpE_DiMhOpmN9zHeZpYbJcuUEKuSDy2AYWPz1A" ,
"name" : "Olo Brockhouse" ,
"aadObjectId" : "b130c271-d2eb-45f9-83ab-9eb3fe3788bc"
}
"channelData" : {
"tenant" : {
"id" : "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
},
"source" : {
"name" : "compose"
}
},
"value" : {
"commandId" : "Test" ,
"commandContext" : "compose" ,
"requestId" : "fe50f49e5c74440bb2ebf07f49e9553c" ,
"context" : {
"theme" : "default"
}
},
"name" : "composeExtension/fetchTask"
Payload activity properties when a dialog is invoked from 1:1 chat
The payload activity properties when a dialog is invoked from 1:1 chat are listed as follows:
Expand table
Property name
Purpose
type
Type of request. It must be invoke
.
name
Type of command that is issued to your service. It must be composeExtension/fetchTask
.
from.id
ID of the user that sent the request.
from.name
Name of the user that sent the request.
from.aadObjectId
Microsoft Entra object ID of the user that sent the request.
channelData.tenant.id
Microsoft Entra tenant ID.
channelData.source.name
The source name from where dialog is invoked.
ChannelData.legacy. replyToId
Gets or sets the ID of the message to which this message is a reply.
value.commandId
Contains the ID of the command that was invoked.
value.commandContext
The context that triggered the event. It must be compose
.
value.context.theme
The user's client theme, useful for embedded web view formatting. It must be default
, contrast
or dark
.
The payload activity properties when a dialog is invoked from 1:1 chat are given in the following example:
{
"type" : "invoke" ,
"id" : "f:bc319b1d-571a-194d-9ffb-11d7ab37c9ff" ,
"from" : {
"id" : "29:1aBjVi5MwCFfhPIV03E5uDdfpBFXp_2Yz-sjrvVg12oavg96cqpE_DiMhOpmN9zHeZpYbJcuUEKuSDy2AYWPz1A" ,
"name" : "Olo Brockhouse" ,
"aadObjectId" : "b130c271-d2eb-45f9-83ab-9eb3fe3788bc"
}
"channelData" : {
"tenant" : {
"id" : "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
},
"source" : {
"name" : "compose"
}
},
"value" : {
"commandId" : "Test" ,
"commandContext" : "compose" ,
"requestId" : "fe50f49e5c74440bb2ebf07f49e9553c" ,
"context" : {
"theme" : "default"
}
},
"name" : "composeExtension/fetchTask"
}
Payload activity properties when a dialog is invoked from a group chat
The payload activity properties when a dialog is invoked from a group chat are listed as follows:
Expand table
Property name
Purpose
type
Type of request. It must be invoke
.
name
Type of command that is issued to your service. It must be composeExtension/fetchTask
.
from.id
ID of the user that sent the request.
from.name
Name of the user that sent the request.
from.aadObjectId
Microsoft Entra object ID of the user that sent the request.
channelData.tenant.id
Microsoft Entra tenant ID.
channelData.source.name
The source name from where dialog is invoked.
ChannelData.legacy. replyToId
Gets or sets the ID of the message to which this message is a reply.
value.commandId
Contains the ID of the command that was invoked.
value.commandContext
The context that triggered the event. It must be compose
.
value.context.theme
The user's client theme, useful for embedded web view formatting. It must be default
, contrast
or dark
.
The payload activity properties when a dialog is invoked from a group chat are given in the following example:
{
"type" : "invoke" ,
"id" : "f:bf72031f-a17e-f99c-48dc-5c0714950d87" ,
"from" : {
"id" : "29:1aBjVi5MwCFfhPIV03E5uDdfpBFXp_2Yz-sjrvVg12oavg96cqpE_DiMhOpmN9zHeZpYbJcuUEKuSDy2AYWPz1A" ,
"name" : "Olo Brockhouse" ,
"aadObjectId" : "b130c271-d2eb-45f9-83ab-9eb3fe3788bc"
},
"conversation" : {
"isGroup" : true ,
"conversationType" : "groupChat" ,
"id" : "19:d77be72390a1416e9644261e9064fa00@thread.skype" ,
"tenantId" : "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
},
"channelData" : {
"tenant" : {
"id" : "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
},
"source" : {
"name" : "compose"
}
},
"value" : {
"commandId" : "Test" ,
"commandContext" : "compose" ,
"requestId" : "213167a1e3b6428b93e186ea5407c759" ,
"context" : {
"theme" : "default"
}
},
"name" : "composeExtension/fetchTask"
}
Payload activity properties when a dialog is invoked from a meeting chat
The payload activity properties when a dialog is invoked from a meeting chat are given in the following example:
{
"type" : "invoke" ,
"id" : "f:4d271f11-4eed-622f-e820-6d82bf91692f" ,
"channelId" : "msteams" ,
"from" : {
"id" : "29:1yLsdbTM1UjxqqD8cjduNUCI1jm8xZaH3lx9u5JQ04t2bknuTCkP45TXdfROTOWk1LzN1AqTgFZUEqHIVGn_qUA" ,
"name" : "MOD Administrator" ,
"aadObjectId" : "ef16aa89-5b26-4a2c-aebb-761b551577c0"
},
"conversation" : {
"tenantId" : "c9f9aafd-64ac-4f38-8e05-12feba3fb090" ,
"id" : "19:meeting_NTk4ZDY4ZmYtOWEzZS00OTRkLThhY2EtZmUzZmUzMDQyM2M0@thread.v2" ,
"name" : "Test meeting"
},
"channelData" : {
"tenant" : {
"id" : "c9f9aafd-64ac-4f38-8e05-12feba3fb090"
},
"source" : {
"name" : "compose"
},
"meeting" : {
"id" : "MCMxOTptZWV0aW5nX05UazRaRFk0Wm1ZdE9XRXpaUzAwT1RSa0xUaGhZMkV0Wm1VelptVXpNRFF5TTJNMEB0aHJlYWQudjIjMA=="
}
},
"value" : {
"commandId" : "Test" ,
"commandContext" : "compose" ,
"requestId" : "c46a6b53573f42b5bc801716e5ccc960" ,
"context" : {
"theme" : "default"
}
},
"name" : "composeExtension/fetchTask" ,
}
Payload activity properties when a dialog is invoked from a channel (new post)
The payload activity properties when a dialog is invoked from a channel (new post) are listed as follows:
Expand table
Property name
Purpose
type
Type of request. It must be invoke
.
name
Type of command that is issued to your service. It must be composeExtension/fetchTask
.
from.id
ID of the user that sent the request.
from.name
Name of the user that sent the request.
from.aadObjectId
Microsoft Entra object ID of the user that sent the request.
channelData.tenant.id
Microsoft Entra tenant ID.
channelData.channel.id
Channel ID (if the request was made in a channel).
channelData.team.id
Team ID (if the request was made in a channel).
channelData.source.name
The source name from where dialog is invoked.
ChannelData.legacy. replyToId
Gets or sets the ID of the message to which this message is a reply.
value.commandId
Contains the ID of the command that was invoked.
value.commandContext
The context that triggered the event. It must be compose
.
value.context.theme
The user's client theme, useful for embedded web view formatting. It must be default
, contrast
, or dark
.
The payload activity properties when a dialog is invoked from a channel (new post) are given in the following example:
{
"type" : "invoke" ,
"id" : "f:a5fbb109-c989-c449-ee83-71ac99919d4b" ,
"from" : {
"id" : "29:1aBjVi5MwCFfhPIV03E5uDdfpBFXp_2Yz-sjrvVg12oavg96cqpE_DiMhOpmN9zHeZpYbJcuUEKuSDy2AYWPz1A" ,
"name" : "Olo Brockhouse" ,
"aadObjectId" : "b130c271-d2eb-45f9-83ab-9eb3fe3788bc"
},
"conversation" : {
"isGroup" : true ,
"conversationType" : "channel" ,
"id" : "19:6decf54d86d945e4b3924b63a9161a78@thread.skype" ,
"name" : "parsable" ,
"tenantId" : "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
},
"channelData" : {
"channel" : {
"id" : "19:6decf54d86d945e4b3924b63a9161a78@thread.skype"
},
"team" : {
"id" : "19:acca514e83cb497e960e0b014d405336@thread.skype"
},
"tenant" : {
"id" : "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
},
"source" : {
"name" : "compose"
}
},
"value" : {
"commandId" : "Test" ,
"commandContext" : "compose" ,
"requestId" : "5336640edc7748b28ce2df43f5b45963" ,
"context" : {
"theme" : "default"
}
},
"name" : "composeExtension/fetchTask"
}
Payload activity properties when a dialog is invoked from a channel (reply to thread)
The payload activity properties when a dialog is invoked from a channel (reply to thread) are listed as follows:
Expand table
Property name
Purpose
type
Type of request. It must be invoke
.
name
Type of command that is issued to your service. It must be composeExtension/fetchTask
.
from.id
ID of the user that sent the request.
from.name
Name of the user that sent the request.
from.aadObjectId
Microsoft Entra object ID of the user that sent the request.
channelData.tenant.id
Microsoft Entra tenant ID.
channelData.channel.id
Channel ID (if the request was made in a channel).
channelData.team.id
Team ID (if the request was made in a channel).
channelData.source.name
The source name from where dialog is invoked.
ChannelData.legacy. replyToId
Gets or sets the ID of the message to which this message is a reply.
value.commandId
Contains the ID of the command that was invoked.
value.commandContext
The context that triggered the event. It must be compose
.
value.context.theme
The user's client theme, useful for embedded web view formatting. It must be default
, contrast
or dark
.
The payload activity properties when a dialog is invoked from a channel (reply to thread) are given in the following example:
{
"type" : "invoke" ,
"id" : "f:19ccc884-c792-35ef-2f40-d0ff43dcca71" ,
"from" : {
"id" : "29:1aBjVi5MwCFfhPIV03E5uDdfpBFXp_2Yz-sjrvVg12oavg96cqpE_DiMhOpmN9zHeZpYbJcuUEKuSDy2AYWPz1A" ,
"name" : "Olo Brockhouse" ,
"aadObjectId" : "b130c271-d2eb-45f9-83ab-9eb3fe3788bc"
},
"conversation" : {
"isGroup" : true ,
"conversationType" : "channel" ,
"id" : "19:6decf54d86d945e4b3924b63a9161a78@thread.skype;messageid=1611060744833" ,
"name" : "parsable" ,
"tenantId" : "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
},
"channelData" : {
"channel" : {
"id" : "19:6decf54d86d945e4b3924b63a9161a78@thread.skype"
},
"team" : {
"id" : "19:acca514e83cb497e960e0b014d405336@thread.skype"
},
"tenant" : {
"id" : "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
},
"source" : {
"name" : "compose"
}
},
"value" : {
"commandId" : "TEst" ,
"commandContext" : "message" ,
"requestId" : "7f7d22efe5414818becebcec649a7912" ,
"messagePayload" : {
"linkToMessage" : "https://teams.microsoft.com/l/message/19:6decf54d86d945e4b3924b63a9161a78@thread.skype/1611060744833" ,
"id" : "1611060744833" ,
"replyToId" : null ,
"createdDateTime" : "2021-01-19T12:52:24.833Z" ,
"lastModifiedDateTime" : null ,
"deleted" : false ,
"summary" : null ,
"importance" : "normal" ,
"locale" : "en-us" ,
"body" : {
"contentType" : "html" ,
"content" : "<div><div><at id=\"0\">Testing outgoing Webhook-Nikitha</at> - Hi</div>\n</div>"
},
"from" : {
"device" : null ,
"conversation" : null ,
"user" : {
"userIdentityType" : "aadUser" ,
"id" : "b130c271-d2eb-45f9-83ab-9eb3fe3788bc" ,
"displayName" : "Olo Brockhouse"
},
"application" : null
},
"reactions" : [],
"mentions" : [
{
"id" : 0 ,
"mentionText" : "Testing outgoing Webhook-Nikitha" ,
"mentioned" : {
"device" : null ,
"conversation" : null ,
"user" : null ,
"application" : {
"applicationIdentityType" : "webhook" ,
"id" : "b8c1c68c-e290-4bdd-81c3-266f310751dc" ,
"displayName" : "Testing outgoing Webhook-Nikitha"
}
}
}
],
"attachments" : []
},
"context" : {
"theme" : "default"
}
},
"name" : "composeExtension/fetchTask"
}
Payload activity properties when a dialog is invoked from a command box
The payload activity properties when a dialog is invoked from a command box are listed as follows:
Expand table
Property name
Purpose
type
Type of request. It must be invoke
.
name
Type of command that is issued to your service. It must be composeExtension/fetchTask
.
from.id
ID of the user that sent the request.
from.name
Name of the user that sent the request.
from.aadObjectId
Microsoft Entra object ID of the user that sent the request.
channelData.tenant.id
Microsoft Entra tenant ID.
channelData.source.name
The source name from where dialog is invoked.
value.commandId
Contains the ID of the command that was invoked.
value.commandContext
The context that triggered the event. It must be compose
.
value.context.theme
The user's client theme, useful for embedded web view formatting. It must be default
, contrast
, or dark
.
The payload activity properties when a dialog is invoked from a command box are given in the following example:
{
"type" : "invoke" ,
"id" : "f:172560f1-95f9-3189-edb2-b7612cd1a3cd" ,
"id" : "29:1aBjVi5MwCFfhPIV03E5uDdfpBFXp_2Yz-sjrvVg12oavg96cqpE_DiMhOpmN9zHeZpYbJcuUEKuSDy2AYWPz1A" ,
"name" : "Olo Brockhouse" ,
"aadObjectId" : "b130c271-d2eb-45f9-83ab-9eb3fe3788bc"
},
"conversation" : {
"isGroup" : true ,
"conversationType" : "channel" ,
"id" : "19:6decf54d86d945e4b3924b63a9161a78@thread.skype" ,
"name" : "parsable" ,
"tenantId" : "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
},
"channelData" : {
"channel" : {
"id" : "19:6decf54d86d945e4b3924b63a9161a78@thread.skype"
},
"team" : {
"id" : "19:acca514e83cb497e960e0b014d405336@thread.skype"
},
"tenant" : {
"id" : "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
},
"source" : {
"name" : "compose"
}
},
"value" : {
"commandId" : "TEst" ,
"commandContext" : "compose" ,
"requestId" : "d2ce690cdc2b4920a538e75882610a30" ,
"context" : {
"theme" : "default"
}
},
"name" : "composeExtension/fetchTask"
}
The following code section is an example of fetchTask
request:
protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync (ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken )
{
}
class TeamsMessagingExtensionsActionPreviewBot extends TeamsActivityHandler {
handleTeamsMessagingExtensionFetchTask(context, action) {
}
}
{
"name" : "composeExtension/fetchTask" ,
"type" : "invoke" ,
"timestamp" : "2019-07-01T22:57:22.175Z" ,
"localTimestamp" : "2019-07-01T15:57:22.175-07:00" ,
"id" : "f:0123456878990178955" ,
"channelId" : "msteams" ,
"serviceURL" : "https://smba.trafficmanager.net/amer/" ,
"from" : {
"id" : "29:1test2GgHIa0DXzDT_OGwL5vSMZdAxDlGR7hYxZ6_JBVqHz2Zq9Nm44FUNWqHCdGBwHg8WrlFRsYrd0cCAS7dig" ,
"name" : "John Smith" ,
"aadObjectId" : "1234567d-1234-462a-8952-35b75f16f1e1"
},
"conversation" : {
"isGroup" : true ,
"conversationType" : "channel" ,
"tenantId" : "1234abcd-1234-12ab-12ab-35b75f16f1e1" ,
"id" : "19:83ed1d507cb5427c93495cf914326310@thread.skype"
},
"recipient" : {
"id" : "28:049566e0-4401-4bcf-86a1-ce22082ce03a" ,
"name" : "mess"
},
"entities" : [
{
"locale" : "en-US" ,
"country" : "US" ,
"platform" : "Windows" ,
"type" : "clientInfo"
}
],
"channelData" : {
"channel" : {
"id" : "19:83ab1d507cb5427c93495cf912345678@thread.skype"
},
"team" : {
"id" : "19:83ab1d507cb5427c93495cf912345678@thread.skype"
},
"tenant" : {
"id" : "1234abcd-1234-12ab-12ab-35b75f16f1e1"
},
"source" : {
"name" : "compose"
}
},
"value" : {
"commandId" : "hello" ,
"commandContext" : "compose" ,
"context" : {
"theme" : "dark"
}
},
"locale" : "en-US"
}
Initial invoke request from a message
When your bot is invoked from a message, the value
object in the initial invoke request must contain the details of the message that your message extension is invoked from. The reactions
and mentions
arrays are optional, and they are not present if there are no reactions or mentions in the original message.
The following section is an example of the value
object:
protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync (ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken )
{
var messageText = action.MessagePayload.Body.Content;
var fromId = action.MessagePayload.From.User.Id;
}
class TeamsMessagingExtensionsActionPreview extends TeamsActivityHandler {
handleTeamsMessagingExtensionFetchTask(context, action) {
const messageText = action.messagePayload.body.content;
}
}
{
"name" : "composeExtension/submitAction" ,
"type" : "invoke" ,
...
"value" : {
"commandId" : "setReminder" ,
"commandContext" : "message" ,
"messagePayload" : {
"id" : "1111111111" ,
"replyToId" : null ,
"createdDateTime" : "2019-02-25T21:29:36.065Z" ,
"lastModifiedDateTime" : null ,
"deleted" : false ,
"subject" : "Message subject" ,
"summary" : null ,
"importance" : "normal" ,
"locale" : "en-us" ,
"body" : {
"contentType" : "html" ,
"content" : "This is the message the messaging extension was invoked from."
},
"from" : {
"device" : null ,
"conversation" : null ,
"user" : {
"userIdentityType" : "aadUser" ,
"id" : "wxyz12ab8-ab12-cd34-ef56-098abc123876" ,
"displayName" : "Jamie Smythe"
},
"application" : null
},
"reactions" : [
{
"reactionType" : "like" ,
"createdDateTime" : "2019-02-25T22:40:40.806Z" ,
"user" : {
"device" : null ,
"conversation" : null ,
"user" : {
"userIdentityType" : "aadUser" ,
"id" : "qrst12346-ab12-cd34-ef56-098abc123876" ,
"displayName" : "Jim Brown"
},
"application" : null
}
}
],
"mentions" : [
{
"id" : 0 ,
"mentionText" : "Sarah" ,
"mentioned" : {
"device" : null ,
"conversation" : null ,
"user" : {
"userIdentityType" : "aadUser" ,
"id" : "ab12345678-ab12-cd34-ef56-098abc123876" ,
"displayName" : "Sarah"
},
"application" : null
}
}
]
}
...
Respond to the invoke request with a task
object that contains either a taskInfo
object with the Adaptive Card or web URL, or a simple string message.
Expand table
Property name
Purpose
type
Can be either continue
to present a form, or message
for a simple pop-up.
value
Either a taskInfo
object for a form, or a string
for a message.
The schema for the taskInfo object is:
Expand table
Property name
Purpose
title
The title of the dialog.
height
It must be either an integer (in pixels), or small
, medium
, large
.
width
It must be either an integer (in pixels), or small
, medium
, large
.
card
The Adaptive Card defining the form (if using one).
url
The URL to be opened inside of the dialog as an embedded web view.
fallbackUrl
If a client does not support the dialog feature, this URL is opened in a browser tab.
Respond to the fetchTask with an Adaptive Card
When using an Adaptive Card, you must respond with a task
object with the value
object containing an Adaptive Card.
The following code section is an example to fetchTask
response with an Adaptive Card:
This sample uses the AdaptiveCards NuGet package in addition to the Bot Framework SDK.
protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync (ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken )
{
string placeholder = "Not invoked from message" ;
if (action.MessagePayload != null )
{
var messageText = action.MessagePayload.Body.Content;
var fromId = action.MessagePayload.From.User.Id;
placeholder = "Invoked from message" ;
}
var response = new MessagingExtensionActionResponse()
{
Task = new TaskModuleContinueResponse()
{
Value = new TaskModuleTaskInfo()
{
Height = "small" ,
Width = "small" ,
Title = "Example dialog" ,
Card = new Attachment()
{
ContentType = AdaptiveCard.ContentType,
Content = new AdaptiveCard("1.0" )
{
Body = new List<AdaptiveElement>()
{
new AdaptiveTextInput() { Id = "FormField1" , Placeholder = placeholder},
new AdaptiveTextInput() { Id = "FormField2" , Placeholder = "FormField2" },
new AdaptiveTextInput() { Id = "FormField3" , Placeholder = "FormField3" },
},
Actions = new List<AdaptiveAction>()
{
new AdaptiveSubmitAction()
{
Type = AdaptiveSubmitAction.TypeName,
Title = "Submit" ,
},
},
},
},
},
},
};
return response;
}
class TeamsMessagingExtensionsActionPreview extends TeamsActivityHandler {
handleTeamsMessagingExtensionFetchTask(context, action) {
const adaptiveCard = CardFactory.adaptiveCard({
actions : [{
data : { submitLocation : 'messagingExtensionFetchTask' },
title : 'Submit' ,
type : 'Action.Submit'
}],
body : [
{ text : 'Task Module' , type : 'TextBlock' , weight : 'bolder' },
{ type : 'TextBlock' , text : 'Enter text for Question:' },
{ id : 'Question' , placeholder : 'Question text here' , type : 'Input.Text' , value : userText },
{ type : 'TextBlock' , text : 'Options for Question:' },
{ type : 'TextBlock' , text : 'Is Multi-Select:' },
{
choices : [{ title : 'True' , value : 'true' }, { title : 'False' , value : 'false' }],
id : 'MultiSelect' ,
isMultiSelect : false ,
style : 'expanded' ,
type : 'Input.ChoiceSet' ,
value : isMultiSelect ? 'true' : 'false'
},
{ id : 'Option1' , placeholder : 'Option 1 here' , type : 'Input.Text' , value : option1 },
{ id : 'Option2' , placeholder : 'Option 2 here' , type : 'Input.Text' , value : option2 }
],
type : 'AdaptiveCard' ,
version : '1.0'
});
return {
task : {
type : 'continue' ,
value : {
card : adaptiveCard,
height : 450 ,
title : 'Task Module Fetch Example' ,
url : null ,
width : 500
}
}
};
}
}
{
"task" : {
"type" : "continue" ,
"value" : {
"title" : "Dialog title" ,
"height" : 500 ,
"width" : "medium" ,
"card" : {
"$schema" : "http://adaptivecards.io/schemas/adaptive-card.json" ,
"type" : "AdaptiveCard" ,
"version" : "1.0" ,
"body" : [
{
"type" : "Input.Text" ,
"placeholder" : "FormField1" ,
"id" : "FormField1"
},
{
"type" : "Input.Text" ,
"placeholder" : "FormField2" ,
"id" : "FormField2"
},
{
"type" : "Input.Text" ,
"placeholder" : "FormField3" ,
"id" : "FormField3"
},
{
"type" : "ActionSet" ,
"actions" : [
{
"type" : "Action.Submit" ,
"title" : "Action.Submit" ,
"id" : "submitAction"
}
]
}
]
}
}
}
}
Create a dialog with an embedded web view
When using an embedded web view, you must respond with a task
object with the value
object containing the URL to the web form that you want to load. The domains of any URL you want to load must be included in the validDomains
array in your app's manifest. For more information on building your embedded web view, see the dialog documentation .
protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync (ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken )
{
string placeholder = "Not invoked from message" ;
if (action.MessagePayload != null )
{
var messageText = action.MessagePayload.Body.Content;
var fromId = action.MessagePayload.From.User.Id;
placeholder = "Invoked from message" ;
}
var response = new MessagingExtensionActionResponse()
{
Task = new TaskModuleContinueResponse()
{
Value = new TaskModuleTaskInfo()
{
Height = "small" ,
Width = "small" ,
Title = "Example dialog" ,
Url = "https://contoso.com/msteams/taskmodules/newcustomer" ,
},
},
},
};
return response;
}
class TeamsMessagingExtensionsActionPreview extends TeamsActivityHandler {
handleTeamsMessagingExtensionFetchTask(context, action) {
return {
task : {
type : 'continue' ,
value : {
width : 500 ,
height : 450 ,
title : 'Task Module Fetch Example' ,
url : 'https://contoso.com/msteams/taskmodules/newcustomer' ,
fallbackUrl : 'https://contoso.com/msteams/taskmodules/newcustomer'
}
}
};
}
}
{
"task" : {
"type" : "continue" ,
"value" : {
"title" : "Dialog title" ,
"height" : 500 ,
"width" : "medium" ,
"url" : "https://contoso.com/msteams/taskmodules/newcustomer" ,
"fallbackUrl" : "https://contoso.com/msteams/taskmodules/newcustomer"
}
}
}
Request to install your conversational bot
If the app contains a conversational bot, install the bot in the conversation and then load the dialog. The bot is useful to get additional context for the dialog. An example for this scenario is to fetch the roster to populate a people picker control or the list of channels in a team.
When the message extension receives the composeExtensions/fetchTask
invoke, check if the bot is installed in the current context to facilitate the flow. For example, check the flow with a get roster call. If the bot is not installed, return an Adaptive Card with an action that requests the user to install the bot. The user must have the permission to install the apps in that location for checking. If the app installation is unsuccessful, the user receives a message to contact the administrator.
The following code section is an example of the response:
{
"type" : "AdaptiveCard" ,
"body" : [
{
"type" : "TextBlock" ,
"text" : "Looks like you haven't used Disco in this team/chat"
}
],
"actions" : [
{
"type" : "Action.Submit" ,
"title" : "Continue" ,
"data" : {
"msteams" : {
"justInTimeInstall" : true
}
}
}
],
"version" : "1.0"
}
After the installation of conversational bot, it receives another invoke message with name = composeExtensions/submitAction
, and value.data.msteams.justInTimeInstall = true
.
The following code section is an example of the task response to the invoke:
{
"value" : {
"commandId" : "giveKudos" ,
"commandContext" : "compose" ,
"context" : {
"theme" : "default"
},
"data" : {
"msteams" : {
"justInTimeInstall" : true
}
}
},
"conversation" : {
"id" : "19:7705841b240044b297123ad7f9c99217@thread.skype"
},
"name" : "composeExtension/submitAction" ,
"imdisplayname" : "Bob Smith"
}
The task response to the invoke must be similar to that of the installed bot.
The following code section is an example of just-in time installation of app with Adaptive card:
private static Attachment GetAdaptiveCardAttachmentFromFile (string fileName )
{
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;
}
Expand table
Sample name
Description
.NET
Node.js
Python
Manifest
Teams message extension action
This sample shows how to define action commands, create dialog, and respond to dialog submit action.
View
View
View
View
Message extension action preview
This sample shows how to use action preview in Messaging Extensions using Bot Framework v4.
View
View
NA
View
Teams message extension search
This sample shows how to build a Search-based Message Extension. It searches nudget packages and displays the results in search based messaging extension.
View
View
View
View