Bot builder : Upload file in a input form - adaptive cards
Tag : azure , By : francisco santos
Date : March 29 2020, 07:55 AM
Any of those help Action.OpenUrl, Action.Submit and Action.ShowCard are currently the only Adaptive Card action types. There is no action type for file uploading. If you are targeting the webchat channel, you could download the repository and make custom modifications to enable some sort of file upload from an adaptive card. You can make a feature request for a new Action type here: https://github.com/Microsoft/AdaptiveCards/issues
|
How to retrieve Adaptive Card's form submission in subsequent waterfall step
Tag : chash , By : Mark W
Date : March 29 2020, 07:55 AM
help you fix your problem Adaptive Cards send their Submit results a little different than regular user text. When a user types in the chat and sends a normal message, it ends up in Context.Activity.Text. When a user fills out an input on an Adaptive Card, it ends up in Context.Activity.Value, which is an object where the key names are the id in your card and the values are the field values in the adaptive card. For example, the json: {
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"text": "Test Adaptive Card"
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"items": [
{
"type": "TextBlock",
"text": "Text:"
}
],
"width": 20
},
{
"type": "Column",
"items": [
{
"type": "Input.Text",
"id": "userText",
"placeholder": "Enter Some Text"
}
],
"width": 80
}
]
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Submit"
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0"
}
{ type: 'message',
value: { userText: 'Testing Testing 123' },
from: { id: 'xxxxxxxx-05d4-478a-9daa-9b18c79bb66b', name: 'User' },
locale: '',
channelData: { postback: true },
channelId: 'emulator',
conversation: { id: 'xxxxxxxx-182b-11e9-be61-091ac0e3a4ac|livechat' },
id: 'xxxxxxxx-182b-11e9-ad8e-63b45e3ebfa7',
localTimestamp: 2019-01-14T18:39:21.000Z,
recipient: { id: '1', name: 'Bot', role: 'bot' },
timestamp: 2019-01-14T18:39:21.773Z,
serviceUrl: 'http://localhost:58453' }
private async Task<DialogTurnResult> DisplayCardAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
// Create the Adaptive Card
var cardPath = Path.Combine(".", "AdaptiveCard.json");
var cardJson = File.ReadAllText(cardPath);
var cardAttachment = new Attachment()
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = JsonConvert.DeserializeObject(cardJson),
};
// Create the text prompt
var opts = new PromptOptions
{
Prompt = new Activity
{
Attachments = new List<Attachment>() { cardAttachment },
Type = ActivityTypes.Message,
Text = "waiting for user input...", // You can comment this out if you don't want to display any text. Still works.
}
};
// Display a Text Prompt and wait for input
return await stepContext.PromptAsync(nameof(TextPrompt), opts);
}
private async Task<DialogTurnResult> HandleResponseAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
// Do something with step.result
// Adaptive Card submissions are objects, so you likely need to JObject.Parse(step.result)
await stepContext.Context.SendActivityAsync($"INPUT: {stepContext.Result}");
return await stepContext.NextAsync();
}
var activity = turnContext.Activity;
if (string.IsNullOrWhiteSpace(activity.Text) && activity.Value != null)
{
activity.Text = JsonConvert.SerializeObject(activity.Value);
}
|
Capture values submitted by Adaptive Card in waterfall dialog
Date : March 29 2020, 07:55 AM
hop of those help? I have followed the advice of this question, the comment on this issue and also this answer. , My issue turned out to be two-fold var postbackActivity = dc.Context.Activity;
string text = JsonConvert.DeserializeObject<DialogValueDto>(postbackActivity.Value.ToString())?.UserInput;
postbackActivity.Text = text;
await dc.Context.SendActivityAsync(postbackActivity);
dc.Context.Activity.Text = text
object value = dc.Context.Activity.Value;
if (condition)
{
// do nothing
}
else if (value.GetType() == typeof(JObject))
{
// code from the Virtual Assistant template to check the values passed through
var submit = JObject.Parse(value.ToString());
// more template code
// Template code
if (forward)
{
var result = await dc.ContinueDialogAsync();
if (result.Status == DialogTurnStatus.Complete)
{
await CompleteAsync(dc);
}
}
}
public DynamicWaterfallDialog(
...
)
: base(nameof(DynamicWaterfallDialog))
{
...
InitialDialogId = nameof(WaterfallDialog);
var waterfallSteps = new WaterfallStep[]
{
UserInputStepAsync,
LoopStepAsync,
};
AddDialog(new TextPrompt(nameof(TextPrompt)));
AddDialog(new WaterfallDialog(InitialDialogId, waterfallSteps));
}
public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken)
{
...
var dc = await _dialogs.CreateContextAsync(turnContext);
if (dc.Context.Activity.Type == ActivityTypes.Message)
{
// Ensure that message is a postBack (like a submission from Adaptive Cards)
if (dc.Context.Activity.GetType().GetProperty("ChannelData") != null)
{
JObject channelData = JObject.Parse(dc.Context.Activity.ChannelData.ToString());
Activity postbackActivity = dc.Context.Activity;
if (channelData.ContainsKey("postBack") && postbackActivity.Value != null)
{
DialogValueDto dialogValueDto = JsonConvert.DeserializeObject<DialogValueDto>(postbackActivity.Value.ToString());
// Only set the text property for adaptive cards because the value we want, and the value that the user submits comes through the
// on the Value property for adaptive cards, instead of the text property like everything else
if (DialogValueDtoExtensions.IsValidDialogValueDto(dialogValueDto) && dialogValueDto.CardType == CardTypeEnum.Adaptive)
{
// Convert the user's Adaptive Card input into the input of a Text Prompt, must be sent as a string
dc.Context.Activity.Text = JsonConvert.SerializeObject(dialogValueDto);
// We don't need to post the text as per https://stackoverflow.com/a/56010355/5209435 because this is automatically handled inside the
// OnEventAsync method of MainDialog.cs
}
}
}
}
if (dc.ActiveDialog != null)
{
var result = await dc.ContinueDialogAsync();
}
else
{
await dc.BeginDialogAsync(typeof(T).Name);
}
}
protected override async Task OnEventAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken))
{
object value = dc.Context.Activity.Value;
if (value.GetType() == typeof(JObject))
{
var submit = JObject.Parse(value.ToString());
if (value != null)
{
// Null propagation here is to handle things like dynamic adaptive cards that submit objects
string action = submit["action"]?.ToString();
...
}
var forward = true;
var ev = dc.Context.Activity.AsEventActivity();
// Null propagation here is to handle things like dynamic adaptive cards that may not convert into an EventActivity
if (!string.IsNullOrWhiteSpace(ev?.Name))
{
...
}
if (forward)
{
var result = await dc.ContinueDialogAsync();
if (result.Status == DialogTurnStatus.Complete)
{
await CompleteAsync(dc);
}
}
}
}
|
How to work properly with advanced Adaptive Cards?
Tag : chash , By : PaulPlum
Date : March 29 2020, 07:55 AM
Hope that helps I've answered each of those questions a few times. I have a feeling you'll run into more, so feel free to search my user for Adaptive Card questions. For each of your questions, specifically: {
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "Container",
"selectAction": {
"type": "Action.ToggleVisibility",
"targetElements": [
"showMe"
]
},
"items": [
{
"type": "TextBlock",
"text": "Click me"
}
]
},
{
"type": "Container",
"id": "showMe",
"items": [
{
"type": "TextBlock",
"text": "New TextBlock"
}
],
"isVisible": false
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"selectAction": {
"type": "Action.Submit",
"data": "ok"
}
}
|
Get User Input from Adaptive Card using Waterfall Dialog in Botframework v4
Date : March 29 2020, 07:55 AM
I wish this help you UPDATE Now that I've reviewed your code, I've found the answer. First, a few points: const activity = turnContext.activity;
if (!activity.text && activity.value) {
activity.text = JSON.stringify(activity.value);
}
turnContext.activity.text = JSON.stringify(turnContext.activity.value);
const activity = turnContext.activity
const activity = copyOf(turnContext.activity)
const activity = memoryLocationOf(turnContext.activity)
if (dc.activeDialog !== undefined) {
const activity = turnContext.activity;
if (!activity.text && activity.value) {
activity.text = JSON.stringify(activity.value);
}
await dc.continueDialog();
} else {
await dc.beginDialog(this.rootDialogId);
}
await next();
async displayCard(step) {
const cardPrompt = MessageFactory.text('');
cardPrompt.attachments = [yourAdaptiveCard];
return await step.prompt('textPrompt', cardPrompt);
}
|