前面幾篇內提到的所有互動都是在對話框中完成,雖然若能順暢的用 Conversation UI 完成所有的事情,那會是很棒的事,使用者不會碰到斷斷續續的或是跳轉的體驗。但有些時候就是不適合在對話中輸入資訊,這邊我舉幾個例子:
在輸入敏感資訊的時候,例如:密碼、信用卡卡號或信用卡安全碼。在網頁輸入時可以用 <input type="password">
來讓輸入變成 *******
,但在各種聊天平台的輸入框輸入都不會有保護,也會留在歷史訊息,旁邊有人就能直接去看到,這是一個蠻大的問題。
在詢問問題時,過多的步驟(我個人認為超過三輪都算是難用)。例如,訂位時如果機器人只問你幾點、幾位那可能還好,但如果機器人要問你幾點、幾位、有沒有小孩需不需要兒童座椅、有沒有人吃素、沒有景觀的位子可以嗎...等等,一個問題是會顯得冗長,但最嚴重的問題是,確認跟修改的流程變得煩悶而且沒有效率,想想看當你想要修改前面兩步的輸入錯誤會是怎樣的情景。
輸入的項目不好用言語去限制或挑選,需要一種選擇器。例如:時間可以用下拉式選單選、地點可以用地圖加圖針的方式去拉、顏色可以用調色盤去拉...等等,這都是用言語很難表達的,當你資料庫有一大堆東西要給使用者選,有可能也會是同一種情境。
在遇到上面三種情境時,我能肯定的說,請用 Webview 來解決吧,這會是更好的體驗。
在使用 Webview 時,如果不是必要,應該要避免開出全版的網頁,這是 Messenger 的選項:
這是 LINE 的選項:
基本上都是有 50%
、80%
、100%
三種選擇。所以我們應該主要使用 50%
、80%
的高度,這樣使用者比較容易感受到這個網頁是由對話來的,容易完成網頁上的任務再回到對話,創造不跳離 App 的體驗。
除了某些純粹想要用網頁提供資訊的狀況(我的網頁已經做好在那邊,不秀一下嗎?)以外,若是遇到我上面所述的三種情境之一,都必須分辨現在操作網頁 Webview 的使用者是哪位 Messenger 或哪位 LINE 的使用者。
作為網頁工程師的第一種想法可能會是「把 id 帶在網址上」,但這樣會有什麼問題呢?會有身份偽造或是別人用假 id 的方式攻擊,當然有些基本應對手法例如用加解密或加一個 Checksum,但其實官方有提供正規的方式的話還是用正規的方式妥當,而且用官方的 SDK 還會有一些特殊的功能可以使用。
在 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 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 來送訊息:
這邊最酷的就是能把 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 一直都不是萬能的,但是知道他的優點與缺點並選擇最適合你當下的解決方案才是一個優秀的開發者該做的事情,當然這對熟悉網頁的開發者來說更不是一個問題。