你可以將 Google 訊息與 RCS 和 Google 錢包搭配使用,設計出流暢的結帳流程:使用者完成登機報到手續、收到登機證,然後從「訊息」應用程式直接將票證新增至 Google 錢包。錢包一經變更,票證就會自動更新。使用者可在手機上快速取得最新的登機證。
本文件說明將登機證導入 Google 錢包流程的技術步驟。此外,課程還會提供對話設計範例範例,協助您透過 RBM 順暢且有效率地進行簽到。
技術實作
如要在 Google 錢包流程中導入登機證,請使用 Google Wallet API 和 RBM API。
必要條件
如要開始使用 Google Wallet API,請按照下列步驟操作:
- 註冊 Google 錢包發卡機構帳戶,才能建立及發布 Google 錢包票證。
- 如果您還沒有 Google Cloud Platform (GCP) 專案,請建立一個。
- 啟用 Google Wallet API。
- 建立服務帳戶和金鑰,以便呼叫 Google Wallet API。
- 在 Google Pay 和錢包主控台中授權服務帳戶。
- 使用登機證範本建立新的登機證。
Google Wallet API
如要建立登機證並產生 RBM 的「新增至 Google 錢包」網址,請按照下列步驟操作:
- 執行必要的驗證和授權。
- 建立票證物件。
- 取得已簽署的 JSON Web Token (JWT)。編碼的 JWT 的長度上限為 2048 個字元。
- 使用 JWT 來產生「新增至 Google 錢包」網址。
RBM API
如要透過 RBM 將「新增至 Google 錢包」建議,請傳送開啟網址動作。 在訊息酬載中執行下列操作:
- 將
text
設為「新增至 Google 錢包」。 - 將「
url
」輸入「新增至 Google 錢包」網址。
建議標籤會自動顯示 Google 錢包圖示。
對話設計
這個範例使用對話的獨特功能,引導使用者完成報到流程。示範如何使用自然對話方塊和豐富的功能 (例如輕觸建議和複合式資訊卡),讓使用者達成目標。在這種情況下,目標為:(1) 自訂航班體驗、(2) 收到登機證,並 (3) 新增至 Google 錢包,以輕鬆存取機場。
以下是對話的總覽。接著,接著顯示設計提示,以及流程的逐步細分。如要為代理程式實作類似的設計,請參閱步驟下方的程式碼範例。
設計建議
設計入住流程時,請謹記以下原則:
- 最重要的訊息就是最重要的訊息。請簡單說明對話的目的,讓使用者有理由進行互動。
- 每則訊息都應提供少量資訊,並提示使用者做出回應。建議回覆和建議採取的動作,可讓你輕鬆完成後續步驟。
- 服務專員應保持回應性,而非機器人。請使用能反映品牌用語的用語。理想的品牌代表與客戶會談的方式為何?
- 人們喜歡感受特殊的您可以根據使用者的航班記錄來建議座位或餐點,藉此提供個人化的入住體驗。
- 複合式資訊卡和輪轉介面可讓對話內容更加生動。請運用這些圖片分享圖片和詳細資料,協助使用者做出選擇。
- 結束良好的對話,請先傳送使用者的登機詳細資料,再傳送登機證。透過親切友善的感覺,加入人類互動。
確認流程
服務專員會通知使用者辦理登機報到手續。
程式碼範例
const suggestions = [ { reply: { text: '⚡ Check in', postbackData: 'checkIn', }, }, { reply: { text: '⏰ Remind me later', postbackData: 'remindMe', }, }, { reply: { text: '✈️ View my flight details', postbackData: 'flightDetails', }, }, { reply: { text: '🔀 Change my flight', postbackData: 'flightChange', }, }, ]; const params = { messageText: 'Check-in for your flight', messageDescription: '👏 Happy morning, Jo! Check-in is now open for your flight from London to Mumbai on ' + getFlightTime() + ' at 2:00PM. What would you like to do? ', msisdn: phoneNumber, suggestions: suggestions, imageUrl: getImageUrl('fly.png'), height: 'MEDIUM', }; rbmApiHelper.sendRichCard(params);
使用者輕觸建議的回覆內容。
服務專員設定報到流程時應有所預期。
程式碼範例
const params = { messageText: "OK, great. It's just 3 simple steps to check in. Here's the first step to get you onboard:", msisdn: msisdn, }; let self = this; rbmApiHelper.sendMessage(params, function (response, err) { self.sendPolicyImage(msisdn); });
服務專員請使用者同意安全性政策。
程式碼範例
const suggestions = [ { reply: { text: 'Yes, I agree', postbackData: 'policy_agree', }, }, { reply: { text: "No, I don't agree", postbackData: 'policy_nack', }, }, ]; const params = { messageText: 'Baggage safety policy', messageDescription: 'To help us ensure a safe flight, please review our safety policy and let us know you agree', msisdn: msisdn, suggestions: suggestions, imageUrl: getImageUrl('policyImage.png'), height: 'MEDIUM', orientation: 'HORIZONTAL', thumbnailImageAlignment: 'LEFT', }; rbmApiHelper.sendRichCard(params);
使用者輕觸建議回覆即可同意。
服務專員感謝使用者,並說明下一個步驟。
程式碼範例
const params = { messageText: "Thank you - A safe passenger is a happy passenger! Here's the next step:", msisdn: msisdn, }; let self = this; rbmApiHelper.sendMessage(params, function (response, err) { self.sendPlan(msisdn); });
服務專員會提示使用者選擇座位。
程式碼範例
const suggestions = [ { reply: { text: 'View the seat map', postbackData: 'view_seat_map', }, }, ]; const outerSuggestions = [ { reply: { text: '17A', postbackData: 'seat_17A', }, }, { reply: { text: '17C', postbackData: 'seat_17C', }, }, { reply: { text: '18A', postbackData: 'seat_18A', }, }, { reply: { text: 'Show me more', postbackData: 'more', }, }, ]; const params = { messageText: 'Choose your seat', messageDescription: "It's time to sit back and get comfy! 💺 We've recommended some seats based on your last flight. Choose the one you want, or let us know your preferred seat by typing the number.", msisdn: msisdn, imageUrl: getImageUrl('seatMap.png'), height: 'TALL', orientation: 'VERTICAL', outerSuggestions: outerSuggestions }; rbmApiHelper.sendRichCard(params);
使用者針對所選座位輕觸建議回覆。
代理程式會確認使用者選擇的項目。
程式碼範例
this.seatmap[msisdn] = seat; const params = { messageText: `Seat ${seat}, you got it`, msisdn: msisdn, }; let self = this; rbmApiHelper.sendMessage(params, function(res) { self.sendFoodOptions(msisdn); });
服務專員請使用者選擇空檔飲食。
程式碼範例
const params = { messageText: `Now let's talk food 😋 You can pre-order your in-flight meal. Would you be happy with a vegetarian entree or a chicken entree?`, msisdn: msisdn, }; let self = this; rbmApiHelper.sendMessage(params, function(res) { self.sendFoodDetails(msisdn); });
服務專員會顯示餐點選項。
程式碼範例
const cardContents = [ { title: 'Panzanella salad (v)', description: 'Ingredients: bread, lettuce, onions, tomatoes, olive oil', suggestions: [ { reply: { text: 'Choose vegetarian', postbackData: 'veggie', }, }, ], media: { height: 'MEDIUM', contentInfo: { fileUrl: getImageUrl('salad.jpg'), }, }, }, { title: 'Grilled chicken with greens', description: 'Ingredients: chicken, potatoes, peppers, olive oil', suggestions: [ { reply: { text: 'Choose chicken', postbackData: 'chicken', }, }, ], media: { height: 'MEDIUM', contentInfo: { fileUrl: getImageUrl('chicken.png'), }, }, }, ]; const params = { msisdn: msisdn, cardContents: cardContents, }; rbmApiHelper.sendCarouselCard(params);
使用者輕觸所選餐點的建議回覆。
代理程式會確認使用者選擇的項目。
程式碼範例
const params = { messageText: `Vegetarian it is 💚`, msisdn: msisdn, }; let self = this; rbmApiHelper.sendMessage(params, function (response, err) { self.sendAskConfirmation(msisdn); });
服務專員總結:
程式碼範例
let seat = this.seatmap[msisdn]; const suggestions = [ { reply: { text: "Yes, I'm happy with that", postbackData: 'happy', }, }, { reply: { text: 'Change my seat', postbackData: 'change_seat', }, }, { reply: { text: 'Change my meal', postbackData: 'change_meal', }, }, ]; const params = { messageText: "Here's what we've noted down: You've opted for seat " + seat + " and a vegetarian meal. Please confirm your choices.", msisdn: msisdn, suggestions: suggestions }; rbmApiHelper.sendMessage(params);
使用者輕觸建議回覆來確認入住詳細資料。
服務專員宣布報到已完成。
程式碼範例
const params = { messageText: "Hooray! You're now checked in for your flight ☑️ Here's your boarding pass. We're so happy to host you soon!", msisdn: msisdn, }; let self = this; rbmApiHelper.sendMessage(params, function (response, err) { self.sendWalletPass(msisdn); });
服務專員傳送使用者的登機證。
程式碼範例
this.walletHelper.createFlightPassUrl(this.seatmap[msisdn]).then((url) => { let suggestions = [ { action: { text: 'Add to Google Wallet', postbackData: 'addToWallet', openUrlAction: { url: url }, }, }, ]; const params = { messageText: 'HS123 LHR to BOM\nPassenger: Jo Flow', messageDescription: "We'll keep you up to date! You'll get a notification if your flight details change.", msisdn: msisdn, suggestions: suggestions, imageUrl: getImageUrl('boardingPass.png'), height: 'TALL', orientation: 'HORIZONTAL', thumbnailImageAlignment: 'LEFT', }; rbmApiHelper.sendRichCard(params); });
在這個水平複合式資訊卡中,圖片是完全由航空公司提供的登機證。圖片應顯示所有必要上車資訊,包括可掃描的條碼。使用者只要輕觸圖片,即可透過 Google 的「訊息」應用程式查看及掃描登機證。
複合式資訊卡會顯示「新增至 Google 錢包」建議。這項建議會觸發「開啟網址動作」,開啟 Google 錢包應用程式,讓使用者可以輕鬆將登機證新增至錢包。(如果應用程式不在使用者的裝置上,系統會提示使用者安裝)。票證新增至 Google 錢包後,使用者就會在航班詳細資料變更時自動收到航班提醒和狀態更新。
如果使用者未將票證新增至 Google 錢包,也應持續更新這項資訊。告知複合式資訊卡上顯示的登機證資訊有異動。
使用者輕觸建議動作,將票證新增至 Google 錢包。
Google 錢包應用程式隨即開啟。使用者只要輕觸按鈕,就能將票證新增至錢包。
使用者輕觸按鈕即可查看票證。
顯示 QR 圖碼的登機證。