Odesílání příloh médií pomocí sady Bot Framework SDK
Článek
PLATÍ PRO: SDK v4
Zprávy vyměňované mezi uživatelem a robotem můžou obsahovat mediální přílohy, jako jsou obrázky, video, zvuk a soubory. Sada SDK služby Bot Framework podporuje úlohu odesílání bohatých zpráv uživateli. Pokud chcete určit typ bohatých zpráv, které kanál (Facebook, Slack atd.) podporuje, přečtěte si informace o omezeních v dokumentaci kanálu.
Poznámka:
Sady SDK služby Bot Framework JavaScript, C# a Python budou nadále podporovány, ale sada Java SDK se vyřazuje s konečnou dlouhodobou podporou končící v listopadu 2023.
Stávající roboti sestavení pomocí sady Java SDK budou i nadále fungovat.
Veškerý zdrojový kód zobrazený v této části vychází z ukázky Zpracování příloh .
Vlastnost Attachments objektu Activity obsahuje pole Attachment objektů, které představují přílohy médií a bohaté karty připojené ke zprávě. Chcete-li přidat přílohu média do zprávy, vytvořte Attachment objekt pro reply aktivitu a nastavte ContentType, ContentUrla Name vlastnosti.
Pokud chcete vytvořit zprávu odpovědi, definujte text a nastavte přílohy. Přiřazení příloh k odpovědi je stejné pro každý typ přílohy, ale různé přílohy jsou nastaveny a definovány odlišně, jak je vidět v následujících fragmentech kódu. Níže uvedený kód nastavuje odpověď pro vloženou přílohu:
Roboti/AttachmentsBot.cs
{
reply = MessageFactory.Text("This is an inline attachment.");
Dále se podíváme na typy příloh. První je vložená příloha:
Roboti/AttachmentsBot.cs
{
var imagePath = Path.Combine(Environment.CurrentDirectory, @"Resources", "architecture-resize.png");
var imageData = Convert.ToBase64String(File.ReadAllBytes(imagePath));
return new Attachment
{
Name = @"Resources\architecture-resize.png",
ContentType = "image/png",
ContentUrl = $"data:image/png;base64,{imageData}",
};
}
Pak nahranou přílohu:
Roboti/AttachmentsBot.cs
{
if (string.IsNullOrWhiteSpace(serviceUrl))
{
throw new ArgumentNullException(nameof(serviceUrl));
}
if (string.IsNullOrWhiteSpace(conversationId))
{
throw new ArgumentNullException(nameof(conversationId));
}
var imagePath = Path.Combine(Environment.CurrentDirectory, @"Resources", "architecture-resize.png");
var connector = turnContext.TurnState.Get<IConnectorClient>() as ConnectorClient;
var attachments = new Attachments(connector);
var response = await attachments.Client.Conversations.UploadAttachmentAsync(
conversationId,
new AttachmentData
{
Name = @"Resources\architecture-resize.png",
OriginalBase64 = File.ReadAllBytes(imagePath),
Type = "image/png",
},
cancellationToken);
var attachmentUri = attachments.GetAttachmentUri(response.Id);
return new Attachment
{
Name = @"Resources\architecture-resize.png",
ContentType = "image/png",
ContentUrl = attachmentUri,
};
}
A konečně, internetová příloha:
Roboti/AttachmentsBot.cs
{
// ContentUrl must be HTTPS.
return new Attachment
{
Name = @"Resources\architecture-resize.png",
ContentType = "image/png",
ContentUrl = "https://docs.microsoft.com/en-us/bot-framework/media/how-it-works/architecture-resize.png",
};
}
}
Pokud chcete vytvořit zprávu odpovědi, definujte text a nastavte přílohy. Přiřazení příloh k odpovědi je stejné pro každý typ přílohy, ale různé přílohy jsou nastaveny a definovány odlišně, jak je vidět v následujících fragmentech kódu. Níže uvedený kód nastavuje odpověď pro vloženou přílohu:
roboti/attachmentsBot.js
*/
const firstChar = turnContext.activity.text[0];
if (firstChar === '1') {
Pokud chcete uživateli poslat jeden obsah, jako je obrázek nebo video, můžete multimédia odeslat několika různými způsoby. Nejprve jako vložená příloha:
A konečně, internetová příloha obsažená v adrese URL:
roboti/attachmentsBot.js
* Returns an attachment to be sent to the user from a HTTPS URL.
*/
getInternetAttachment() {
// NOTE: The contentUrl must be HTTPS.
return {
name: 'architecture-resize.png',
contentType: 'image/png',
contentUrl: 'https://docs.microsoft.com/en-us/bot-framework/media/how-it-works/architecture-resize.png'
Zdrojový kód zobrazený v této části vychází z ukázky zpracování příloh .
getAttachments() Metoda objektu Activity obsahuje pole Attachment objektů, které představují multimediální přílohy a bohaté karty připojené ke zprávě. Chcete-li přidat přílohu média do zprávy, vytvořte Attachment objekt pro reply aktivitu a nastavte ContentType, ContentUrla Name vlastnosti.
Pokud chcete vytvořit zprávu odpovědi, definujte text a nastavte přílohy. Přiřazení příloh k odpovědi je stejné pro každý typ přílohy, ale různé přílohy jsou nastaveny a definovány odlišně, jak je vidět v následujících fragmentech kódu. Níže uvedený kód nastavuje odpověď pro vloženou přílohu:
AttachmentsBot.java
result = getInlineAttachment()
.thenApply(attachment -> {
Activity reply = MessageFactory.text("This is an inline attachment.");
reply.setAttachment(attachment);
return reply;
});
Dále se podíváme na typy příloh. První je vložená příloha:
AttachmentsBot.java
// Creates an inline attachment sent from the bot to the user using a base64 string.
// Using a base64 string to send an attachment will not work on all channels.
// Additionally, some channels will only allow certain file types to be sent this way.
// For example a .png file may work but a .pdf file may not on some channels.
// Please consult the channel documentation for specifics.
private CompletableFuture<Attachment> getInlineAttachment() {
return getEncodedFileData("architecture-resize.png")
.thenApply(encodedFileData -> {
Attachment attachment = new Attachment();
attachment.setName("architecture-resize.png");
attachment.setContentType("image/png");
attachment.setContentUrl("data:image/png;base64," + encodedFileData);
return attachment;
});
}
// Creates an Attachment to be sent from the bot to the user from a HTTP URL.
private static Attachment getInternetAttachment() {
// ContentUrl must be HTTPS.
Attachment attachment = new Attachment();
attachment.setName("architecture-resize.png");
attachment.setContentType("image/png");
attachment.setContentUrl("https://docs.microsoft.com/en-us/bot-framework/media/how-it-works/architecture-resize.png");
return attachment;
}
Pokud chcete vytvořit zprávu odpovědi, definujte text a nastavte přílohy. Přiřazení příloh k odpovědi je stejné pro každý typ přílohy, ale různé přílohy jsou nastaveny a definovány odlišně, jak je vidět v následujících fragmentech kódu.
Níže uvedený kód nastavuje odpověď pro vloženou přílohu:
roboti/attachments_bot.py
reply.text = "This is an inline attachment."
reply.attachments = [self._get_inline_attachment()]
Pokud chcete uživateli poslat jeden obsah, jako je obrázek nebo video, můžete multimédia odeslat několika různými způsoby. Nejprve jako vložená příloha:
roboti/attachments_bot.py
def _get_inline_attachment(self) -> Attachment:
"""
Creates an inline attachment sent from the bot to the user using a base64 string.
Using a base64 string to send an attachment will not work on all channels.
Additionally, some channels will only allow certain file types to be sent this way.
For example a .png file may work but a .pdf file may not on some channels.
Please consult the channel documentation for specifics.
:return: Attachment
"""
file_path = os.path.join(os.getcwd(), "resources/architecture-resize.png")
with open(file_path, "rb") as in_file:
base64_image = base64.b64encode(in_file.read()).decode()
return Attachment(
name="architecture-resize.png",
content_type="image/png",
content_url=f"data:image/png;base64,{base64_image}",
)
Pak nahranou přílohu:
roboti/attachments_bot.py
async def _get_upload_attachment(self, turn_context: TurnContext) -> Attachment:
"""
Creates an "Attachment" to be sent from the bot to the user from an uploaded file.
:param turn_context:
:return: Attachment
"""
with open(
os.path.join(os.getcwd(), "resources/architecture-resize.png"), "rb"
) as in_file:
image_data = in_file.read()
connector = await turn_context.adapter.create_connector_client(
turn_context.activity.service_url
)
conversation_id = turn_context.activity.conversation.id
response = await connector.conversations.upload_attachment(
conversation_id,
AttachmentData(
name="architecture-resize.png",
original_base64=image_data,
type="image/png",
),
)
base_uri: str = connector.config.base_url
attachment_uri = (
base_uri
+ ("" if base_uri.endswith("/") else "/")
+ f"v3/attachments/{response.id}/views/original"
)
return Attachment(
name="architecture-resize.png",
content_type="image/png",
content_url=attachment_uri,
)
A konečně, internetová příloha obsažená v adrese URL:
roboti/attachments_bot.py
def _get_internet_attachment(self) -> Attachment:
"""
Creates an Attachment to be sent from the bot to the user from a HTTP URL.
:return: Attachment
"""
return Attachment(
name="architecture-resize.png",
content_type="image/png",
content_url="https://docs.microsoft.com/en-us/bot-framework/media/how-it-works/architecture-resize.png",
)
Pokud je příloha obrázkem, zvukem nebo videem, služba Konektor bude komunikovat data přílohy do kanálu způsobem, který kanálu umožní vykreslit tuto přílohu v rámci konverzace. Pokud je příloha souborem, adresa URL souboru se v rámci konverzace vykreslí jako hypertextový odkaz.
Odeslání karty hrdiny
Kromě jednoduchých obrázků nebo video příloh můžete připojit kartu hrdiny, která umožňuje kombinovat obrázky a tlačítka v jednom objektu a odeslat je uživateli. Markdown je podporovaný pro většinu textových polí, ale podpora se může lišit podle kanálu.
private static async Task DisplayOptionsAsync(ITurnContext turnContext, CancellationToken cancellationToken)
{
// Create a HeroCard with options for the user to interact with the bot.
var card = new HeroCard
{
Text = "You can upload an image or select one of the following choices",
Buttons = new List<CardAction>
{
// Note that some channels require different values to be used in order to get buttons to display text.
// In this code the emulator is accounted for with the 'title' parameter, but in other channels you may
// need to provide a value for other parameters like 'text' or 'displayText'.
new CardAction(ActionTypes.ImBack, title: "1. Inline Attachment", value: "1"),
new CardAction(ActionTypes.ImBack, title: "2. Internet Attachment", value: "2"),
new CardAction(ActionTypes.ImBack, title: "3. Uploaded Attachment", value: "3"),
},
};
var reply = MessageFactory.Attachment(card.ToAttachment());
await turnContext.SendActivityAsync(reply, cancellationToken);
Pokud chcete vytvořit zprávu s kartou a tlačítkem hrdiny, můžete k zprávě připojit HeroCard objekt.
* @param {Object} turnContext
*/
async displayOptions(turnContext) {
const reply = { type: ActivityTypes.Message };
// Note that some channels require different values to be used in order to get buttons to display text.
// In this code the emulator is accounted for with the 'title' parameter, but in other channels you may
// need to provide a value for other parameters like 'text' or 'displayText'.
const buttons = [
{ type: ActionTypes.ImBack, title: '1. Inline Attachment', value: '1' },
{ type: ActionTypes.ImBack, title: '2. Internet Attachment', value: '2' },
{ type: ActionTypes.ImBack, title: '3. Uploaded Attachment', value: '3' }
];
const card = CardFactory.heroCard('', undefined,
buttons, { text: 'You can upload an image or select one of the following choices.' });
reply.attachments = [card];
Pokud chcete vytvořit zprávu s kartou a tlačítkem hrdiny, můžete k zprávě připojit HeroCard objekt.
private static CompletableFuture<Void> displayOptions(TurnContext turnContext) {
// Create a HeroCard with options for the user to interact with the bot.
HeroCard card = new HeroCard();
card.setText("You can upload an image or select one of the following choices");
// Note that some channels require different values to be used in order to get buttons to display text.
// In this code the emulator is accounted for with the 'title' parameter, but in other channels you may
// need to provide a value for other parameters like 'text' or 'displayText'.
card.setButtons(
new CardAction(ActionTypes.IM_BACK, "1. Inline Attachment", "1"),
new CardAction(ActionTypes.IM_BACK, "2. Internet Attachment", "2"),
new CardAction(ActionTypes.IM_BACK, "3. Uploaded Attachment", "3")
);
Activity reply = MessageFactory.attachment(card.toAttachment());
return turnContext.sendActivity(reply).thenApply(resourceResponse -> null);
}
Pokud chcete vytvořit zprávu s kartou a tlačítkem hrdiny, můžete k zprávě připojit HeroCard objekt.
async def _display_options(self, turn_context: TurnContext):
"""
Create a HeroCard with options for the user to interact with the bot.
:param turn_context:
:return:
"""
# Note that some channels require different values to be used in order to get buttons to display text.
# In this code the emulator is accounted for with the 'title' parameter, but in other channels you may
# need to provide a value for other parameters like 'text' or 'displayText'.
card = HeroCard(
text="You can upload an image or select one of the following choices",
buttons=[
CardAction(
type=ActionTypes.im_back, title="1. Inline Attachment", value="1"
),
CardAction(
type=ActionTypes.im_back, title="2. Internet Attachment", value="2"
),
CardAction(
type=ActionTypes.im_back, title="3. Uploaded Attachment", value="3"
),
],
)
Zpracování událostí v rámci karet s bohatými funkcemi
Pokud chcete zpracovávat události na kartách s bohatými obsahy, pomocí objektů akcí karty určete, co se má stát, když uživatel vybere tlačítko nebo klepne na oddíl karty. Každá akce karty má vlastnost typu a hodnoty .
Chcete-li správně fungovat, přiřaďte každému kliknutí na kartu hrdiny typ akce. Tato tabulka uvádí a popisuje dostupné typy akcí a to, co by mělo být ve vlastnosti přidružené hodnoty.
Akce messageBack karty má obecnější význam než ostatní akce karty. Další informace o typech messageBack akcí karty najdete v části Akce Karta schématu aktivity.
Typ
Popis
Hodnota
call
Zahájí telefonní hovor.
Cíl pro telefonní hovor v tomto formátu: tel:123123123123.
downloadFile
Stáhne soubor.
Adresa URL souboru, který chcete stáhnout.
imBack
Odešle robotovi zprávu a publikuje viditelnou odpověď v chatu.
Text zprávy, kterou chcete odeslat.
messageBack
Představuje textovou odpověď, která se má odeslat prostřednictvím chatovacího systému.
Volitelná programová hodnota, která se má zahrnout do vygenerovaných zpráv.
openUrl
Otevře adresu URL v integrovaném prohlížeči.
Adresa URL, která se má otevřít.
playAudio
Přehraje zvuk.
Adresa URL zvuku, který se má přehrát.
playVideo
Přehraje video.
Adresa URL videa, která se má přehrát.
postBack
Odešle robotovi zprávu a nemusí v chatu publikovat viditelnou odpověď.
Text zprávy, kterou chcete odeslat.
showImage
Zobrazí obrázek.
Adresa URL obrázku, který se má zobrazit.
signin
Zahájí proces přihlášení OAuth.
Adresa URL toku OAuth, který se má zahájit.
Karta Hero s využitím různých typů událostí
Následující kód ukazuje příklady použití různých událostí s bohatými kartami.
Příklady všech dostupných karet najdete v ukázce Používání karet .
Cards.cs
public static HeroCard GetHeroCard()
{
var heroCard = new HeroCard
{
Title = "BotFramework Hero Card",
Subtitle = "Microsoft Bot Framework",
Text = "Build and connect intelligent bots to interact with your users naturally wherever they are," +
" from text/sms to Skype, Slack, Office 365 mail and other popular services.",
Images = new List<CardImage> { new CardImage("https://sec.ch9.ms/ch9/7ff5/e07cfef0-aa3b-40bb-9baa-7c9ef8ff7ff5/buildreactionbotframework_960.jpg") },
Buttons = new List<CardAction> { new CardAction(ActionTypes.OpenUrl, "Get Started", value: "https://docs.microsoft.com/bot-framework") },
};
return heroCard;
}
Cards.cs
public static SigninCard GetSigninCard()
{
var signinCard = new SigninCard
{
Text = "BotFramework Sign-in Card",
Buttons = new List<CardAction> { new CardAction(ActionTypes.Signin, "Sign-in", value: "https://login.microsoftonline.com/") },
};
return signinCard;
}
Příklady všech dostupných karet najdete v ukázce Používání karet .
createOAuthCard() {
return CardFactory.oauthCard(
'OAuth connection', // Replace with the name of your Azure AD connection
'Sign In',
'BotFramework OAuth Card'
);
}
Příklady všech dostupných karet najdete v ukázce Používání karet .
Cards.java
public static HeroCard getHeroCard() {
HeroCard heroCard = new HeroCard();
heroCard.setTitle("BotFramework Hero Card");
heroCard.setSubtitle("Microsoft Bot Framework");
heroCard.setText("Build and connect intelligent bots to interact with your users naturally wherever they are," +
" from text/sms to Skype, Slack, Office 365 mail and other popular services.");
heroCard.setImages(new CardImage("https://sec.ch9.ms/ch9/7ff5/e07cfef0-aa3b-40bb-9baa-7c9ef8ff7ff5/buildreactionbotframework_960.jpg"));
heroCard.setButtons(new CardAction(ActionTypes.OPEN_URL, "Get Started", "https://docs.microsoft.com/bot-framework"));
return heroCard;
}
Cards.java
public static SigninCard getSigninCard() {
SigninCard signinCard = new SigninCard();
signinCard.setText("BotFramework Sign-in Card");
signinCard.setButtons(new CardAction(ActionTypes.SIGNIN, "Sign-in", "https://login.microsoftonline.com/"));
return signinCard;
}
Příklady všech dostupných karet najdete v ukázce Používání karet .
def create_oauth_card(self) -> Attachment:
card = OAuthCard(
text="BotFramework OAuth Card",
connection_name="OAuth connection", # Replace it with the name of your Azure AD connection.
buttons=[
CardAction(
type=ActionTypes.signin,
title="Sign in",
value="https://example.org/signin",
)
],
)
return CardFactory.oauth_card(card)
Odeslání adaptivní karty
I když můžete pomocí objektu pro vytváření zpráv vytvořit zprávu, která obsahuje přílohu (libovolného druhu), adaptivní karta je jedním konkrétním typem přílohy. Ne všechny kanály podporují adaptivní karty a některé kanály můžou adaptivní karty podporovat pouze částečně. Pokud například pošlete adaptivní kartu na Facebooku, tlačítka nebudou fungovat, zatímco texty a obrázky dobře fungují. Objekt pro vytváření zpráv je pomocná třída sady SDK služby Bot Framework, která se používá k automatizaci kroků vytváření za vás.
Adaptivní karty jsou otevřený formát výměny karet, který umožňuje vývojářům vyměňovat si obsah uživatelského rozhraní běžným a konzistentním způsobem. Ne všechny kanály však podporují adaptivní karty.
Návrhář adaptivních karet poskytuje bohaté interaktivní prostředí pro navrhování adaptivních karet.
Poznámka:
Tuto funkci byste měli otestovat pomocí kanálů, které robot použije k určení, jestli tyto kanály podporují adaptivní karty.
Následující zdrojový kód pochází z ukázky using karet .
Dialogy/MainDialog.cs
Nejprve vytvořte odpověď a definujte přílohy jako seznam.
// Cards are sent as Attachments in the Bot Framework.
// So we need to create a list of attachments for the reply activity.
var attachments = new List<Attachment>();
// Reply to the activity we received with an activity.
var reply = MessageFactory.Attachment(attachments);
Pak přidejte přílohy a nastavte typ rozložení na karusel.
Tady je přidáváme po jednom, ale můžete s ním manipulovat a přidat karty, které dáváte přednost.
// Display a carousel of all the rich card types.
reply.AttachmentLayout = AttachmentLayoutTypes.Carousel;
reply.Attachments.Add(Cards.CreateAdaptiveCardAttachment());
reply.Attachments.Add(Cards.GetAnimationCard().ToAttachment());
reply.Attachments.Add(Cards.GetAudioCard().ToAttachment());
reply.Attachments.Add(Cards.GetHeroCard().ToAttachment());
reply.Attachments.Add(Cards.GetOAuthCard().ToAttachment());
reply.Attachments.Add(Cards.GetReceiptCard().ToAttachment());
reply.Attachments.Add(Cards.GetSigninCard().ToAttachment());
reply.Attachments.Add(Cards.GetThumbnailCard().ToAttachment());
reply.Attachments.Add(Cards.GetVideoCard().ToAttachment());
Po přidání příloh můžete odpověď odeslat stejně jako jakoukoli jinou.
// Send the card(s) to the user as an attachment to the activity
await stepContext.Context.SendActivityAsync(reply, cancellationToken);
Následující zdrojový kód pochází z ukázky using karet .
dialogy/mainDialog.js
Přidejte přílohy a nastavte typ rozložení na karusel.
Po přidání příloh můžete odpověď odeslat stejně jako jakoukoli jinou.
Následující zdrojový kód pochází z ukázky using karet .
MainDialog.java
Nejprve vytvořte odpověď a definujte přílohy jako seznam.
// Cards are sent as Attachments in the Bot Framework.
// So we need to create a list of attachments for the reply activity.
List<Attachment> attachments = new ArrayList<>();
// Reply to the activity we received with an activity.
Activity reply = MessageFactory.attachment(attachments);
Pak přidejte přílohy a nastavte typ rozložení na karusel.
Tady je přidáváme po jednom, ale můžete s ním manipulovat a přidat karty, které dáváte přednost.
// Display a carousel of all the rich card types.
reply.setAttachmentLayout(AttachmentLayoutTypes.CAROUSEL);
reply.getAttachments().add(Cards.createAdaptiveCardAttachment());
reply.getAttachments().add(Cards.getAnimationCard().toAttachment());
reply.getAttachments().add(Cards.getAudioCard().toAttachment());
reply.getAttachments().add(Cards.getHeroCard().toAttachment());
reply.getAttachments().add(Cards.getOAuthCard().toAttachment());
reply.getAttachments().add(Cards.getReceiptCard().toAttachment());
reply.getAttachments().add(Cards.getSigninCard().toAttachment());
reply.getAttachments().add(Cards.getThumbnailCard().toAttachment());
reply.getAttachments().add(Cards.getVideoCard().toAttachment());
Po přidání příloh můžete odpověď odeslat stejně jako jakoukoli jinou.
// Send the card(s) to the user as an attachment to the activity
return stepContext.getContext().sendActivity(reply)
Nejprve vytvořte odpověď a definujte přílohy jako seznam.
reply = MessageFactory.list([])
Pak přidejte přílohy a nastavte typ rozložení na karusel.
Tady je přidáváme po jednom, ale můžete s ním manipulovat a přidat karty, které dáváte přednost.
Po přidání příloh můžete odpověď odeslat stejně jako jakoukoli jinou.
# Send the card(s) to the user as an attachment to the activity
await step_context.context.send_activity(reply)
Ukázka kódu pro zpracování vstupu adaptivní karty
Následující ukázka ukazuje jeden ze způsobů použití vstupů adaptivní karty v rámci třídy dialogového okna robota.
Rozšíří ukázku karet hero ověřením vstupu přijatého v textovém poli z reagujícího klienta.
Nejdřív je potřeba přidat funkci textového vstupu a tlačítka do existující adaptivní karty tak, že přidáte následující kód těsně před poslední hranatá závorka adaptiveCard.json, která se nachází ve složce prostředků:
ID textového vstupního pole je nastavené na text. Když uživatel vybere OK, zpráva, kterou adaptivní karta vygeneruje, bude mít hodnotu vlastnost s názvem text , která obsahuje informace, které uživatel zadal do textového vstupního pole karty.
Náš validátor používá Newtonsoft.json k prvnímu převodu na a JObjectpotom vytvoří oříznutý textový řetězec pro porovnání. Proto přidejte:
using System;
using System.Linq;
using Newtonsoft.Json.Linq;
pro MainDialog.cs a instalaci nejnovějšího stabilního balíčku NuGet newtonsoft.json.
V kódu validátoru jsme do komentářů ke kódu přidali tok logiky.
Tato ChoiceValidator metoda je umístěna do vzorku Using karty těsně po uzavřené složené závorce pro deklaraci MainDialog:
private async Task ChoiceValidator(
PromptValidatorContext promptContext,
CancellationToken cancellationToken)
{
// Retrieves Adaptive Card comment text as JObject.
// looks for JObject field "text" and converts that input into a trimmed text string.
var jobject = promptContext.Context.Activity.Value as JObject;
var jtoken = jobject?["text"];
var text = jtoken?.Value().Trim();
// Logic: 1. if succeeded = true, just return promptContext
// 2. if false, see if JObject contained Adaptive Card input.
// No = (bad input) return promptContext
// Yes = update Value field with JObject text string, return "true".
if (!promptContext.Recognized.Succeeded && text != null)
{
var choice = promptContext.Options.Choices.FirstOrDefault(
c => c.Value.Equals(text, StringComparison.InvariantCultureIgnoreCase));
if (choice != null)
{
promptContext.Recognized.Value = new FoundChoice
{
Value = choice.Value,
};
return true;
}
}
return promptContext.Recognized.Succeeded;
}
Teď nad změnou MainDialog deklarace:
// Define the main dialog and its related components.
AddDialog(new ChoicePrompt(nameof(ChoicePrompt)));
na:
// Define the main dialog and its related components.
AddDialog(new ChoicePrompt(nameof(ChoicePrompt), ChoiceValidator));
Tím se vyvolá validátor, který bude hledat vstup adaptivní karty při každém vytvoření nové výzvy k volbě.
Otevřete mainDialog.js a vyhledejte metodu async run(turnContext, accessor) spuštění. Tato metoda zpracovává příchozí aktivitu.
Hned po volání dialogSet.add(this); přidejte následující:
// The following check looks for a non-existent text input
// plus Adaptive Card input in _activity.value.text
// If both conditions exist, the Activity Card text
// is copied into the text input field.
if(turnContext._activity.text == null
&& turnContext._activity.value.text != null) {
this.logger.log('replacing null text with Activity Card text input');
turnContext._activity.text = turnContext._activity.value.text;
}
Pokud tato kontrola najde neexistující textový vstup z klienta, zdá se, že existuje vstup z adaptivní karty.
Pokud vstup adaptivní karty existuje, _activity.value.textzkopíruje ho do normálního textového vstupního pole.
Náš validátor používá pomocné rutiny serializace z com.microsoft.bot.schema k prvnímu převodu na a JsonNodepak vytvořit oříznutý textový řetězec pro porovnání. K dokončení tohoto importu budeme potřebovat také několik dalších importů, takže přidejte:
MainDialog.java.
V kódu validátoru jsme do komentářů ke kódu přidali tok logiky.
Tento PromptValidator výraz se umístí do vzorku Using karet hned po uzavřené závorce veřejné pro deklaraci MainDialogu:
PromptValidator<FoundChoice> validator = (promptContext) -> {
// Retrieves Adaptive Card comment text as JObject.
// looks for JObject field "text" and converts that input into a trimmed text
// string.
JsonNode jsonNode = Serialization.getAs(promptContext.getContext().getActivity().getValue(), JsonNode.class);
JsonNode textNode = jsonNode != null ? jsonNode.get("text") : null;
String text = textNode != null ? textNode.textValue() : "";
// Logic: 1. if succeeded = true, just return promptContext
// 2. if false, see if JObject contained Adaptive Card input.
// No = (bad input) return promptContext
// Yes = update Value field with JObject text string, return "true".
if (!promptContext.getRecognized().getSucceeded() && text != null) {
Optional<Choice> choice = promptContext.getOptions()
.getChoices()
.stream()
.filter(c -> StringUtils.compareIgnoreCase(c.getValue(), text) == 0)
.findFirst();
if (choice.isPresent()) {
promptContext.getRecognized().setValue(new FoundChoice() {
{
setValue(choice.get().getValue());
}
});
return CompletableFuture.completedFuture(true);
}
}
return CompletableFuture.completedFuture(promptContext.getRecognized().getSucceeded());
};
Teď nad změnou MainDialog deklarace:
// Define the main dialog and its related components.
addDialog(new ChoicePrompt("ChoicePrompt"));
na:
// Define the main dialog and its related components.
addDialog(new ChoicePrompt("ChoicePrompt", validator, null));
Tím se vyvolá validátor, který bude hledat vstup adaptivní karty při každém vytvoření nové výzvy k volbě.
Vytvořte a odešlete uživateli aktivitu s navrhovanými akcemi.
Tato choice_validator metoda je umístěna do vzorku Using karty těsně po uzavřené závorce veřejné pro deklaraci MainDialog:
@staticmethod
async def choice_validator(prompt_context: PromptValidatorContext) -> bool:
if prompt_context.context.activity.value:
text = prompt_context.context.activity.value["text"].lower()
if not prompt_context.recognized.succeeded and text:
matching_choices = [choice for choice in prompt_context.options.choices if choice.value.lower() == text]
if matching_choices:
choice = matching_choices[0]
prompt_context.recognized.value = FoundChoice(
value=choice.value,
index=0,
score=1.0
)
return True
return prompt_context.recognized.succeeded