対象範囲: SDK v4
ユーザーとボットの間のメッセージ交換には、イメージ、ビデオ、オーディオ、ファイルなどのメディア添付ファイルを含めることができます。 Bot Framework SDK では、ユーザーにリッチ メッセージを送信するタスクがサポートされています。 チャネル (Facebook、Slack など) がサポートするリッチ メッセージの種類を確認するには、チャネルのドキュメントで制限事項に関する情報を参照してください。
注
AI サービス、オーケストレーション、知識を選択してエージェントを構築するには、Microsoft 365 Agents SDK の使用を検討してください。 Agents SDK では、C#、JavaScript、または Python がサポートされています。 Agents SDK の詳細については、 aka.ms/agents を参照してください。 SaaS ベースのエージェント プラットフォームをお探しの場合は、 Microsoft Copilot Studio を検討してください。 Bot Framework SDK を使用して構築された既存のボットがある場合は、ボットを Agents SDK に更新できます。
Bot Framework SDK から Agents SDK への移行ガイダンスで、主要な変更と更新プログラムを確認できます。 Bot Framework SDK のサポート チケットは、2025 年 12 月 31 日の時点で提供されなくなります。
前提条件
-
ボットの基本に関する知識。
- この記事のコードは、次のサンプルに基づいています。
添付ファイルを送信する
イメージやビデオなどのユーザー コンテンツを送信するには、添付ファイルまたは添付ファイルのリストをメッセージに追加します。
使用可能なカードの例については、「ユーザー エクスペリエンスの設計」をご覧ください。
FAQ の「チャネルを使用して転送されるファイルのサイズ制限を教えてください」も参照してください。
このセクションのソース コードは全て、添付ファイルの処理のサンプルに基づいています。
Attachments オブジェクトの Activity プロパティには、メッセージに添付するメディア添付ファイルやリッチ カードを表す Attachment オブジェクトが格納されます。 メディア添付ファイルをメッセージに追加するには、Attachment アクティビティ用の reply オブジェクトを作成し、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
// @ts-check
返信メッセージを作成するには、テキストを定義し、添付ファイルを設定します。 添付ファイルを返信に割り当てる場合、添付ファイルの種類ごとに同じ操作を行いますが、次のスニペットに示すように、添付ファイルの設定と定義はそれぞれ異なります。 次のコードでは、インラインの添付ファイル用の返信が設定されます。
bots/attachmentsBot.js
* @param {Object} turnContext
// possible options.
const firstChar = turnContext.activity.text[0];
イメージやビデオのような単一のコンテンツを送信する場合、メディアを送信する方法は複数あります。 まず、インラインの添付ファイルとして送信できます。
bots/attachmentsBot.js
/**
* Returns an inline attachment.
*/
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',
次は、アップロードされた添付ファイルです。
bots/attachmentsBot.js
* Returns an attachment that has been uploaded to the channel's blob storage.
* @param {Object} turnContext
*/
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',
最後は、URL に含まれるインターネットの添付ファイルです。
bots/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',
このセクションのソース コードは、添付ファイルの処理のサンプルに基づいています。
getAttachments() オブジェクトの Activity メソッドには、メッセージに添付するメディア添付ファイルやリッチ カードを表す Attachment オブジェクトが格納されます。 メディア添付ファイルをメッセージに追加するには、Attachment アクティビティ用の reply オブジェクトを作成し、ContentType、ContentUrl、Name の各プロパティを設定します。
返信メッセージを作成するには、テキストを定義し、添付ファイルを設定します。 添付ファイルを返信に割り当てる場合、添付ファイルの種類ごとに同じ操作を行いますが、次のスニペットに示すように、添付ファイルの設定と定義はそれぞれ異なります。 次のコードでは、インラインの添付ファイル用の返信が設定されます。
AttachmentsBot.java
警告
探しているサンプルが移動したようです。 私たちはこれを解決することに取り組んでいますのでご安心ください。
次に、添付ファイルの種類を見ていきます。 最初はインラインの添付ファイルです。
AttachmentsBot.java
警告
探しているサンプルが移動したようです。 私たちはこれを解決することに取り組んでいますのでご安心ください。
次は、アップロードされた添付ファイルです。
AttachmentsBot.java
警告
探しているサンプルが移動したようです。 私たちはこれを解決することに取り組んでいますのでご安心ください。
最後は、インターネットの添付ファイルです。
AttachmentsBot.java
警告
探しているサンプルが移動したようです。 私たちはこれを解決することに取り組んでいますのでご安心ください。
次のソース コードは、添付ファイルの処理サンプルからのものです。
返信メッセージを作成するには、テキストを定義し、添付ファイルを設定します。 添付ファイルを返信に割り当てる場合、添付ファイルの種類ごとに同じ操作を行いますが、次のスニペットに示すように、添付ファイルの設定と定義はそれぞれ異なります。
次のコードでは、インラインの添付ファイル用の返信が設定されます。
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",
)
添付ファイルがイメージ、オーディオ、またはビデオの場合、コネクタ サービスにより、チャネルでの会話内の添付ファイルがレンダリングできる方法で、添付ファイルのデータがチャネルに通信されます。 添付ファイルがファイルである場合は、ファイルの URL が会話内にハイパーリンクとしてレンダリングされます。
ヒーロー カードを送信する
シンプルなイメージ添付ファイルまたはビデオ添付ファイルだけでなく、ヒーロー カードを添付することもできます。これにより、1 つのオブジェクトに含まれるイメージとボタンを結合してユーザーに送信することができます。 Markdown はほとんどのテキスト フィールドでサポートされていますが、サポート状況はチャネルごとに異なる場合があります。
ヒーロー カードとボタンを使用してメッセージを作成するには、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
* Sends a HeroCard with choices of attachments.
* @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];
ヒーロー カードとボタンを使用してメッセージを作成するには、HeroCard オブジェクトをメッセージに添付します。
次のソース コードは、添付ファイルの処理サンプルからのものです。
AttachmentsBot.java
警告
探しているサンプルが移動したようです。 私たちはこれを解決することに取り組んでいますのでご安心ください。
ヒーロー カードとボタンを使用してメッセージを作成するには、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"
),
],
)
リッチカード内でイベントを処理する
リッチなカード内のイベントを処理するには、カード アクション オブジェクトを使用して、ユーザーがボタンを選択したり、またはカードのセクションをタップしたりしたときのアクションを指定します。 各カード アクションには type と value プロパティがあります。
正常に機能させるために、ヒーロー カード上のクリック可能な各アイテムにアクション タイプを割り当てます。 この表では、使用できるアクションの種類と、関連付けられている value プロパティに含める内容を一覧にまとめ、説明しています。
messageBack カード アクションは、他のカード アクションよりも一般化された意味を持ちます。
およびその他のカード アクションの種類の詳細については、アクティビティ スキーマの「messageBack」セクションを参照してください。
| タイプ |
説明 |
価値 |
| 呼び出し |
電話を発信します。 |
電話の発信先 (形式は tel:123123123123)。 |
| ファイルをダウンロード |
ファイルをダウンロードします。 |
ダウンロードするファイルの URL。 |
| imBack |
ボットにメッセージを送信し、目に見える応答をチャットに投稿します。 |
送信するメッセージのテキスト。 |
| メッセージ返信 |
チャット システムを介して送信されるテキスト応答を表しています。 |
生成されたメッセージに含めるオプションのプログラム値。 |
| URLを開く |
組み込みのブラウザーで URL を開きます。 |
開くためのURL。 |
| オーディオを再生 |
オーディオを再生します。 |
再生するオーディオの URL。 |
| ビデオを再生する |
ビデオを視聴します。 |
再生するビデオの URL。 |
| ポストバック |
ボットにメッセージを送信します。目に見える応答はチャットに投稿できません。 |
送信するメッセージのテキスト。 |
| 画像を表示 |
画像を表示します。 |
表示する画像の URL。 |
| サインイン |
OAuth サインイン プロセスを開始します。 |
開始する OAuth フローの URL。 |
さまざまな種類のイベントを使用するヒーロー カード
次のコードでは、さまざまなリッチ カード イベントを使用する例を示します。
使用可能なすべてのカードの例については、カードの使用 サンプルをご覧ください。
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
image: 'https://upload.wikimedia.org/wikipedia/en/3/3c/SW_-_Empire_Strikes_Back.jpg'
}
);
}
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',
dialogs/mainDialog.js
}
])
);
}
createOAuthCard() {
return CardFactory.oauthCard(
使用可能なすべてのカードの例については、カードの使用 サンプルをご覧ください。
Cards.java
警告
探しているサンプルが移動したようです。 私たちはこれを解決することに取り組んでいますのでご安心ください。
Cards.java
警告
探しているサンプルが移動したようです。 私たちはこれを解決することに取り組んでいますのでご安心ください。
使用可能なすべてのカードの例については、カードの使用 サンプルをご覧ください。
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)
アダプティブ カードを送信する
メッセージ ファクトリを使用して添付ファイル (任意の種類) を含むメッセージを作成できますが、アダプティブ カードは添付ファイルの一種です。 アダプティブ カードをサポートするのは一部のチャネルのみで、チャネルによってはアダプティブ カードが部分的にしかサポートされない可能性があります。 たとえば、Facebook でアダプティブ カードを送信する場合、テキストと画像は適切に機能しますが、ボタンは機能しません。 メッセージ ファクトリは、作成手順を自動化するための、Bot Framework SDK のヘルパー クラスです。
アダプティブ カードは、開発者が 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 { AttachmentLayoutTypes, CardFactory } = require('botbuilder');
// ======================================
// Helper functions used to create cards.
// ======================================
次のソース コードは、カードの使用サンプルのものです。。
Cards.java
この例では、ファイルからアダプティブ カード JSON を読み取り、添付ファイルとして追加します。
警告
探しているサンプルが移動したようです。 私たちはこれを解決することに取り組んでいますのでご安心ください。
次のソース コードは、カードの使用サンプルのものです。。
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
添付ファイルを追加し、レイアウトの種類をカルーセルに設定します。
添付ファイルが追加されると、他と同じように返信を送信できます。
case 'Video Card':
await stepContext.context.sendActivity({ attachments: [this.createVideoCard()] });
break;
default:
await stepContext.context.sendActivity({
attachments: [
this.createAdaptiveCard(),
this.createAnimationCard(),
this.createAudioCard(),
this.createHeroCard(),
this.createOAuthCard(),
this.createReceiptCard(),
this.createSignInCard(),
this.createThumbnailCard(),
次のソース コードは、カードの使用サンプルのものです。。
MainDialog.java
最初に、返信を作成し、添付ファイルをリストとして定義します。
警告
探しているサンプルが移動したようです。 私たちはこれを解決することに取り組んでいますのでご安心ください。
次に、添付ファイルを追加し、レイアウトの種類をカルーセルに設定します。
ここでは 1 つずつ追加しますが、必要に応じて、リストを使ってカードを追加することもできます。
警告
探しているサンプルが移動したようです。 私たちはこれを解決することに取り組んでいますのでご安心ください。
添付ファイルが追加されると、他と同じように返信を送信できます。
警告
探しているサンプルが移動したようです。 私たちはこれを解決することに取り組んでいますのでご安心ください。
ここで示すソース コードは、カード使用のサンプルに基づいています。
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 の最後の括弧の直前に次のコードを追加することにより、既存のアダプティブ カードにテキスト入力およびボタン機能を追加する必要があります。
"actions": [
{
"type": "Action.ShowCard",
"title": "Text",
"card": {
"type": "AdaptiveCard",
"body": [
{
"type": "Input.Text",
"id": "text",
"isMultiline": true,
"placeholder": "Enter your comment"
}
],
"actions": [
{
"type": "Action.Submit",
"title": "OK"
}
]
}
}
]
テキスト入力フィールドの ID は "text" に設定されます。 ユーザーが [OK] を選択すると、アダプティブ カードによって生成されるメッセージには、ユーザーがカードのテキスト入力フィールドに入力した情報を含むプロパティを持つ、 という名前のtextプロパティがあります。
検証コントロールでは、Newtonsoft.json を使用して最初にこれを JObject に変換し、次に比較のためにトリミングされたテキスト文字列を作成します そのため、次のコードを
using System;
using System.Linq;
using Newtonsoft.Json.Linq;
MainDialog.cs に追加して、Newtonsoft.Json の最新の安定版 NuGet パッケージをインストールします。
検証コントロールのコードでは、コード コメントにロジック フローを追加しました。
この ChoiceValidator メソッドは、Using cards サンプルにある、MainDialog の宣言用の閉じ括弧の public の直後に配置されています。
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 を開き、実行メソッド 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 のシリアル化ヘルパーを使用して最初にこれを 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 式は、Using cards サンプルにある、MainDialog の宣言用の閉じ括弧の public の直後に配置されています。
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 メソッドは、Using cards サンプルにある、MainDialog の宣言用の閉じ括弧の public の直後に配置されています。
@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))
これにより、新しい選択プロンプトが作成されるたびに、検証コントロールが呼び出されてアダプティブ カード入力が検索されます。
Using Cards ボットをテストする
-
カードの使用サンプルをローカルで実行し、Bot Framework Emulator でボットを開きます。
- ボットのプロンプトに従って、アダプティブ カードなどのカードの種類を表示します。
次のステップ