Chatbot 開發使用Bot Framework V4 - 資訊卡

一般來說Chatbot試圖以模擬自然對話做為應用軟體的一種溝通模式,然而畢竟不是真的人類,要能達到理想上的完全像人類一樣的對話,就目前來說是有困難的,因此在Chatbot的一些情境裡,我們會利用資訊卡的UI來讓對話更流暢。

這些資訊卡你可以把它想像成應用程式裡的UI 控制項,用於讓使用者與Chatbot做互動,協助引導與Chatbot之間的交談,例如,提供項目選擇清單、摘要內容等,在bot framework裡(不管是V3或V4版本)皆有支援資訊卡,以下針對目前資訊卡的種類及程式碼片段做說明

AdaptiveCard
透過json的宣告,在各種通訊平台上產生自適應的資訊卡UI,不同通訊平台所呈現的UI會有些差異,直接來看這個例子,利用AdaptiveCard呈現個人資訊

private static Attachment CreateAdaptiveCardAttachment()
{
	// combine path for cross platform support
	string[] paths = { ".", "myprofile.json" };
	var adaptiveCardJson = File.ReadAllText(Path.Combine(paths), System.Text.Encoding.UTF8);

	var adaptiveCardAttachment = new Attachment()
	{
		ContentType = "application/vnd.microsoft.card.adaptive",
		Content = JsonConvert.DeserializeObject(adaptiveCardJson),
	};
	return adaptiveCardAttachment;
}

從程式碼我們可以看到使用AdaptiveCard時須先定義一個json檔案,這個json檔案包含以下資訊

  • type (必填) 固定值"AdaptiveCard"
  • version (非必填) 指定資訊卡schema版本
  • body (非必填) 顯示在AdaptiveCard裡的元素
  • actions (非必填) 在資訊卡的action bar要呈現的功能按鈕
  • selectAction (非必填) 點擊資訊卡時要調用的動作
  • fallbackText (非必填) 當通訊平台不支援所指定的資訊卡schema版本時,要顯示的文字
  • backgroundImage (非必填) 背景圖不用多解釋了吧
  • speak (非必填) AdaptiveCard簡要內容文字
  • lang (非必填) 指定本地化日期/時間格式

再進一步展開body內容

看似複雜,但簡單來說在body的部份主要是建構AdaptiveCard的主體內容,先利用Container把區塊劃分出來,接著在每個Container內放置內容,可以是圖檔、文字等,並且可以細部設置以ColumnSet或TextBlock型態編排,以及寬度、字型大小等等。

接著在AdaptiveCard最後面可以放置actions,讓使用者可以做點選操作。

AudioCard & VideoCard
這二種資訊卡分別支援聲音及影音方面,程式碼方面大致相同,差別在於給予是聲音檔案或是影音檔案,直接來看VideoCard
private static Attachment CreateVideoCard()
{
	var card = new VideoCard
	{
		Title = "AI實作範例-Chatbot",
		Subtitle = "使用bot framework 打造Chatbot",
		Text = "這是一個使用bot framework+LUIS打造Chatbot的範例",
		Media = new List<MediaUrl>
		{
			new MediaUrl()
			{
				Url = "https://www.youtube.com/watch?v=bWUoaIJ6KUw",
			},
		},
		Buttons = new List<CardAction>
		{
			new CardAction()
			{
				Title = "Read More",
				Type = ActionTypes.OpenUrl,
				Value = "https://www.youtube.com/watch?v=bWUoaIJ6KUw",
			},
		},
	};

	return card.ToAttachment();
}

 從程式碼我們可以看到使用VideoCard時,除了Title、Subtitle、Text屬性可以給予文字資訊之外,影像檔案的部份是設置Media屬性,接著同樣可以提供CardAction讓使用者可以進一步點選進行互動,不管是VideoCard或AudioCard,都是可以直接在Chatbot裡就進行播放的

HeroCard & ThumbnailCard
這二種資訊卡程式碼方面大致相同,差別在於UI上的圖示大小呈現不同,HeroCard會呈現大尺吋圖示,比較適合用來呈現與內容本文相關的圖,而ThumbnailCard則是小圖示,比較適合用來呈現品牌Logo或產品Logo

private static Attachment CreateHeroCard()
{
	var heroCard = new HeroCard
	{
		Title = "BotFramework Chatbot",
		Subtitle = "Use Microsoft Bot Framework v4 Create Chatbot",
		Text = "使用Microsoft Bot Framework v4打造聊天機器人",
		Images = new List<CardImage> {
			new CardImage("http://anthillonline.com/wp-content/uploads/2018/07/chatbot-300x350.jpg")
		},
		Buttons = new List<CardAction> {
			new CardAction(ActionTypes.OpenUrl, "View More", value: "https://docs.microsoft.com/bot-framework")
		},
	};

	return heroCard.ToAttachment();
}

從程式碼我們可以看到除了Title、Subtitle、Text屬性可以給予文字資訊之外,透過設置Images屬性可以決定要呈現的圖示,接著同樣可以提供CardAction讓使用者可以進一步點選進行互動

ReceiptCard
這個資訊卡比較特別,類似收據的格式,用於呈現購物項目清單以及金額等資訊

private static Attachment CreateReceiptCard()
{
	var receiptCard = new ReceiptCard
	{
		Title = "Ian Chen",
		Facts = new List<Fact> {
			new Fact("訂單編號", "A12345678"),
			new Fact("消費日期", "2018/5/1"),
			new Fact("付款方式", "VISA 8888-****")
		},
		Items = new List<ReceiptItem>
		{
			new ReceiptItem("球棒型加油棒",
				price: "$ 200",
				quantity: "1",
				image: new CardImage(url: "https://img1.momoshop.com.tw/goodsimg/0004/706/410/4706410_X.jpg")),
			new ReceiptItem("應援毛巾(藍)",
				price: "$ 250",
				quantity: "1",
				image: new CardImage(url: "https://img1.momoshop.com.tw/goodsimg/0004/781/728/4781728_X.jpg")),
		},
		Tax = "$ 0",
		Total = "$ 450",
		Buttons = new List<CardAction>
		{
			new CardAction(
				ActionTypes.OpenUrl,
				"詳細資訊",
				"https://img1.momoshop.com.tw/ecm/img/online/21/411/00/000/bt_1_019_01/bt_1_019_01_e3.jpg",
				value: "https://www.momoshop.com.tw/category/LgrpCategory.jsp?l_code=2141100000")
		}
	};

	return receiptCard.ToAttachment();
}

程式碼的部份,Factsg屬性用於呈現最上方的資訊,而Items屬性用於呈現項目清單,Tax及Total則是稅金和總金額資訊,同樣的可以提供CardAction讓使用者可以進一步點選進行互動

AnimationCard
用於呈現播放 GIF 或短片的資訊卡

private static Attachment GetAnimationCard()
{
	var animationCard = new AnimationCard
	{
		Title = "Microsoft Bot Framework",
		Subtitle = "Animation Card",
		Media = new List<MediaUrl>
		{
			new MediaUrl()
			{
				Url = "https://freight.cargo.site/w/600/q/94/i/125b3fa7090d4d0e880febc7e29f6d0095f58f6d75ab76ccd6db623a046f2346/giphy-7.gif",
			},
		},
	};

	return animationCard.ToAttachment();
}

程式碼很簡單,設置Media屬性提供gif圖檔的URL即可,當然做為一個資訊卡,基本的Title、Subtitle還是有的。

最後在主程式碼的部份,我們來看看如何把資訊卡做為一個回覆訊息,回傳給使用者,透過turnContext的Activity物件呼叫CreateReply方法,產生一個回覆的Activity物件,接著在這個Activity物件的Attachments屬性加入Attachment,最後呼叫SendActivityAsync(reply)把回覆的Activity物件送回去即可

public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
	if (turnContext.Activity.Type == ActivityTypes.Message)
	{
		var reply = turnContext.Activity.CreateReply();
		reply.Attachments.Add(GetAnimationCard());
		await turnContext.SendActivityAsync(reply);
	}
}
最後要提醒的是,bot framework提供了多樣的資訊卡UI,不過這些UI在不同的通訊平台上所呈現的最終效果,會有不同的差異,善用資訊卡UI可以讓你的Chatbot提供更佳的操作互動性,而非完全採用自然語言互動,畢竟Chatbot的本體仍然還是機器,而非真實的人類

 

若本文對您有所幫助,歡迎轉貼,但請在加註【轉貼】及來源出處,並在附上本篇的超連結,感恩您的配合囉。

By No.18