iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 16
1
Modern Web

使用 Modern Web 技術來打造 Chat App系列 第 16

Day 16:對話式 App 的必要之惡 - 「Webview」

前面幾篇內提到的所有互動都是在對話框中完成,雖然若能順暢的用 Conversation UI 完成所有的事情,那會是很棒的事,使用者不會碰到斷斷續續的或是跳轉的體驗。但有些時候就是不適合在對話中輸入資訊,這邊我舉幾個例子:

  1. 在輸入敏感資訊的時候,例如:密碼、信用卡卡號或信用卡安全碼。在網頁輸入時可以用 <input type="password"> 來讓輸入變成 *******,但在各種聊天平台的輸入框輸入都不會有保護,也會留在歷史訊息,旁邊有人就能直接去看到,這是一個蠻大的問題。

  2. 在詢問問題時,過多的步驟(我個人認為超過三輪都算是難用)。例如,訂位時如果機器人只問你幾點、幾位那可能還好,但如果機器人要問你幾點、幾位、有沒有小孩需不需要兒童座椅、有沒有人吃素、沒有景觀的位子可以嗎...等等,一個問題是會顯得冗長,但最嚴重的問題是,確認跟修改的流程變得煩悶而且沒有效率,想想看當你想要修改前面兩步的輸入錯誤會是怎樣的情景。

  3. 輸入的項目不好用言語去限制或挑選,需要一種選擇器。例如:時間可以用下拉式選單選、地點可以用地圖加圖針的方式去拉、顏色可以用調色盤去拉...等等,這都是用言語很難表達的,當你資料庫有一大堆東西要給使用者選,有可能也會是同一種情境。

在遇到上面三種情境時,我能肯定的說,請用 Webview 來解決吧,這會是更好的體驗。

不要輕易打斷使用流程

在使用 Webview 時,如果不是必要,應該要避免開出全版的網頁,這是 Messenger 的選項:

https://ithelp.ithome.com.tw/upload/images/20191001/201036302mZCFK2L5z.png

這是 LINE 的選項:

https://ithelp.ithome.com.tw/upload/images/20191001/20103630jNZMlRJwca.png

基本上都是有 50%80%100% 三種選擇。所以我們應該主要使用 50%80% 的高度,這樣使用者比較容易感受到這個網頁是由對話來的,容易完成網頁上的任務再回到對話,創造不跳離 App 的體驗。

分辨使用者,並銜接對話流程

除了某些純粹想要用網頁提供資訊的狀況(我的網頁已經做好在那邊,不秀一下嗎?)以外,若是遇到我上面所述的三種情境之一,都必須分辨現在操作網頁 Webview 的使用者是哪位 Messenger 或哪位 LINE 的使用者。

作為網頁工程師的第一種想法可能會是「把 id 帶在網址上」,但這樣會有什麼問題呢?會有身份偽造或是別人用假 id 的方式攻擊,當然有些基本應對手法例如用加解密或加一個 Checksum,但其實官方有提供正規的方式的話還是用正規的方式妥當,而且用官方的 SDK 還會有一些特殊的功能可以使用。

Messenger

在 Messenger 你必須插入「Messenger Extensions SDK」的 JavaScript 來使用相關的功能(而且要有 HTTPS 並設定 whitelisted_domains)。

基本上只有兩個重要的 API:

想拿到 psid 可以透過「MessengerExtensions.getContext」:

MessengerExtensions.getContext('YOUR_APP_ID', 
  function success({ psid }) {
    // success
    console.log({ psid });
  },
  function error(err) {
    // error
  }
);

這個「MessengerExtensions.requestCloseBrowser」則用來關掉瀏覽器回到對話:

MessengerExtensions.requestCloseBrowser(function success() {
  // webview closed
}, function error(err) {
  // an error occurred
});

LINE

在 LINE 上 則是要用「LINE Front-end Framework」簡稱「LIFF」來達到一樣的效果。

你需要跑「這個註冊 LIFF 的流程」並指定名字、高度、網址後,就能開始用了。

然後你需要確定你的網頁有注入這行 script:

<script src="https://d.line-scdn.net/liff/1.0/sdk.js"></script>

接著來看一下 API 的部分:

可以在 liff.init 裡面拿到 userId

liff.init(
  data => {
    // Now you can call LIFF API
    console.log({ userId: data.context.userId });
  },
  err => {
    // LIFF initialization failed
  }
);

可以用 liff.getProfile 去拿到使用者資料:

const { displayName } = await liff.getProfile();

再來有一個我覺得非常不錯的,可以直接呼叫 API 來送訊息:

  • Text
  • Image
  • Video
  • Audio
  • Location
  • Template(只支援 URI action)
  • Flex

這邊最酷的就是能把 messaging-api-line 拿起來跟 liff.sendMessages 一起使用:

const { Line } = require('messaging-api-line');


await liff.sendMessages([
  Line.createText('Hello'),
  Line.createImage({
    originalContentUrl: 'https://example.com/original.jpg',
    previewImageUrl: 'https://example.com/preview.jpg',
  }),
  Line.createText('End'),
]);

然後一樣可以用 liff.closeWindow 關掉瀏覽器視窗:

await liff.closeWindow();

結語

Conversational Interface 一直都不是萬能的,但是知道他的優點與缺點並選擇最適合你當下的解決方案才是一個優秀的開發者該做的事情,當然這對熟悉網頁的開發者來說更不是一個問題。


上一篇
Day 15:機器人亂入下的「多人對話」、「群組聊天」
下一篇
Day 17:屬於機器人的跨平台策略
系列文
使用 Modern Web 技術來打造 Chat App30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言