ユーザーとボットの間のメッセージ交換には、イメージ、ビデオ、オーディオ、ファイルなどのメディア添付ファイルを含めることができます。 Bot Framework SDK では、ユーザーにリッチ メッセージを送信するタスクがサポートされています。 チャネル (Facebook、Slack など) がサポートするリッチ メッセージの種類を確認するには、チャネルのドキュメントで制限事項に関する情報を参照してください。
このセクションに示すソース コードはすべて、 添付ファイルの処理 サンプルに基づいています。
Activity オブジェクトの Attachments プロパティには、メッセージに添付するメディア添付ファイルやリッチ カードを表す Attachment オブジェクトが格納されます。 メディア添付ファイルをメッセージに追加するには、reply アクティビティ用の Attachment オブジェクトを作成し、ContentType、ContentUrl、Name の各プロパティを設定します。
返信メッセージを作成するには、テキストを定義し、添付ファイルを設定します。 添付ファイルを返信に割り当てる場合、添付ファイルの種類ごとに同じ操作を行いますが、次のスニペットに示すように、添付ファイルの設定と定義はそれぞれ異なります。 次のコードでは、インラインの添付ファイル用の返信が設定されます。
Bots/AttachmentsBot.cs
{
reply = MessageFactory.Text("This is an inline attachment.");
次に、添付ファイルの種類を見ていきます。 最初はインラインの添付ファイルです。
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}",
};
}
次は、アップロードされた添付ファイルです。
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,
};
}
最後は、インターネットの添付ファイルです。
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",
};
}
}
ここに示すソース コードは、 添付ファイルの処理 サンプルに基づいています。
添付ファイルを使用するには、お使いのボットに次のライブラリを含めます。
bots/attachmentsBot.js
const { ActivityHandler, ActionTypes, ActivityTypes, CardFactory } = require('botbuilder');
返信メッセージを作成するには、テキストを定義し、添付ファイルを設定します。 添付ファイルを返信に割り当てる場合、添付ファイルの種類ごとに同じ操作を行いますが、次のスニペットに示すように、添付ファイルの設定と定義はそれぞれ異なります。 次のコードでは、インラインの添付ファイル用の返信が設定されます。
bots/attachmentsBot.js
const reply = { type: ActivityTypes.Message };
reply.text = 'This is an inline attachment.';
reply.attachments = [this.getInlineAttachment()];
イメージやビデオのような単一のコンテンツを送信する場合、メディアを送信する方法は複数あります。 まず、インラインの添付ファイルとして送信できます。
bots/attachmentsBot.js
getInlineAttachment() {
const imageData = fs.readFileSync(path.join(__dirname, '../resources/architecture-resize.png'));
const base64Image = Buffer.from(imageData).toString('base64');
return {
name: 'architecture-resize.png',
contentType: 'image/png',
contentUrl: `data:image/png;base64,${ base64Image }`
};
}
次は、アップロードされた添付ファイルです。
bots/attachmentsBot.js
async getUploadedAttachment(turnContext) {
const imageData = fs.readFileSync(path.join(__dirname, '../resources/architecture-resize.png'));
const connectorFactory = turnContext.turnState.get(turnContext.adapter.ConnectorFactoryKey);
const connector = await connectorFactory.create(turnContext.activity.serviceUrl);
const conversationId = turnContext.activity.conversation.id;
const response = await connector.conversations.uploadAttachment(conversationId, {
name: 'architecture-resize.png',
originalBase64: imageData,
type: 'image/png'
});
// Retrieve baseUri from ConnectorClient for... something.
const baseUri = connector.baseUri;
const attachmentUri = baseUri + (baseUri.endsWith('/') ? '' : '/') + `v3/attachments/${ encodeURI(response.id) }/views/original`;
return {
name: 'architecture-resize.png',
contentType: 'image/png',
contentUrl: attachmentUri
};
最後は、URL に含まれるインターネットの添付ファイルです。
bots/attachmentsBot.js
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'
};
}
このセクションに示すソース コードは、 添付ファイルの処理 サンプルに基づいています。
オブジェクトのActivityメソッドにはgetAttachments()、メッセージに添付されたメディア添付ファイルとリッチ カードを表すオブジェクトの配列Attachmentが含まれています。 メディア添付ファイルをメッセージに追加するには、reply アクティビティ用の Attachment オブジェクトを作成し、ContentType、ContentUrl、Name の各プロパティを設定します。
返信メッセージを作成するには、テキストを定義し、添付ファイルを設定します。 添付ファイルを返信に割り当てる場合、添付ファイルの種類ごとに同じ操作を行いますが、次のスニペットに示すように、添付ファイルの設定と定義はそれぞれ異なります。 次のコードでは、インラインの添付ファイル用の返信が設定されます。
AttachmentsBot.java
result = getInlineAttachment()
.thenApply(attachment -> {
Activity reply = MessageFactory.text("This is an inline attachment.");
reply.setAttachment(attachment);
return reply;
});
次に、添付ファイルの種類を見ていきます。 最初はインラインの添付ファイルです。
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;
});
}
次は、アップロードされた添付ファイルです。
AttachmentsBot.java
private CompletableFuture<Attachment> getUploadedAttachment(TurnContext turnContext, String serviceUrl, String conversationId) {
if (StringUtils.isEmpty(serviceUrl)) {
return Async.completeExceptionally(new IllegalArgumentException("serviceUrl"));
}
if (StringUtils.isEmpty(conversationId)) {
return Async.completeExceptionally(new IllegalArgumentException("conversationId"));
}
ConnectorClient connector = turnContext.getTurnState()
.get(BotFrameworkAdapter.CONNECTOR_CLIENT_KEY);
Attachments attachments = connector.getAttachments();
return getFileData("architecture-resize.png")
.thenCompose(fileData -> {
AttachmentData attachmentData = new AttachmentData();
attachmentData.setName("architecture-resize.png");
attachmentData.setType("image/png");
attachmentData.setOriginalBase64(fileData);
return connector.getConversations().uploadAttachment(conversationId, attachmentData)
.thenApply(response -> {
String attachmentUri = attachments.getAttachmentUri(response.getId());
Attachment attachment = new Attachment();
attachment.setName("architecture-resize.png");
attachment.setContentType("image/png");
attachment.setContentUrl(attachmentUri);
return attachment;
});
});
}
最後は、インターネットの添付ファイルです。
AttachmentsBot.java
// 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;
}
ここに示すソース コードは、 添付ファイルの処理 サンプルに基づいています。
返信メッセージを作成するには、テキストを定義し、添付ファイルを設定します。 添付ファイルを返信に割り当てる場合、添付ファイルの種類ごとに同じ操作を行いますが、次のスニペットに示すように、添付ファイルの設定と定義はそれぞれ異なります。
次のコードでは、インラインの添付ファイル用の返信が設定されます。
bots/attachments_bot.py
reply.text = "This is an inline attachment."
reply.attachments = [self._get_inline_attachment()]
イメージやビデオのような単一のコンテンツを送信する場合、メディアを送信する方法は複数あります。 まず、インラインの添付ファイルとして送信できます。
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}",
)
次は、アップロードされた添付ファイルです。
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,
)
最後は、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",
)
ヒーロー カードとボタンを使用してメッセージを作成するには、メッセージにオブジェクトを HeroCard 添付します。
ここに示すソース コードは、 添付ファイルの処理 サンプルに基づいています。
Bots/AttachmentsBot.cs
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);
ヒーロー カードとボタンを使用してメッセージを作成するには、メッセージにオブジェクトを HeroCard 添付します。
ここに示すソース コードは、 添付ファイルの処理 サンプルに基づいています。
bots/attachmentsBot.js
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];
await turnContext.sendActivity(reply);
}
ヒーロー カードとボタンを使用してメッセージを作成するには、メッセージにオブジェクトを HeroCard 添付します。
ここに示すソース コードは、 添付ファイルの処理 サンプルに基づいています。
AttachmentsBot.java
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);
}
ヒーロー カードとボタンを使用してメッセージを作成するには、メッセージにオブジェクトを HeroCard 添付します。
ここに示すソース コードは、 添付ファイルの処理 サンプルに基づいています。
bots/attachments_bot.py
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"
),
],
)
正しく機能するには、ヒーロー カード上のクリック可能な各アイテムにアクションの種類を割り当てます。 この表では、使用できるアクションの種類と、関連付けられている value プロパティに含める内容を一覧にまとめ、説明しています。
カード アクションは messageBack 、他のカード アクションよりも一般化された意味を持ちます。 その他の カード アクション の種類の詳細については、 アクティビティ スキーマ のカード アクションセクションを messageBack 参照してください。
使用可能なすべてのカードの例については、「 カードの使用 」サンプルを参照してください。
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;
}
使用可能なすべてのカードの例については、「 カードの使用 」サンプルを参照してください。
dialogs/mainDialog.js
createHeroCard() {
return CardFactory.heroCard(
'BotFramework Hero Card',
CardFactory.images(['https://sec.ch9.ms/ch9/7ff5/e07cfef0-aa3b-40bb-9baa-7c9ef8ff7ff5/buildreactionbotframework_960.jpg']),
CardFactory.actions([
{
type: 'openUrl',
title: 'Get started',
value: 'https://docs.microsoft.com/en-us/azure/bot-service/'
}
])
);
}
dialogs/mainDialog.js
createOAuthCard() {
return CardFactory.oauthCard(
'OAuth connection', // Replace with the name of your Azure AD connection
'Sign In',
'BotFramework OAuth Card'
);
}
使用可能なすべてのカードの例については、「 カードの使用 」サンプルを参照してください。
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;
}
使用可能なすべてのカードの例については、「 カードの使用 」サンプルを参照してください。
dialogs/main_dialog.py
def create_hero_card(self) -> Attachment:
card = HeroCard(
title="",
images=[
CardImage(
url="https://sec.ch9.ms/ch9/7ff5/e07cfef0-aa3b-40bb-9baa-7c9ef8ff7ff5/buildreactionbotframework_960.jpg"
)
],
buttons=[
CardAction(
type=ActionTypes.open_url,
title="Get Started",
value="https://docs.microsoft.com/en-us/azure/bot-service/",
)
],
)
return CardFactory.hero_card(card)
dialogs/main_dialog.py
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)
アダプティブ カードは、カード交換のオープン フォーマットであり、開発者は一貫性のある共通した方法で UI コンテンツを交換できます。 ただし、すべてのチャネルでアダプティブ カードがサポートされているわけではありません。
アダプティブ カードを使用するには、必ず AdaptiveCards NuGet パッケージを追加してください。
ここで示すソース コードは、カード使用のサンプルに基づいています。
Cards.cs
この例では、アダプティブ カード JSON をファイルから読み取り、添付ファイルとして追加します。
public static Attachment CreateAdaptiveCardAttachment()
{
// combine path for cross platform support
var paths = new[] { ".", "Resources", "adaptiveCard.json" };
var adaptiveCardJson = File.ReadAllText(Path.Combine(paths));
var adaptiveCardAttachment = new Attachment()
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = JsonConvert.DeserializeObject(adaptiveCardJson),
};
return adaptiveCardAttachment;
}
アダプティブ カードを使用するには、必ず adaptivecards npm パッケージを追加してください。
ここで示すソース コードは、カード使用のサンプルに基づいています。
dialogs/mainDialog.js
この例では、アダプティブ カード JSON をファイルから読み取り、カードが添付されたメッセージ アクティビティを作成します。
const AdaptiveCard = require('../resources/adaptiveCard.json');
createAdaptiveCard() {
return CardFactory.adaptiveCard(AdaptiveCard);
}
ここで示すソース コードは、カード使用のサンプルに基づいています。
Cards.java
この例では、アダプティブ カード JSON をファイルから読み取り、添付ファイルとして追加します。
public static Attachment createAdaptiveCardAttachment() {
Attachment adaptiveCardAttachment = new Attachment();
try (
InputStream inputStream = adaptiveCardAttachment.getClass().getClassLoader()
.getResourceAsStream("adaptiveCard.json")
) {
String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
adaptiveCardAttachment.setContentType("application/vnd.microsoft.card.adaptive");
adaptiveCardAttachment.setContent(new ObjectMapper().readValue(result, ObjectNode.class));
return adaptiveCardAttachment;
} catch (Throwable t) {
throw new CompletionException(t);
}
}
ここで示すソース コードは、カード使用のサンプルに基づいています。
bots/main_dialog.py
この例では、アダプティブ カード JSON をファイルから読み取り、カードが添付されたメッセージ アクティビティを作成します。
from .resources.adaptive_card_example import ADAPTIVE_CARD_CONTENT
def create_adaptive_card(self) -> Attachment:
return CardFactory.adaptive_card(ADAPTIVE_CARD_CONTENT)
また、メッセージには複数の添付ファイルをカルーセル レイアウトで含めることもできます。このレイアウトでは、添付ファイルが左右に並べて配置され、ユーザーは全体をスクロールすることができます。
ここで示すソース コードは、カード使用のサンプルに基づいています。
Dialogs/MainDialog.cs
最初に、返信を作成し、添付ファイルをリストとして定義します。
// 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);
次に、添付ファイルを追加し、レイアウトの種類をカルーセルに設定 します。
ここでは 1 つずつ追加しますが、必要に応じて、リストを使ってカードを追加することもできます。
// 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());
添付ファイルが追加されると、他と同じように返信を送信できます。
// Send the card(s) to the user as an attachment to the activity
await stepContext.Context.SendActivityAsync(reply, cancellationToken);
ここで示すソース コードは、カード使用のサンプルに基づいています。
dialogs/mainDialog.js
添付ファイルを追加し、レイアウトの種類を カルーセルに設定します。
添付ファイルが追加されると、他と同じように返信を送信できます。
await stepContext.context.sendActivity({
attachments: [
this.createAdaptiveCard(),
this.createAnimationCard(),
this.createAudioCard(),
this.createHeroCard(),
this.createOAuthCard(),
this.createReceiptCard(),
this.createSignInCard(),
this.createThumbnailCard(),
this.createVideoCard()
],
attachmentLayout: AttachmentLayoutTypes.Carousel
});
ここで示すソース コードは、カード使用のサンプルに基づいています。
MainDialog.java
最初に、返信を作成し、添付ファイルをリストとして定義します。
// 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);
次に、添付ファイルを追加し、レイアウトの種類をカルーセルに設定 します。
ここでは 1 つずつ追加しますが、必要に応じて、リストを使ってカードを追加することもできます。
// 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());
添付ファイルが追加されると、他と同じように返信を送信できます。
// Send the card(s) to the user as an attachment to the activity
return stepContext.getContext().sendActivity(reply)
ここで示すソース コードは、 カードの使用 サンプルに基づいています。
dialogs/main_dialog.py
最初に、返信を作成し、添付ファイルをリストとして定義します。
reply = MessageFactory.list([])
次に、添付ファイルを追加し、レイアウトの種類をカルーセルに設定 します。
ここでは 1 つずつ追加しますが、必要に応じて、リストを使ってカードを追加することもできます。
reply.attachment_layout = AttachmentLayoutTypes.carousel
reply.attachments.append(self.create_adaptive_card())
reply.attachments.append(self.create_animation_card())
reply.attachments.append(self.create_audio_card())
reply.attachments.append(self.create_hero_card())
reply.attachments.append(self.create_oauth_card())
reply.attachments.append(self.create_receipt_card())
reply.attachments.append(self.create_signin_card())
reply.attachments.append(self.create_thumbnail_card())
reply.attachments.append(self.create_video_card())
添付ファイルが追加されると、他と同じように返信を送信できます。
# Send the card(s) to the user as an attachment to the activity
await step_context.context.send_activity(reply)
次の例は、ボット ダイアログ クラス内でアダプティブ カード入力を使用する 1 つの方法を示しています。
応答するクライアントからテキスト フィールドで受信した入力を検証することで、ヒーロー カードのサンプルを拡張します。
まず、resources フォルダーにある adaptiveCard.json の最後の角かっこの直前に次のコードを追加して、既存のアダプティブ カードにテキスト入力とボタンの機能を追加する必要があります。
この検証コントロールでは 、Newtonsoft.json を使用して最初にこれを a JObjectに変換し、次に比較のためにトリミングされたテキスト文字列を作成します。 そのため、次のコードを
using System;
using System.Linq;
using Newtonsoft.Json.Linq;
を MainDialog.cs にインストールし、Newtonsoft.Json の最新の安定した NuGet パッケージをインストールします。
検証コントロールのコードでは、コード コメントにロジック フローを追加しました。
この ChoiceValidator メソッドは、MainDialog の宣言用の閉じかっこパブリックの直後に 、Using カード のサンプルに配置されます。
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;
}
宣言の変更の上に次の手順を MainDialog 実行します。
// Define the main dialog and its related components.
AddDialog(new ChoicePrompt(nameof(ChoicePrompt)));
この行を次のように変更します。
// Define the main dialog and its related components.
AddDialog(new ChoicePrompt(nameof(ChoicePrompt), ChoiceValidator));
これにより、バリデーターが呼び出され、新しい選択プロンプトが作成されるたびにアダプティブ カード入力が検索されます。
mainDialog.js開き、run メソッドasync run(turnContext, accessor)を見つけます。このメソッドは受信アクティビティを処理します。
呼び出し dialogSet.add(this); の直後に、次のコードを追加します。
// 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;
}
このチェックで、クライアントからの存在しないテキストの入力が見つかった場合、アダプティブ カードからの入力があるかどうかが調べられます。
アダプティブ カード入力が存在する _activity.value.text場合は、これを通常のテキスト入力フィールドにコピーします。
検証コントロールでは、com.microsoft.bot.schema の シリアル化 ヘルパーを使用して、最初にこれを a JsonNodeに変換してから、比較のためにトリミングされたテキスト文字列を作成します。 これを完了するには、他のいくつかのインポートも必要になるため、次を追加します。
import com.fasterxml.jackson.databind.JsonNode;
import com.microsoft.bot.dialogs.prompts.PromptValidator;
import com.microsoft.bot.schema.Serialization;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
MainDialog.java に
検証コントロールのコードでは、コード コメントにロジック フローを追加しました。
この PromptValidator 式は、MainDialog の宣言用に閉じかっこパブリックの直後に Using カード サンプルに配置されます。
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());
};
宣言の変更の上に次の手順を MainDialog 実行します。
// Define the main dialog and its related components.
addDialog(new ChoicePrompt("ChoicePrompt"));
この行を次のように変更します。
// Define the main dialog and its related components.
addDialog(new ChoicePrompt("ChoicePrompt", validator, null));
これにより、バリデーターが呼び出され、新しい選択プロンプトが作成されるたびにアダプティブ カード入力が検索されます。
推奨されるアクションを含むアクティビティを作成し、ユーザーに送信します。
このchoice_validatorメソッドは、次の宣言MainDialogのために閉じかっこパブリックの直後に Using カードサンプルに配置されます。
@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
宣言の変更の上に次の手順を MainDialog 実行します。
self.add_dialog(ChoicePrompt(CARD_PROMPT))
この行を次のように変更します。
self.add_dialog(ChoicePrompt(CARD_PROMPT, MainDialog.choice_validator))
これにより、バリデーターが呼び出され、新しい選択プロンプトが作成されるたびにアダプティブ カード入力が検索されます。