Berichten die worden uitgewisseld tussen gebruikers en bot, kunnen mediabijlagen bevatten, zoals afbeeldingen, video, audio en bestanden. De Bot Framework SDK ondersteunt de taak van het verzenden van uitgebreide berichten naar de gebruiker. Raadpleeg de documentatie van het kanaal voor informatie over beperkingen om te bepalen welk type rich messages een kanaal (Facebook, Slack, enzovoort) ondersteunt.
Notitie
De Sdk's voor Bot Framework JavaScript, C# en Python blijven ondersteund, maar de Java SDK wordt buiten gebruik gesteld met definitieve langetermijnondersteuning die eindigt op november 2023.
Bestaande bots die zijn gebouwd met de Java SDK blijven functioneren.
De Attachments eigenschap van het Activity object bevat een matrix met Attachment objecten die de mediabijlagen en uitgebreide kaarten vertegenwoordigen die aan het bericht zijn gekoppeld. Als u een mediabijlage wilt toevoegen aan een bericht, maakt u een Attachment object voor de reply activiteit en stelt u de ContentType, ContentUrlen Name eigenschappen in.
Als u het antwoordbericht wilt maken, definieert u de tekst en stelt u de bijlagen in. Het toewijzen van de bijlagen aan het antwoord is hetzelfde voor elk bijlagetype, maar de verschillende bijlagen worden anders ingesteld en gedefinieerd, zoals te zien is in de volgende fragmenten. Met de onderstaande code wordt het antwoord voor een inlinebijlage ingesteld:
Bots/AttachmentsBot.cs
{
reply = MessageFactory.Text("This is an inline attachment.");
Vervolgens kijken we naar de typen bijlagen. Eerst is een inlinebijlage:
Bots/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}",
};
}
Vervolgens een geüploade bijlage:
Bots/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,
};
}
Ten slotte: een internetbijlage:
Bots/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",
};
}
}
Als u het antwoordbericht wilt maken, definieert u de tekst en stelt u de bijlagen in. Het toewijzen van de bijlagen aan het antwoord is hetzelfde voor elk bijlagetype, maar de verschillende bijlagen worden anders ingesteld en gedefinieerd, zoals te zien is in de volgende fragmenten. Met de onderstaande code wordt het antwoord voor een inlinebijlage ingesteld:
bots/attachmentsBot.js
*/
const firstChar = turnContext.activity.text[0];
if (firstChar === '1') {
Als u de gebruiker één deel van de inhoud, zoals een afbeelding of een video, wilt verzenden, kunt u media op verschillende manieren verzenden. Ten eerste, als een inlinebijlage:
* 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'
De getAttachments() methode van het Activity object bevat een matrix met Attachment objecten die de mediabijlagen en uitgebreide kaarten vertegenwoordigen die aan het bericht zijn gekoppeld. Als u een mediabijlage wilt toevoegen aan een bericht, maakt u een Attachment object voor de reply activiteit en stelt u de ContentType, ContentUrlen Name eigenschappen in.
Als u het antwoordbericht wilt maken, definieert u de tekst en stelt u de bijlagen in. Het toewijzen van de bijlagen aan het antwoord is hetzelfde voor elk bijlagetype, maar de verschillende bijlagen worden anders ingesteld en gedefinieerd, zoals te zien is in de volgende fragmenten. Met de onderstaande code wordt het antwoord voor een inlinebijlage ingesteld:
AttachmentsBot.java
result = getInlineAttachment()
.thenApply(attachment -> {
Activity reply = MessageFactory.text("This is an inline attachment.");
reply.setAttachment(attachment);
return reply;
});
Vervolgens kijken we naar de typen bijlagen. Eerst is een inlinebijlage:
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;
}
Als u het antwoordbericht wilt maken, definieert u de tekst en stelt u de bijlagen in. Het toewijzen van de bijlagen aan het antwoord is hetzelfde voor elk bijlagetype, maar de verschillende bijlagen worden anders ingesteld en gedefinieerd, zoals te zien is in de volgende fragmenten.
Met de onderstaande code wordt het antwoord voor een inlinebijlage ingesteld:
bots/attachments_bot.py
reply.text = "This is an inline attachment."
reply.attachments = [self._get_inline_attachment()]
Als u de gebruiker één deel van de inhoud, zoals een afbeelding of een video, wilt verzenden, kunt u media op verschillende manieren verzenden. Ten eerste, als een inlinebijlage:
bots/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}",
)
Vervolgens een geüploade bijlage:
bots/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,
)
Ten slotte bevat een internetbijlage in een URL:
bots/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",
)
Als een bijlage een afbeelding, audio of video is, communiceert de connectorservice bijlagegegevens naar het kanaal op een manier die het kanaal in staat stelt om die bijlage in het gesprek weer te geven. Als de bijlage een bestand is, wordt de bestands-URL weergegeven als hyperlink in het gesprek.
Een herokaart verzenden
Naast eenvoudige afbeeldingen of videobijlagen kunt u een hero-kaart koppelen, waarmee u afbeeldingen en knoppen in één object kunt combineren en naar de gebruiker kunt verzenden. Markdown wordt ondersteund voor de meeste tekstvelden, maar ondersteuning kan per kanaal verschillen.
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);
Als u een bericht wilt opstellen met een hero-kaart en -knop, kunt u een HeroCard object aan een bericht koppelen.
* @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];
Als u een bericht wilt opstellen met een hero-kaart en -knop, kunt u een HeroCard object aan een bericht koppelen.
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);
}
Als u een bericht wilt opstellen met een hero-kaart en -knop, kunt u een HeroCard object aan een bericht koppelen.
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"
),
],
)
Gebeurtenissen binnen uitgebreide kaarten verwerken
Als u gebeurtenissen binnen uitgebreide kaarten wilt verwerken, gebruikt u kaartactieobjecten om op te geven wat er moet gebeuren wanneer de gebruiker een knop selecteert of tikt op een sectie van de kaart. Elke kaartactie heeft een eigenschap type en waarde .
Als u correct wilt functioneren, wijst u een actietype toe aan elk klikbaar item op een hero-kaart. In deze tabel worden de beschikbare actietypen vermeld en beschreven en wat er moet staan in de bijbehorende waardeeigenschap.
De messageBack kaartactie heeft een meer gegeneraliseerde betekenis dan de andere kaartacties. Zie de sectie Kaartactie van het activiteitenschema voor meer informatie over de messageBack en andere kaartactietypen.
Type
Description
Waarde
call
Start een telefoongesprek.
Bestemming voor het telefoongesprek in deze indeling: tel:123123123123.
downloadFile
Hiermee downloadt u een bestand.
De URL van het bestand dat u wilt downloaden.
imBack
Verzendt een bericht naar de bot en plaatst een zichtbaar antwoord in de chat.
Tekst van het bericht dat moet worden verzonden.
messageBack
Vertegenwoordigt een tekstantwoord dat moet worden verzonden via het chatsysteem.
Een optionele programmatische waarde die moet worden opgenomen in gegenereerde berichten.
openUrl
Hiermee opent u een URL in de ingebouwde browser.
De URL die moet worden geopend.
playAudio
Speelt audio af.
De URL van de audio die moet worden afgespeeld.
playVideo
Hiermee wordt een video afgespeeld.
De URL van de video die moet worden afgespeeld.
postBack
Verzendt een bericht naar de bot en plaatst mogelijk geen zichtbaar antwoord in de chat.
Tekst van het bericht dat moet worden verzonden.
showImage
Geeft een afbeelding weer.
De URL van de afbeelding die moet worden weergegeven.
aanmelden
Hiermee wordt een OAuth-aanmeldingsproces gestart.
De URL van de OAuth-stroom die moet worden gestart.
Hero-kaart met verschillende gebeurtenistypen
In de volgende code ziet u voorbeelden met behulp van verschillende uitgebreide kaartevenementen.
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;
}
createOAuthCard() {
return CardFactory.oauthCard(
'OAuth connection', // Replace with the name of your Azure AD connection
'Sign In',
'BotFramework OAuth Card'
);
}
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;
}
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)
Een adaptieve kaart verzenden
Hoewel u de berichtenfactory kunt gebruiken om een bericht te maken dat een bijlage (van welke aard dan ook) bevat, is een adaptieve kaart één specifiek type bijlage. Niet alle kanalen ondersteunen adaptieve kaarten en sommige kanalen ondersteunen mogelijk slechts gedeeltelijk adaptieve kaarten. Als u bijvoorbeeld een adaptieve kaart in Facebook verzendt, werken de knoppen niet terwijl teksten en afbeeldingen goed werken. De berichtenfactory is een Bot Framework SDK-helperklasse die wordt gebruikt om de stappen voor het maken voor u te automatiseren.
Adaptieve kaarten zijn een open kaartuitwisselingsindeling waarmee ontwikkelaars UI-inhoud op een algemene en consistente manier kunnen uitwisselen. Niet alle kanalen ondersteunen echter adaptieve kaarten.
De ontwerpfunctie voor adaptieve kaarten biedt een rijke, interactieve ontwerptijd voor het ontwerpen van adaptieve kaarten.
Notitie
U moet deze functie testen met de kanalen die uw bot gebruikt om te bepalen of deze kanalen adaptieve kaarten ondersteunen.
Berichten kunnen ook meerdere bijlagen bevatten in een carrouselindeling, waardoor de bijlagen naast elkaar worden geplaatst en de gebruiker kan schuiven.
De volgende broncode is afkomstig uit het voorbeeld kaarten gebruiken.
Dialoogvensters/MainDialog.cs
Maak eerst het antwoord en definieer de bijlagen als een lijst.
// 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);
Voeg vervolgens de bijlagen toe en stel het indelingstype in op carrousel.
Hier voegen we ze één voor één toe, maar u kunt de lijst bewerken om de kaarten op de gewenste wijze toe te voegen.
// 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());
Zodra de bijlagen zijn toegevoegd, kunt u het antwoord net als elke andere verzenden.
// Send the card(s) to the user as an attachment to the activity
await stepContext.Context.SendActivityAsync(reply, cancellationToken);
De volgende broncode is afkomstig uit het voorbeeld kaarten gebruiken.
dialoogvensters/mainDialog.js
Voeg de bijlagen toe en stel het indelingstype in op carrousel.
Zodra de bijlagen zijn toegevoegd, kunt u het antwoord net als elke andere verzenden.
De volgende broncode is afkomstig uit het voorbeeld kaarten gebruiken.
MainDialog.java
Maak eerst het antwoord en definieer de bijlagen als een lijst.
// 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);
Voeg vervolgens de bijlagen toe en stel het indelingstype in op carrousel.
Hier voegen we ze één voor één toe, maar u kunt de lijst bewerken om de kaarten op de gewenste wijze toe te voegen.
// 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());
Zodra de bijlagen zijn toegevoegd, kunt u het antwoord net als elke andere verzenden.
// Send the card(s) to the user as an attachment to the activity
return stepContext.getContext().sendActivity(reply)
Maak eerst het antwoord en definieer de bijlagen als een lijst.
reply = MessageFactory.list([])
Voeg vervolgens de bijlagen toe en stel het indelingstype in op carrousel.
Hier voegen we ze één voor één toe, maar u kunt de lijst bewerken om de kaarten op de gewenste wijze toe te voegen.
Zodra de bijlagen zijn toegevoegd, kunt u het antwoord net als elke andere verzenden.
# Send the card(s) to the user as an attachment to the activity
await step_context.context.send_activity(reply)
Codevoorbeeld voor het verwerken van adaptieve kaartinvoer
In het volgende voorbeeld ziet u een manier om adaptieve kaartinvoer in een botdialoogvensterklasse te gebruiken.
Het breidt het voorbeeld van hero-kaarten uit door de invoer die in het tekstveld is ontvangen, te valideren van de reagerende client.
U moet eerst de tekstinvoer- en knopfunctionaliteit toevoegen aan de bestaande adaptieve kaart door de volgende code toe te voegen vlak voor de laatste vierkante haak van adaptiveCard.json, die zich in de map resources bevindt:
De id van het tekstinvoerveld is ingesteld op 'tekst'. Wanneer de gebruiker OK selecteert, heeft het bericht dat de adaptieve kaart genereert een waardeeigenschap met een eigenschap met de naam text die de gebruiker in het tekstinvoerveld van de kaart heeft ingevoerd.
Onze validator gebruikt Newtonsoft.json om dit eerst te converteren naar een JObjecten vervolgens een teksttekenreeks met bijgesneden tekst te maken voor vergelijking. Voeg dus toe:
using System;
using System.Linq;
using Newtonsoft.Json.Linq;
om het nieuwste stabiele NuGet-pakket van Newtonsoft.Json te MainDialog.cs en te installeren.
In de validatiecode hebben we de logicastroom toegevoegd aan de codeopmerkingen.
Deze ChoiceValidator methode wordt in het voorbeeld kaarten gebruiken geplaatst vlak na de gesloten accolade openbaar voor declaratie van 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;
}
Nu hierboven in de MainDialog declaratiewijziging:
// Define the main dialog and its related components.
AddDialog(new ChoicePrompt(nameof(ChoicePrompt)));
in:
// Define the main dialog and its related components.
AddDialog(new ChoicePrompt(nameof(ChoicePrompt), ChoiceValidator));
Hiermee wordt uw validator aangeroepen om te zoeken naar adaptieve kaartinvoer telkens wanneer er een nieuwe keuzeprompt wordt gemaakt.
Open mainDialog.js en zoek de uitvoeringsmethode async run(turnContext, accessor) . Deze methode verwerkt binnenkomende activiteit.
Voeg net na de aanroep dialogSet.add(this); het volgende toe:
// 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;
}
Als met deze controle een niet-bestaande tekstinvoer van de client wordt gevonden, ziet u of er invoer van een adaptieve kaart is.
Als er een adaptieve kaartinvoer bestaat _activity.value.text, wordt dit gekopieerd naar het normale tekstinvoerveld.
Onze validator maakt gebruik van de serialisatiehulp van com.microsoft.bot.schema om dit eerst te converteren naar een JsonNodeen vervolgens een teksttekenreeks met bijgesneden tekst te maken voor vergelijking. We hebben ook enkele andere importbewerkingen nodig om dit te voltooien, dus voeg het volgende toe:
om te MainDialog.java.
In de validatiecode hebben we de logicastroom toegevoegd aan de codeopmerkingen.
Deze PromptValidator expressie wordt in het voorbeeld kaarten gebruiken geplaatst net na de gesloten accolade openbaar voor de declaratie van 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());
};
Nu hierboven in de MainDialog declaratiewijziging:
// Define the main dialog and its related components.
addDialog(new ChoicePrompt("ChoicePrompt"));
in:
// Define the main dialog and its related components.
addDialog(new ChoicePrompt("ChoicePrompt", validator, null));
Hiermee wordt uw validator aangeroepen om te zoeken naar adaptieve kaartinvoer telkens wanneer er een nieuwe keuzeprompt wordt gemaakt.
Een activiteit met voorgestelde acties maken en verzenden naar de gebruiker.
Deze choice_validator methode wordt net na de gesloten accolade openbaar geplaatst in het voorbeeld van kaarten met behulp van 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
Nu hierboven in de MainDialog declaratiewijziging: