3.2 處理使用者輸入的內容

在 3.1 的範例中我們看到了可以使用 builder.Prompts 來提示使用者輸入文字資料,不過 builder.Prompts 不僅能處理使用者的文字內容,也可以提示使用者輸入數字清單選項時間確認、甚至是多媒體內容 (附件)。這一篇就是介紹如何處理使用者的輸入。

輸入內容的對話流程

在 Bot Framework 中,提示使用者輸入內容時,就要到對話的下一個流程來接收輸入的結果,而輸入的內容就會放在下一個對話流程中的參數裡。

dialog('greeting', [
  (session) => {
    builder.Prompts.text('請問您叫什麼名字?');
  },
  (session, results) => {
    session.endDialog(`您的名字是${results.response}`);
  }
]);

上面這個例子示範了在前一個對話流程中提示使用者輸入他的名字(一段文字),而在下一個對話流程中再以 results 去接輸入的內容,而文字資料就放在 results.response 中。

提示使用者輸入的資料類別

目前 builder.Prompts 支援下面幾種資料類別:

提示輸入的類型 說明
Prompts.text 輸入純文字內容。
Prompts.confirm 請使用者確認動作。
Prompts.number 輸入數字內容。
Prompts.time 輸入時間內容。
Prompts.choice 提供給使用者一個清單做選擇。
Prompts.attachment 輸入附件資料,如圖片、檔案等多媒體內容。

Prompts.text

提示使用者輸入一段文字,回傳的內容會是 string 型態。

builder.Prompts.text(session, '請問怎麼稱呼您?');

這樣會顯示「請問怎麼稱呼您?」後等待使用者輸入內容,results.response 會是一個字串內容的資料。

Prompts.confirm

請使用者用 yesno (也可以是 Y/yN/n)的回答來進行確認。

builder.Prompts.confirm(session, '您確定要修改嗎?');

用戶回覆的內容會是一個 boolean 值,所以回答 yes 時 results.response 會是 true 否則則為 false

但若用戶輸入預期以外的內容時,它預設會顯示「I didn’t understand. Please answer ‘yes’ or ‘no’.」如果要修改這段提示文字,可以在 Prompts.confirm 呼叫中加入 retryPrompt 的選項,像是這樣:

builder.Prompts.confirm(session, '您確定要修改嗎?', {
    retryPrompt: '不好意思,請輸入 yes 或是 no 來回答' 
});

這樣就會用設定的文字訊息來提示使用者該怎麼輸入。

所有的 Prompts 都可以用相同的方式來設定 retryPrompt。

Prompts.number

請使用者輸入數值資料(包含整數及浮點數),results.response 的資料就是 number 型態。

builder.Prompts.number(session, '請問您想買幾個呢?', {
  retryPrompt: '不好意思,請輸入數字'
});

Prompts.time

請使用者輸入時間資料,這個功能是使用 Chrono 這套時間格式解析的函式庫實作的(支援中文!),所以支援的時間格式與此函式庫相同,支援絕對時間以及相對時間的描述。而要將使用者輸入的時間資料轉換為 JavaScript 的 Date 型態則需要使用 builder.EntityRecognizer.resolveTime() 來做轉換。

時間會被轉換成 UTC 時間。

bot.dialog('reserve', [
  (session) => {
    builder.Prompts.time(session, '請問要訂幾點呢?', {
      retryPrompt: '請輸入正確的時間格式'
    });
  },
  (session, results) => {
    let time = builder.EntityRecognizer.resolveTime([results.response]);
    session.endDialogWithResult({ time: time });
  }
]);

results.response.entity 會拿到使用者原始的輸入資料,例如使用者輸入「三天後」就會直接拿到 三天後

Prompts.choice

讓使用者從一個清單中選取一個選項來回答。決定選項的方式可以使用 | 分隔的字串:

builder.Prompts.choice(session, "請問您要點什麼飲料呢?", "綠茶|紅茶|奶茶");

或是字串陣列:

builder.Prompts.choice(session, '請問您要點什麼飲料呢?', ['綠茶', '紅茶', '奶茶']);

或是 JSON 物件:

builder.Prompts.choice(session, '請問您要點什麼飲料呢?', {
  "綠茶": {
    "Price": 30
  },
  "紅茶": {
    "Price": 30
  },
  "奶茶": {
    "Price": 35
  }
});

而選擇的結果會放在 results.response.entity 中,內容就是清單上的文字。或者也可以從 results.response.index 中拿到清單陣列的索引值 (從 0 開始)。

而清單選項的選擇方式也可以由幾個常數來設定樣式:

索引值 常數名稱 樣式效果
0 builder.ListStyle.none 不特別顯示清單,變成提示文字的一部份。
1 builder.ListStyle.inline 直顯顯示一行清單,並以數字編排。
2 builder.ListStyle.list 顯示一個有數字編號的清單。
3 builder.ListStyle.button 如果通訊平台支援就將選項顯示成按鈕,否則顯示成文字。
4 builder.ListStyle.auto 自動根據通訊平台或清單數量來決定顯示樣式。

樣式在 bot framework emulator 中看起來都一樣,必須要部署到通訊平台上才會顯示出不同的樣式。

Prompts.attachment

提示使用者上傳圖片、檔案或是其它多媒體檔案,而上傳的資料就跟處理訊息的附件一樣(可參考 2.2 的範例),只是 results.response 就是 attachments 的附件資料內容。

bot.dialog('editAvatar', [
  (session) => {
    builder.Prompts.attachment(session, "請上傳一張照片作為您的大頭貼");
  },
  (session, results) => {
    if (results.response.length > 0) {
      session.dialogData.file = results.response[0];
      builder.Prompts.confirm(session, "您是否要用這張照片作為大頭貼呢?");
    } else {
      session.endDialog('發生錯誤'); 
    }
  },
  (session, results) => {
    let endingMessage;
    if (results.response) {
      // 使用 session.dialogData.file 修改照片
      endingMessage = '好的,已為您修改大頭貼';
    } else {
      endingMessage = '瞭解,動作已取消';
    }
    session.endDialog(endingMessage);
  }
]);

參考資源

results matching ""

    No results matching ""