Wysyłanie załączników multimediów za pomocą zestawu Bot Framework SDK
Artykuł
DOTYCZY: ZESTAW SDK w wersji 4
Komunikaty wymieniane między użytkownikiem a botem mogą zawierać załączniki multimediów, takie jak obrazy, wideo, dźwięk i pliki. Zestaw SDK platformy Bot Framework obsługuje zadanie wysyłania rozbudowanych komunikatów do użytkownika. Aby określić typ zaawansowanych wiadomości, które obsługuje kanał (Facebook, Slack itd.), zapoznaj się z dokumentacją kanału, aby uzyskać informacje o ograniczeniach.
Uwaga
Zestawy SDK języka JavaScript, C# i Python platformy Bot Framework będą nadal obsługiwane, jednak zestaw SDK języka Java jest wycofywany z ostatecznym długoterminowym wsparciem kończącym się w listopadzie 2023 r.
Istniejące boty utworzone za pomocą zestawu JAVA SDK będą nadal działać.
Cały kod źródłowy pokazany w tej sekcji jest oparty na przykładzie Obsługa załączników .
Właściwość AttachmentsActivity obiektu zawiera tablicę Attachment obiektów reprezentujących załączniki multimediów i rozbudowane karty dołączone do wiadomości. Aby dodać załącznik multimediów do wiadomości, utwórz Attachment obiekt dla reply działania i ustaw ContentTypewłaściwości , ContentUrli Name .
Aby utworzyć wiadomość odpowiedzi, zdefiniuj tekst, a następnie skonfiguruj załączniki. Przypisywanie załączników do odpowiedzi jest takie samo dla każdego typu załącznika, jednak różne załączniki są konfigurowane i definiowane inaczej, jak pokazano w poniższych fragmentach kodu. Poniższy kod konfiguruje odpowiedź dla wbudowanego załącznika:
Boty/AttachmentsBot.cs
{
reply = MessageFactory.Text("This is an inline attachment.");
Następnie przyjrzymy się typom załączników. Najpierw jest załącznik wbudowany:
Boty/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}",
};
}
Następnie przekazany załącznik:
Boty/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,
};
}
Na koniec załącznik internetowy:
Boty/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",
};
}
}
Aby utworzyć wiadomość odpowiedzi, zdefiniuj tekst, a następnie skonfiguruj załączniki. Przypisywanie załączników do odpowiedzi jest takie samo dla każdego typu załącznika, jednak różne załączniki są konfigurowane i definiowane inaczej, jak pokazano w poniższych fragmentach kodu. Poniższy kod konfiguruje odpowiedź dla wbudowanego załącznika:
boty/attachmentsBot.js
*/
const firstChar = turnContext.activity.text[0];
if (firstChar === '1') {
Aby wysłać użytkownikowi pojedynczą zawartość, na przykład obraz lub film wideo, możesz wysłać multimedia na kilka różnych sposobów. Najpierw jako załącznik wbudowany:
Na koniec załącznik internetowy zawarty w adresie URL:
boty/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'
Kod źródłowy pokazany w tej sekcji jest oparty na przykładzie Obsługa załączników .
Metoda getAttachments()Activity obiektu zawiera tablicę Attachment obiektów reprezentujących załączniki multimediów i rozbudowane karty dołączone do wiadomości. Aby dodać załącznik multimediów do wiadomości, utwórz Attachment obiekt dla reply działania i ustaw ContentTypewłaściwości , ContentUrli Name .
Aby utworzyć wiadomość odpowiedzi, zdefiniuj tekst, a następnie skonfiguruj załączniki. Przypisywanie załączników do odpowiedzi jest takie samo dla każdego typu załącznika, jednak różne załączniki są konfigurowane i definiowane inaczej, jak pokazano w poniższych fragmentach kodu. Poniższy kod konfiguruje odpowiedź dla wbudowanego załącznika:
AttachmentsBot.java
result = getInlineAttachment()
.thenApply(attachment -> {
Activity reply = MessageFactory.text("This is an inline attachment.");
reply.setAttachment(attachment);
return reply;
});
Następnie przyjrzymy się typom załączników. Najpierw jest załącznik wbudowany:
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;
}
Aby utworzyć wiadomość odpowiedzi, zdefiniuj tekst, a następnie skonfiguruj załączniki. Przypisywanie załączników do odpowiedzi jest takie samo dla każdego typu załącznika, jednak różne załączniki są konfigurowane i definiowane inaczej, jak pokazano w poniższych fragmentach kodu.
Poniższy kod konfiguruje odpowiedź dla wbudowanego załącznika:
boty/attachments_bot.py
reply.text = "This is an inline attachment."
reply.attachments = [self._get_inline_attachment()]
Aby wysłać użytkownikowi pojedynczą zawartość, na przykład obraz lub film wideo, możesz wysłać multimedia na kilka różnych sposobów. Najpierw jako załącznik wbudowany:
boty/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}",
)
Następnie przekazany załącznik:
boty/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,
)
Na koniec załącznik internetowy zawarty w adresie URL:
boty/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",
)
Jeśli załącznik jest obrazem, dźwiękiem lub wideo, usługa łącznika przekaże dane załącznika do kanału w sposób umożliwiający kanał renderowanie tego załącznika w konwersacji. Jeśli załącznik jest plikiem, adres URL pliku będzie renderowany jako hiperlink w konwersacji.
Wysyłanie karty bohatera
Oprócz prostych obrazów lub załączników wideo można dołączyć kartę bohatera, która umożliwia łączenie obrazów i przycisków w jednym obiekcie i wysyłanie ich do użytkownika. Język Markdown jest obsługiwany w przypadku większości pól tekstowych, ale obsługa może się różnić w zależności od kanału.
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);
Aby utworzyć wiadomość za pomocą karty bohatera i przycisku, możesz dołączyć HeroCard obiekt do wiadomości.
* @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];
Aby utworzyć wiadomość za pomocą karty bohatera i przycisku, możesz dołączyć HeroCard obiekt do wiadomości.
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);
}
Aby utworzyć wiadomość za pomocą karty bohatera i przycisku, możesz dołączyć HeroCard obiekt do wiadomości.
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"
),
],
)
Przetwarzanie zdarzeń na kartach bogatych
Aby przetworzyć zdarzenia na kartach bogatych, użyj obiektów akcji karty, aby określić, co powinno się zdarzyć, gdy użytkownik wybierze przycisk lub naciśnij sekcję karty. Każda akcja karty ma właściwość typu i wartości .
Aby prawidłowo działać, przypisz typ akcji do każdego elementu, który można kliknąć na karcie bohatera. W tej tabeli wymieniono i opisano dostępne typy akcji oraz właściwości, które powinny znajdować się we skojarzonej właściwości wartości.
Akcja messageBack karty ma bardziej uogólnione znaczenie niż inne akcje karty. Aby uzyskać więcej informacji na temat messageBack i innych typów akcji kart, zobacz sekcję Akcja karty schematu działania.
Type
Opis
Wartość
call
Inicjuje połączenie telefoniczne.
Miejsce docelowe połączenia telefonicznego w tym formacie: tel:123123123123.
downloadFile
Pobiera plik.
Adres URL pliku do pobrania.
imBack
Wysyła wiadomość do bota i publikuje widoczną odpowiedź na czacie.
Tekst wiadomości do wysłania.
messageBack
Reprezentuje odpowiedź tekstową, która ma zostać wysłana za pośrednictwem systemu czatów.
Opcjonalna wartość programowa do uwzględnienia w wygenerowanych komunikatach.
openUrl
Otwiera adres URL w wbudowanej przeglądarce.
Adres URL do otwarcia.
playAudio
Odtwarza dźwięk.
Adres URL dźwięku do odtwarzania.
playVideo
Odtwarza wideo.
Adres URL wideo do odtwarzania.
postBack
Wysyła wiadomość do bota i może nie publikować widocznej odpowiedzi na czacie.
Tekst wiadomości do wysłania.
showImage
Wyświetla obraz.
Adres URL obrazu do wyświetlenia.
signin
Inicjuje proces logowania OAuth.
Adres URL przepływu OAuth do zainicjowania.
Karta bohatera korzystająca z różnych typów zdarzeń
Poniższy kod przedstawia przykłady z użyciem różnych zaawansowanych zdarzeń kart.
Przykłady wszystkich dostępnych kart można znaleźć w przykładzie Korzystanie z kart .
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;
}
Przykłady wszystkich dostępnych kart można znaleźć w przykładzie Korzystanie z kart .
createOAuthCard() {
return CardFactory.oauthCard(
'OAuth connection', // Replace with the name of your Azure AD connection
'Sign In',
'BotFramework OAuth Card'
);
}
Przykłady wszystkich dostępnych kart można znaleźć w przykładzie Korzystanie z kart .
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;
}
Przykłady wszystkich dostępnych kart można znaleźć w przykładzie Korzystanie z kart .
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)
Wysyłanie karty adaptacyjnej
Chociaż możesz użyć fabryki komunikatów do utworzenia komunikatu zawierającego załącznik (dowolnego rodzaju), karta adaptacyjna jest jednym konkretnym typem załącznika. Nie wszystkie kanały obsługują karty adaptacyjne, a niektóre kanały mogą obsługiwać tylko częściowo karty adaptacyjne. Jeśli na przykład wyślesz kartę adaptacyjną na Facebooku, przyciski nie będą działać, gdy teksty i obrazy będą działać dobrze. Fabryka komunikatów to klasa pomocnika zestawu SDK platformy Bot Framework używana do automatyzowania kroków tworzenia.
Karty adaptacyjne to format wymiany kart otwartych, umożliwiający deweloperom spójną i spójną wymianę zawartości interfejsu użytkownika. Jednak nie wszystkie kanały obsługują karty adaptacyjne.
Projektant kart adaptacyjnych zapewnia zaawansowane, interaktywne środowisko projektowania kart adaptacyjnych.
Uwaga
Należy przetestować tę funkcję za pomocą kanałów używanych przez bota, aby określić, czy te kanały obsługują karty adaptacyjne.
Poniższy kod źródłowy pochodzi z przykładu Używanie kart .
Okna dialogowe/MainDialog.cs
Najpierw utwórz odpowiedź i zdefiniuj załączniki jako listę.
// 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);
Następnie dodaj załączniki i ustaw typ układu na karuzeli.
W tym miejscu dodajemy je pojedynczo, ale możesz manipulować listą, aby dodać karty, jednak wolisz.
// 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 dodaniu załączników możesz wysłać odpowiedź tak samo jak każda inna.
// Send the card(s) to the user as an attachment to the activity
await stepContext.Context.SendActivityAsync(reply, cancellationToken);
Poniższy kod źródłowy pochodzi z przykładu Używanie kart .
okna dialogowe/mainDialog.js
Dodaj załączniki i ustaw typ układu na karuzeli.
Po dodaniu załączników możesz wysłać odpowiedź tak samo jak każda inna.
Poniższy kod źródłowy pochodzi z przykładu Używanie kart .
MainDialog.java
Najpierw utwórz odpowiedź i zdefiniuj załączniki jako listę.
// 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);
Następnie dodaj załączniki i ustaw typ układu na karuzeli.
W tym miejscu dodajemy je pojedynczo, ale możesz manipulować listą, aby dodać karty, jednak wolisz.
// 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 dodaniu załączników możesz wysłać odpowiedź tak samo jak każda inna.
// Send the card(s) to the user as an attachment to the activity
return stepContext.getContext().sendActivity(reply)
Kod źródłowy pokazany tutaj jest oparty na przykładzie Używanie kart .
okna dialogowe/main_dialog.py
Najpierw utwórz odpowiedź i zdefiniuj załączniki jako listę.
reply = MessageFactory.list([])
Następnie dodaj załączniki i ustaw typ układu na karuzeli.
W tym miejscu dodajemy je pojedynczo, ale możesz manipulować listą, aby dodać karty, jednak wolisz.
Po dodaniu załączników możesz wysłać odpowiedź tak samo jak każda inna.
# Send the card(s) to the user as an attachment to the activity
await step_context.context.send_activity(reply)
Przykład kodu do przetwarzania danych wejściowych karty adaptacyjnej
Poniższy przykład przedstawia jeden ze sposobów użycia danych wejściowych karty adaptacyjnej w klasie okna dialogowego bota.
Rozszerza przykładowe karty hero, sprawdzając dane wejściowe odebrane w polu tekstowym od odpowiadającego klienta.
Najpierw należy dodać funkcję wprowadzania tekstu i przycisku do istniejącej karty adaptacyjnej, dodając następujący kod tuż przed ostatnim nawiasem adaptiveCard.json znajdującym się w folderze resources:
Identyfikator pola wprowadzania tekstu jest ustawiony na "tekst". Gdy użytkownik wybierze przycisk OK, komunikat Wygenerowana karta adaptacyjna będzie zawierać właściwość wartości o nazwie text zawierającą informacje wprowadzone przez użytkownika w polu wprowadzania tekstu karty.
Nasz moduł sprawdzania poprawności używa Newtonsoft.json , aby najpierw przekonwertować go na JObjectelement , a następnie utworzyć przycięty ciąg tekstowy do porównania. Dodaj więc:
using System;
using System.Linq;
using Newtonsoft.Json.Linq;
aby MainDialog.cs i zainstalować najnowszy stabilny pakiet NuGet Newtonsoft.Json.
W kodzie modułu sprawdzania poprawności dodaliśmy przepływ logiki do komentarzy kodu.
Ta ChoiceValidator metoda jest umieszczana w przykładzie Using cards tuż po publicznie zamkniętego nawiasu klamrowego dla deklaracji 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;
}
Teraz powyżej w deklaracji MainDialog zmień:
// 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));
Spowoduje to wywołanie modułu sprawdzania poprawności w celu wyszukania danych wejściowych karty adaptacyjnej za każdym razem, gdy zostanie utworzony nowy monit o wybór.
Otwórz mainDialog.js i znajdź metodę run Ta metoda async run(turnContext, accessor) obsługuje działanie przychodzące.
Tuż po wywołaniu dialogSet.add(this); dodaj następujące elementy:
// 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;
}
Jeśli to sprawdzenie znajdzie nieistniejące dane wejściowe tekstowe od klienta, wygląda na to, że istnieją dane wejściowe z karty adaptacyjnej.
Jeśli w obiekcie istnieje _activity.value.textdane wejściowe karty adaptacyjnej, kopiuje je do normalnego pola wprowadzania tekstu.
Nasz moduł sprawdzania poprawności używa pomocnika serializacji z witryny com.microsoft.bot.schema, aby najpierw przekonwertować go na JsonNodeelement , a następnie utworzyć przycięty ciąg tekstowy do porównania. Aby ukończyć ten proces, będziemy również potrzebować kilku innych importów, więc dodaj następujące elementy:
MainDialog.java.
W kodzie modułu sprawdzania poprawności dodaliśmy przepływ logiki do komentarzy kodu.
To PromptValidator wyrażenie jest umieszczane w przykładzie Using cards tuż po zamkniętym nawiasie klamrowym publicznym deklaracji MainDialog:
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());
};
Teraz powyżej w deklaracji MainDialog zmień:
// 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));
Spowoduje to wywołanie modułu sprawdzania poprawności w celu wyszukania danych wejściowych karty adaptacyjnej za każdym razem, gdy zostanie utworzony nowy monit o wybór.
Tworzenie i wysyłanie działania z sugerowanymi akcjami do użytkownika.
Ta choice_validator metoda jest umieszczana w przykładzie Using cards tuż po publicznie zamkniętego nawiasu klamrowego dla deklaracji 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
Spowoduje to wywołanie modułu sprawdzania poprawności w celu wyszukania danych wejściowych karty adaptacyjnej za każdym razem, gdy zostanie utworzony nowy monit o wybór.
Testowanie bota używającego kart
Uruchom przykładowe karty Using (Używanie kart) lokalnie i otwórz bota w aplikacji Bot Framework Emulator.
Postępuj zgodnie z monitami bota, aby wyświetlić typ karty, taki jak karta adaptacyjna.